10

私は、swing がスレッドセーフではないことを学びました。さらに深く掘り下げると、マルチスレッドに関連するさまざまな問題を防ぐために、swing コンポーネントへのすべての変更をイベント ディスパッチ スレッドで行う必要があることがわかりました。しかし、情報はそこで完全に止まっているように見えました。インターネット上でアクセス可能な場所ならどこでもこれを行う方法を説明する優れたチュートリアルはないようです。

他の問題に関連して投稿されたコードからの情報をまとめてパッチを当てると、プログラム内のすべてのスイング変更の周りに乱雑なコード ブロックを配置する必要があるように思われました (自分のコードのこの例のように):

try {
        SwingUtilities.invokeAndWait(new Runnable() {

            public void run() {
                setTitle("Frame title");
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                setVisible(true);

                setSize(800, 480);
                setLocationRelativeTo(null);
                setIconImage(Toolkit.getDefaultToolkit().createImage(ClassLoader.getSystemResource("Frame icon.png")));
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }

基本、これでいいの?コード内の Swing コンポーネントを変更するたびに、そのコード (または invokeLater と同等のもの) を配置する必要がありますか?

また、Swing がこれを自動的に行わないのはなぜですか?

4

4 に答える 4

8

秘訣は、スイングがあなたを呼び出すとき、それは常に EDT にあるので、心配する必要がないということです。

ただし、タイマーまたは他の外部イベント、メイン スレッド、または作成した他のスレッドによってトリガーされるアクションにいる場合は、invokeLater または invokeAndWait を使用する必要があります。

言い換えれば、はいスイングは自動的に「それ」を行います。invokeXx を使用する必要があることは非常にまれであるため、swing が内部的に行うと時間がかかりすぎてしまいます。

多くの Java プログラマーはこれを決して理解せず、GUI の描画に関してかなり厄介で見つけにくい問題を引き起こす可能性があります。Swing が EDT を使用せずに呼び出されたときに例外をスローしたことを願っています。Java がプロの GUI に関して言えば、Java の方が評判が良いでしょう。

于 2011-10-25T22:58:01.067 に答える
4

イベントハンドラーから実行されるコードは、EDT(頭字語のイベント)ですでに実行されていることに注意してください。

これは、一般的な使用(スイングワーカーやスレッドプールなどをいじらない間)では、常にEDT内にいることを意味します

また、EDTに参加している場合は、いつでもクエリを実行できます。SwingUtilities.isEventDispatchThread()

invokeAndWaitまた、コード内で、すでにEDTにいる場合、への呼び出しは失敗し、エラーがスローされることに注意してください。

于 2011-10-25T22:58:37.930 に答える
3

すべてのUIコードがinvokeLater呼び出しの実行可能ファイルの一部である必要はありません。これは、プログラムの大部分がとにかくEDTで実行されるためです。別のスレッドを使用している場合にのみ、EDTにメッセージをディスパッチする必要があります。

于 2011-10-25T22:59:50.703 に答える
3

基本的に、EDT の外部から GUI を描画または更新することはありません。別のスレッドから SwingUtilitis.invokeLater() を使用して、GUI 描画または更新コードが EDT で実行されるようにします。

于 2011-10-25T22:45:58.530 に答える