GUIのビジュアルに影響を与えるスレッドについては、SwingUtilities.invokeAndWait/invokeLaterを使用してEDTで実行する必要があることをどこかで読みました
基本的な GUI の場合、new SwingGUI().setVisible(true);
invokeAndWait を使用して EDT の行に次のようなものを配置する必要がありますか? 表示するだけ?
これはカウントされますか?
GUIのビジュアルに影響を与えるスレッドについては、SwingUtilities.invokeAndWait/invokeLaterを使用してEDTで実行する必要があることをどこかで読みました
基本的な GUI の場合、new SwingGUI().setVisible(true);
invokeAndWait を使用して EDT の行に次のようなものを配置する必要がありますか? 表示するだけ?
これはカウントされますか?
あなたの質問に対する簡単な答えは次のとおりです。はい、呼び出しもsetVisible
EDT で行う必要があります。現在のスレッドが EDT であるかどうかを調べるには、EventQueue#isDispatchThread
メソッドを使用できます。
いくつかの参照リンク:
編集:私が提供したリンクを読んだ後、Oracle サイトの記事の一部は、別のスレッドで Swing コンポーネントを作成できることをまだ文書化しているため、古くなっているようです。これには、「新しい」ポリシーに関するいくつかの素晴らしい回答とブログ投稿および記事へのリンクが含まれているstackoverflowの質問があります(数年前のように新しい)
はい、Swing オブジェクトに触れる場合は、EDT で行う必要があります。ほとんどの場合、すでにそこにいますが、そうでない場合は、SwingUtilities
クラスを使用してください。これは、Swing クラスがマルチスレッド化されていないため、他のスレッドでアクセスすると厄介な問題が発生する可能性があるためです。そして、何かを表示するために、隠れて多くのことを行っている可能性がありsetVisible()
ます (物事を再レイアウトするなど)。安全である方がよい。
あなたから呼び出されるものは何でも
public static void main(String[] agrs) {
直接(別のスレッドを生成したり、invokeLaterを使用したりせずに)メインスレッドで実行されています。
EDT(ユーザー入力によってトリガーされる)によって(同時に)アクセスされている可能性があるときにメインスレッドを使用してGUIオブジェクトにアクセスすると、スレッドの問題が発生する可能性があります。invokeLaterを呼び出すと、タスク(実行可能ファイル)がEDTで実行され、他のEDTタスクによる同時アクセスが防止されます。ボタンを押すなど。
EDTがビジーでないことを確認できる場合(最初のウィンドウがsetVisible(true)になる前)、メインスレッドからGUIにアクセスできます。EDTに作業中のコンポーネントへの参照がないことを確認できる場合(EDTの範囲外です)。コンテナに追加する前に、EDTにアクセスする方法がないため、EDTが同時にアクセスしなくても、メインスレッドからアクセスできます。
Swing オブジェクトにアクセスするものはすべて、イベント ディスパッチ スレッド (EDT) を介してアクセスする必要があります。これには小さな例外が 1 つあります (後で説明します)。EDT の目的は、IO によって発生する可能性のあるイベント (マウスおよびキーボード イベント) を処理することです。多くの場合、これは GUI のレイアウトを変更することを意味します。Swing はスレッドセーフになるように開発されていません。つまり、2 つのスレッドが同じコンポーネントを同時に変更しようとすると、GUI が破損する可能性があります。Swing コンポーネント (EDT) にアクセスする既知のスレッドが既に 1 つあるため、他のスレッドが Swing コンポーネントを変更したり、状態を読み取ったりすることはできません。
ここで、EDT の外部で Swing オブジェクトを操作できる例外的なケースについて説明します。コンポーネントが表示される前に、IO がイベントをトリガーすることはできません。したがって、メインスレッドは Swing GUI をセットアップしてから、単一の JFrame を表示するように設定できます。フレーム IO イベントが発生する可能性があるため、メイン スレッドはこれ以上 Swing コンポーネントを変更しようとしません。は、このオプションを GUI を開始するためにのみ使用する必要があり、実際にはおもちゃの問題でのみ使用する必要があります。
私が言いたいのは、次のことは問題なく、ただ遊んでいるだけなら問題を引き起こさないということです。
public static void main(String[] args) {
// create components
JFrame f = new JFrame();
...
// do layout and other bits of setup
// show gui to user
f.setVisible(true);
}