以前の質問に関連して: Javaの別のクラスから再描画を呼び出しますか?
私はJavaが初めてで、SwingWorkerのチュートリアルを見たことがあります。しかし、前の質問で与えたサンプルコードでそれを実装する方法がわかりません。
誰でも私のコードスニペットに関してSwingWorkerの使用方法を説明したり、適切なチュートリアルを教えてくれたりできますか?見たことがありますが、まだ理解しているかはわかりません。
通常、SwingWorkerは、Swingで長時間実行されるタスクを実行するために使用されます。
Event Dispatch Thread(EDT)で長時間実行されるタスクを実行すると、GUIがロックアップする可能性があるため、行われたことの1つは SwingUtilities.invokeLater
および invokeAndWait
これは、目的のタスク(Runnable
の形式)を実行する前に他のAWTイベントを優先させるGUIの応答性を維持します。
ただし、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
メソッドが呼び出されます。この例では、ActionListener
を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つのボタンが表示されます。 「Answer!」というラベルの付いたものそしてもう一つの「何もない」。 「Answer!」をクリックするとボタン、最初は何も起こりませんが、「なし」ボタンをクリックすると動作し、GUIが応答することを示します。
そして、1秒後、AnswerWorker
の結果がメッセージボックスに表示されます。
同意する:
Event Dispatch Thread(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();
}
}
});
少なくとも、上記のコードでactionPerformedをトリガーするボタンをクリックすると、マウスを移動できません。何か不足していますか?