2

私はJavaを使用しています。ループ内でコンテナに「正方形」を追加するクリックイベントがあります。追加されたときに、各正方形が右に表示されるようにします。別のスレッドで「正方形の追加」を実行しようとしましたが、機能しません。

'パブリッククラスGuiControllerがActionListener、MouseListenerを実装する'に使用するコードは次のとおりです。

@Override
public void mouseClicked(MouseEvent e)
{
    //createBoardPane();
    new Thread
    (
        new Runnable() 
        {
            public void run() 
            {
                showAnimation();
            }
        }
    ).start();
}

public void showAnimation()
{   
    for(int i = 0; i < model.getAnimationList().size(); i++)
    {
        String coord = model.getAnimationList().get(i);
        int x = Integer.parseInt(coord.substring(0, coord.indexOf(',')));
        int y = Integer.parseInt(coord.substring(coord.indexOf(',') + 1, coord.length() - 2));
        boolean shouldPlacePiece = (coord.charAt(coord.length() - 1) == 'p');

        if(shouldPlacePiece)
        {
            model.getView().getBoardPane().getComponent(x + (y * model.getBoardSize())).setBackground(Color.BLACK);
        }
        else
        {
            model.getView().getBoardPane().getComponent(x + (y * model.getBoardSize())).setBackground(Color.WHITE);
        }

        model.getView().getBoardPane().repaint();

        long time = System.currentTimeMillis();
        while((System.currentTimeMillis() - time) < 250)
        {
            // wait loop
        }
    }
}

どんな助けでも大歓迎です!

4

1 に答える 1

1

Threadアニメーションの実行中にGUIとの対話をロックアップしたい場合を除いて、この長時間実行されるタスクのために実行する別のタスクを作成することは優れたアイデアでした。

現在、Swing GUIオブジェクトはスレッドセーフではないため(いくつかの例外を除いて)、Swingのイベントディスパッチループのスレッド以外のスレッドからオブジェクトを操作することはできません。したがって、forループ内のすべてのGUI更新コードを取得し、それを新しいRunnable(はい、別のRunnable)でラップします。次に、ループの各反復でそれをSwingUtilities.invokeLater(Runnable doRun)呼び出します。Runnable

次に、GUI更新コードはイベントディスパッチループでできるだけ早く実行するようにスケジュールされます。これは、ワーカースレッドがスリープ状態になる間に発生します(何か反対はありますThread.sleepか?)。

代替:SwingWorker代わりに使用Thread

SwingWorkerは、新しいスレッドを作成および管理し、そのスレッド(SwingWorker)がイベントディスパッチループのスレッドで実行されるようにするデータを公開します。コードで上書きdoInBackgroundします。パラメータを指定して呼び出しpublish、イベントディスパッチスレッドにプッシュします。processこれらのパラメーターを処理してGUIを更新するには、コードでオーバーライドします。

SwingWorkerの落とし穴はpublish、約33ミリ秒の期間にわたってedイベントを蓄積することです。それよりも頻繁に公開している場合は、33ミリ秒程度ごとにすべてのイベントがまとめられる可能性があります。この場合、更新間の250ミリ秒は問題になりません。

于 2012-07-30T21:05:25.007 に答える