(Swing GUI を使用した私のアプリケーションでは) JButton をクリックした後に呼び出されるループまたはメソッドで実行される作業中に GlassPane を表示したいと考えています。
例: (ボタンをクリックした後に実行されるアクション)
if (item.equals(button)) {
glassPane.setVisible(true);
someTimeConsumingMethod();
glassPane.setVisible(false);
}
このコードを実行すると、someTimeConsumingMethod() の実行中に glassPane が表示されなくなります。結果が表示される前に、GUI が一瞬フリーズします。そのループ (glassPane.setVisible(false);) の最後の行を削除すると、メソッドが完了した後 (GUI がフリーズしたとき)、glassPane が表示されます。
GUI がフリーズする前にその glassPane を表示する簡単な方法はありますか、それともここで高度な知識を使用する必要がありますか? (スレッド?)
更新1:
davidXYZの回答に従ってコードを更新しました(2つの変更があります):
(ボタンクリック後の動作)
if (item.equals(button)) {
glassPane.setVisible(true);
new Thread(new Runnable(){
public void run(){
someTimeConsumingMethod(); // 1st change: running the someTimeConsumingMethod in new Thread
// instead of setting glassPane to visible
}
}).start();
// 2nd change: moved glassPane.setVisible(false); inside the someTimeConsumingMethod(); (placed at the end of it).
}
最初の変更のポイントは、GUI スレッドで someTimeConsumingMethod を実行する直前に新しいスレッドで glassPane を表示するように設定すると、someTimeConsumingMethod が終了した後に glassPane が明らかになることです (これを再確認しました)。
今では問題なく動作します。すべての回答に感謝します。スレッドを実際に理解するために、あなたが提供したすべてのリンクを必ず確認します!
UPDATE2: いくつかの詳細情報: someTimeConsumingMethod(); 私のアプリケーションでは、XML データに応じて新しい Swing コンポーネントを準備しています (カードは JButton と JLabel から構築され、必要に応じていくつかの JPanel を使用し、それらを正しい場所に追加します)。
UPDATE3:
SwingWorker の invokeLater メソッドを使用して機能させようとしています。これで次のようになります。
(ボタンクリック後の動作)
if (item.equals(button)) {
glassPane.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
someTimeConsumingMethod();
glassPane.setVisible(false);
}
});
}
UPDATE1のコードほどうまく機能しません(ただし、それでも機能します)。問題は次のとおりです。
glassPane は .gif アニメーションなしで読み込まれます (ファイルはカスタム glassPane クラスで設定されます - UPDATE1コードで動作します)
「作業」プロセスの最後にわずかな遅延があります。最初のカーソルが (WAIT_CURSOR から) 通常に変わり、非常に短い時間後に glassPane が消えます。カーソルは、アクティブ化/非アクティブ化時にカスタム glassPane クラスによって変更されます (新しいスレッドの方法を使用して遅延はありません)。
SwingWorker の invokeLater メソッドを使用する正しい方法ですか?
編集:私の間違いです。SwingWorker と SwingUtilities.invokeLater() を混同しました。イメージの問題は、someTimeCONsumingMethod の開始時に GUI がフリーズしたことが原因だと思います。