1

*問題が解決しました - すべての回答に感謝します。とても役に立ちました!

学校の課題で小さなさいころゲームを作っているのですが、この問題に遭遇しました。多数のサイコロアイコンをすばやく循環させて、サイコロの転がしをシミュレートしたいと考えています。ただし、これ自体は問題の原因ではありません。JFrameで直接「アニメーション」を作成すると、正しく表示されます。私は以下のコードでそれを行いました:

public class Example{

        private static ImageIcon die1 = new ImageIcon("terning1.jpg");
        private static ImageIcon die2 = new ImageIcon("terning2.jpg");
        private static ImageIcon die3 = new ImageIcon("terning3.jpg");
        private static ImageIcon die4 = new ImageIcon("terning4.jpg");
        private static ImageIcon die5 = new ImageIcon("terning5.jpg");
        private static ImageIcon die6 = new ImageIcon("terning6.jpg");

        private static JLabel die = new JLabel(die1);
        private static Random generator = new Random();

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(die);

        frame.pack();
        frame.setVisible(true);

        for (int i = 0; i < 100; i++) {
            int x = generator.nextInt(6) + 1;

            switch(x){
                case 1 : die.setIcon(die1);
                    break;
                case 2 : die.setIcon(die2);
                    break;
                case 3 : die.setIcon(die3);
                    break;
                case 4 : die.setIcon(die4);
                    break;
                case 5 : die.setIcon(die5);
                    break;
                case 6 : die.setIcon(die6);
                    break;
            }

            //Make the loop wait for 50 millis
            long a, b;
            a = System.currentTimeMillis();
            do {
                b = System.currentTimeMillis();
            } while ((b-a) < 50);           
        }

    }       
}

これで問題なく動作しますが、明らかに、JFrame を最初に開いたときにのみ動作します。だから私はサイコロを振るボタンを追加したいと思います。しかし、actionlistener を使用して JButton を追加し、for ループを actionPerformed メソッドに配置すると、ループが終了するまでプログラムが停止し、ループ内の最後のダイのみが表示されます。例:

public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setLayout(new FlowLayout());

        frame.add(button);
        frame.add(die);

        button.addActionListener(new ButtonListener());

        frame.pack();
        frame.setVisible(true);
    }

    private static class ButtonListener implements ActionListener {

        public void actionPerformed(ActionEvent event) {
            for (int i = 0; i < 100; i++) {
                int x = generator.nextInt(6) + 1;

                switch (x) {
                    case 1:
                        die.setIcon(die1);
                        break;
                    case 2:
                        die.setIcon(die2);
                        break;
                    case 3:
                        die.setIcon(die3);
                        break;
                    case 4:
                        die.setIcon(die4);
                        break;
                    case 5:
                        die.setIcon(die5);
                        break;
                    case 6:
                        die.setIcon(die6);
                        break;
                }

                //Make the loop wait for 50 millis
                long a, b;
                a = System.currentTimeMillis();
                do {
                    b = System.currentTimeMillis();
                } while ((b - a) < 50);
            }

これを解決する方法に関するヒントはありますか?よろしくお願いします!

4

4 に答える 4

3

何が起こっているかというと、すべての Swing イベントが発生する「イベント ディスパッチ スレッド」がコードを待たなければならないということです。イベント ディスパッチ スレッドで実行時間の長い処理を行わないでください。これは有名なアンチパターンです。

これについて説明しているhttp://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.htmlで始まる Java チュートリアルのレッスンを読む必要があります。

あなたの問題とは関係のない2つの小さな点:

  1. ImageIcon6 つの個別の変数ではなく、変数 の配列を使用すると、コードがはるかに管理しやすくなります。
  2. 使用している「ビジースリープ」の代わりにsleep、クラスのメソッドを使用できます。Thread
于 2013-10-31T17:17:27.043 に答える
1

すべてが同じスレッドにあるため、UI はロックされているため、for ループの実行が完了するまで待機する必要があります。別のスレッドでロジックを実行する必要があります。

于 2013-10-31T17:16:40.827 に答える
0

actionPerformed(ActionEvent event)UI を更新できないため、EDT でメソッドを実行します。コードから UI を更新するには、 SwingWorkerを使用してみてください。バックグラウンド プロセスの実行中に UI を更新できます。インターネットでその例をたくさん見つけることができます。

または、バックグラウンド プロセスにExecutorを使用して、EDT から UI を更新することもできます。

于 2013-10-31T17:26:02.500 に答える