51

前の質問に関連して: Java の別のクラスから再描画を呼び出しますか?

私は Java が初めてで、SwingWorker に関するいくつかのチュートリアルを見てきました。それでも、前の質問で示したサンプル コードを使用して実装する方法がわかりません。

私のコードスニペットに関してSwingWorkerを使用する方法を説明したり、適切なチュートリアルを教えてもらえますか? 私は見ましたが、まだ理解できていません。

4

2 に答える 2

115

一般に、SwingWorker は Swing で長時間実行されるタスクを実行するために使用されます。

イベント ディスパッチ スレッド (EDT) で実行時間の長いタスクを実行すると、GUI がロックされる可能性があるため、必要なタスクを実行する前に他の AWT イベントを優先することで、GUI の応答性を維持することが行われましSwingUtilities.invokeLaterinvokeAndWait。 ( の形式でRunnable)。

ただし、問題SwingUtilitiesは、実行されたメソッドから元のメソッドにデータを返すことができないことRunnableです。これはSwingWorker、対処するために設計されたものです。

Java チュートリアルにはSwingWorkerに関するセクションがあります。

次の例では、aSwingWorkerを使用して時間のかかるタスクを別のスレッドで実行し、1 秒後に回答を含むメッセージ ボックスを表示します。

まず、拡張SwingWorkerするクラスが作成されます。

class AnswerWorker extends SwingWorker<Integer, Integer>
{
    protected Integer doInBackground() throws Exception
    {
        // Do a time-consuming task.
        Thread.sleep(1000);
        return 42;
    }

    protected void done()
    {
        try
        {
            JOptionPane.showMessageDialog(f, get());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

doInBackgroundおよびメソッドの戻り値の型はgetの最初の型として指定されSwingWorker、2 番目の型はpublishおよびprocessメソッドの戻り値として使用される型であり、この例では使用されていません。

次に、 を呼び出すためSwingWorkerに、executeメソッドが呼び出されます。この例では、 anActionListenerを aにフックして、JButtonを実行しAnswerWorkerます。

JButton b = new JButton("Answer!");
b.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e)
    {
        new AnswerWorker().execute();
    }
});

上のボタンを に追加し、JFrameクリックするとすぐにメッセージ ボックスが表示されます。以下は、Swing アプリケーションの GUI を初期化するために使用できます。

private void makeGUI()
{
    final JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().setLayout(new FlowLayout());

    // include: "class AnswerWorker" code here.
    // include: "JButton" b code here.

    f.getContentPane().add(b);
    f.getContentPane().add(new JButton("Nothing"));
    f.pack();
    f.setVisible(true);
}

アプリケーションが実行されると、2 つのボタンが表示されます。「答えて!」というラベルの付いたもの。そして別の「何もない」。「答えて!」をクリックすると、ボタンをクリックしても、最初は何も起こりませんが、「何もしない」ボタンをクリックすると機能し、GUI が反応することを示します。

そして、1 秒後にAnswerWorkerメッセージ ボックスに結果が表示されます。

于 2009-04-23T15:37:27.213 に答える
12

同意:

イベント ディスパッチ スレッド (EDT) で実行時間の長いタスクを実行すると、GUI がロックされる可能性があります。

不賛成:

そのため、行われたことの 1 つは、SwingUtilities.invokeLater と invokeAndWait を使用して、GUI の応答性を維持することです。

invokeLater は引き続き EDT でコードを実行し、UI をフリーズさせる可能性があります!! これを試して:

SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

少なくとも、上記のコードで実行されるアクションをトリガーするボタンをクリックすると、マウスを動かすことができません。何か不足していますか?

于 2013-07-12T13:42:12.757 に答える