2009-04-23 14 views
41

私の前の質問に関連して:Call repaint from another class in Java?JavaでSwingWorkerを使用するにはどうすればよいですか?

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

誰でもSwingWorkerの使い方を説明できますか?ちょっとしたチュートリアルを参考にしてください。私は見ているが、私はまだ理解しているか分からない。

答えて

98

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

Event Dispatch Thread(EDT)で長時間実行されるタスクを実行すると、GUIがロックアップする可能性があります。その結果、SwingUtilities.invokeLaterinvokeAndWaitを使用して、GUIの応答性を維持し、イベントを実行する前に(Runnableの形式で)

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

JavaチュートリアルのセクションはSwingWorkerです。

別のスレッドで時間のかかるタスクを実行するためにSwingWorkerが使用され、応答で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メソッドが呼び出されます。この例では、実行するJButtonActionListenerをフックます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); 
} 

アプリケーションが実行されると、二つのボタンがあるでしょう。 1つは「回答!もう一つの "何もない"。ユーザーが「回答」をクリックするとボタンを押しても、最初は何も起こりませんが、 "Nothing"ボタンをクリックすると、GUIが応答していることが示されます。

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

+0

私がやっていることは、長時間実行されている作業ではないと思います。私はこの問題に対処する別の方法を考えており、別の質問で尋ねます。おかげで – Relequestual

+3

+1ありがとう! :) – coder9

+0

@ coder9あなたは大歓迎です:) – coobird

7

は同意:

はイベントディスパッチスレッド(EDT)の長時間実行タスクを実行すると、GUIがロックアップすることがあります。

同意しないでください:

そう

使用することで行われたものの一つは、応答性のGUIを保ちSwingUtilities.invokeLaterをして​​invokeAndWaitの..

invokeLaterはまだコードを実行しますEDTで、あなたのUIを凍結することができます!私は上記のコードでのactionPerformedをトリガーボタンをクリックすると、少なくとも私は、私のマウスを移動することはできません

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

:これを試してみてください。何か不足していますか?

+0

あなたは正しいです。通常、invokeLaterはイベントディスパッチスレッドの外側で呼び出され、イベントディスパッチスレッド上で何かを実行します。実行中のタスクがinvokeLaterを呼び出して表示を変更することがあります。これは、スイングオブジェクトに対するアクションがスレッドの安全性を維持するためにイベントスレッドから発生しなければならないためです。 – dhorn

関連する問題