多くのサイトを見て、色々考えているのですが、イマイチ理解が及びません。以下のような風に思っていていいのでしょうか。
・Swingではメインとなるmainスレッド(表現は正しくないかもしれない)と、描画関係のイベントを実行するイベントディスパッチスレッドで出来てる。
・描画関係のイベント(正確にはコンポーネントの可視化及び可視化したコンポーネントの描画)はイベントディスパッチスレッド上で実行しなければならない。
・SwingUtilities.invokeLaterを使うことによってその中身のプログラムをイベントディスパッチスレッドで実行してくれる...?
→setVisible(true)やsetText("")など全てSwingUtilities.invokeLaterを使って記述しなければならない.....???(面倒すぎじゃないでしょうか)
・Swingでのマルチスレッドを行うにはSwingWorkerを使う(ことは見つけているのですが、まずEDTについて理解しないと先に進めないと思い、まだあまりこれの内容は調べていません)
・描画系の命令を実行しないのならば、別スレッドを作成して使用しても良い....?
こんなところでしょうか。
しかし、このとおりだとすると今までの自分の書いてきたプログラムは間違いだらけ(特に「全ての描画系命令をSwingUtilities.invokeLaterを使いEDTで実行する」点)になってしまいます。
ちゃんとした理解をしておきたいので、わかりやすい説明でも、上記の間違っている点でもご教示願います。
A 回答 (1件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
書いてあること自体は、一部を除いて、ほぼ間違っていないと思います。
ただ、自分の書いたコードがイベントディスパッチスレッドで動いているのかそうでないのか、よくわからなくて混乱されているような印象を持ちました。
Swingは、シングルスレッドの設計です。Swingコンポーネントに対する呼び出しは、イベントディスパッチスレッド(EDT)上で行われる必要があります。例外は、repaint()です。
マウス、キーボード操作などのイベントも、すべてEDT上で処理します。
アプリケーションの処理はイベントに対する反応として記述します。これが、イベント発生時に呼び出されます。イベントは1つのスレッド上で順番に処理されます。
こういう設計は、イベント駆動といって、プラットフォームを問わず、GUIを持つアプリケーション用の仕組みとして一般に見られるものです。
http://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%99% …
> Swingではメインとなるmainスレッド(表現は正しくないかもしれない)と、描画関係のイベントを実行するイベントディスパッチスレッドで出来てる。
Javaでmainスレッドというと、最初に作られるスレッドですが、mainスレッド自体はとくに必要無いので、終わってしまってもかまいません。実際、自分の作ったアプリケーションでも、用が済んだらmainスレッドはすぐに終了してしまいます。EDTが重要です。
ただ、シングルスレッドの設計とはいえ、Swingは、EDT以外のスレッドも内部で使用します。
例えば、java.awt.Toolkitで画像を読み込むとバックグラウンドのスレッドで読み込まれます。
画像の読み込みには一般的に時間がかかるからです。
> 描画関係のイベント(正確にはコンポーネントの可視化及び可視化したコンポーネントの描画)はイベントディスパッチスレッド上で実行しなければならない。
そうです。描画というより、Swingコンポーネント関係の操作をEDT上で行う必要があります。
コンポーネントの描画もEDT上で行われます。
可視化というのが何を指すのか、ちょっと意味がとれませんでしたが…
setVisible(true) のことでしょうか? ということなら、これもその通りです。
> SwingUtilities.invokeLaterを使うことによってその中身のプログラムをイベントディスパッチスレッドで実行してくれる...?
そうです。invokeLaterに渡したRunnableオブジェクトのrunメソッドを呼ぶというイベントが、イベントキューに入れられます。イベントが処理されるとrunメソッドが呼ばれます。
そのため、即座に実行されるわけではなく、実行が予約されるような動きであると思ってください。
> →setVisible(true)やsetText("")など全てSwingUtilities.invokeLaterを使って記述しなければならない.....???(面倒すぎじゃないでしょうか)
EDT以外から、setText等のSwingコンポーネントの操作をしたいのならその通りです。
しかし、マウス、キーボードイベントのようなイベント処理はそもそもEDT上で動くわけですから、そこでsetText等をする分には、invokeLaterを使っていなくても問題ないです。
そういう意味では、「全て」ではありません。あくまで、EDT以外のスレッドからの場合です。
> 面倒すぎじゃないでしょうか
すべてマルチスレッドで同期をきちんと考える面倒さと、全部をEDTでやる面倒さ、どっちが面倒か、ですね。
自分としては、用もないのにマルチスレッドで処理したくはありません。
マルチスレッドで、破綻無く動かすのはなかなか面倒です。
SwingWorkerについてですが、長時間の処理を実行したいとき、EDTで処理してしまうとイベントディスパッチループへ処理を返さないことになり、他のイベントを処理できなくなります。画面は固まって、応答なしになります。
となると、重い処理は別のスレッド(作業用スレッド)で実行したくなります。問題は画面へのアクセスです。プログレスバーのように、処理中の状況を画面に表示したいことがあると思います。しかし、EDT以外のスレッドからSwingコンポーネントにはアクセスできません。描画処理はイベントを送ってEDT側で処理する必要があります。
SwingWorkerは、この手の作業用スレッドとEDTとのやりとりや、作業スレッドの再利用など、面倒なところを助けてくれるものです。
便利ですが、使わなければいけないというわけではありません。ルールを守っていれば、自分で同じような仕組みを書けばいいので。でも、便利なので使いますけど。
> 描画系の命令を実行しないのならば、別スレッドを作成して使用しても良い....?
もちろんです。問題になるのは、描画系というかSwingコンポーネント関係です。
ただし、結果を表示したいとなったら、EDTに頼む必要があります。
見えないSwingの中でやっていることがいろいろあるので、なかなか、何がどこのスレッドで、どういうタイミングで動くのかイメージするのが難しいかもしれません。
細かく丁寧にありがとうございます。おかげで私の中で大きく勘違いをしていることに気づくことができました!!
今まで私はソースコードとして書いたプログラムをどのスレッドが行っているのか把握していませんでした。イベントリスナーによって実行されるプログラムなどはメインスレッドが行っているものだと思っていました。そのため理解に苦労していたのだと思います。
詳しい説明をありがとうございました! これからはSwingのスレッドポリシーに則ってプログラムを書こうと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・2024年に成し遂げたこと
- ・3分あったら何をしますか?
- ・何歳が一番楽しかった?
- ・治せない「クセ」を教えてください
- ・【大喜利】看板の文字を埋めてください
- ・【大喜利】【投稿~12/17】 ありそうだけど絶対に無いことわざ
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・【穴埋めお題】恐竜の新説
- ・我がまちの「給食」自慢を聞かせてっ!
- ・冬の健康法を教えて!
- ・一番好きな「クリスマスソング」は?
- ・集合写真、どこに映る?
- ・自分の通っていた小学校のあるある
- ・フォントについて教えてください!
- ・これが怖いの自分だけ?というものありますか?
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・10代と話して驚いたこと
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VB.NETのSendMessageを教えてく...
-
VB.NET フォーム上に描いたグ...
-
C#のGraphicsクラスについてです。
-
複数画像表示切り替え Visual c++
-
getGraphics()の意味を教えて...
-
ドラッグして矩形を描くには
-
DirectXのスプライト機能で3D回転
-
VS Treeview のデザイン変更
-
javaでクイズ
-
JAVAでの背景画像表示
-
iアプリ実行時の実際のウィンド...
-
JavaでのDirectXの使用
-
Java Script 色を塗れるプログ...
-
「タイプ初期化子が例外をスロ...
-
エクセルVBAで、条件に一致する...
-
オブジェクト参照がオブジェク...
-
VBA コピーが出来ません…!
-
配列の重複する値とその個数を...
-
変数名の付け方
-
エクセルVBA 画像を貼り付ける...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
JAVAでの背景画像表示
-
VB.NET フォーム上に描いたグ...
-
画面のちらつきの原因が知りた...
-
VB.NETのSendMessageを教えてく...
-
SwingとEDT(イベントディスパッ...
-
重なった要素上でのイベントで...
-
C# DataGridView のCellPaintin...
-
Canvas等の図形を移動する時,直...
-
描画処理が実行されない
-
複数画像表示切り替え Visual c++
-
Javaで割り当てられていない文...
-
requestanimationframeを一斉に...
-
アクセスで他アプリから復帰し...
-
C# リストビューの特定のセルの...
-
Androidで画像の中で指定した範...
-
このプログラミングをどう組み...
-
Javaで文字の角度を変えて表示...
-
javaのpaintComponentについて
-
java.awt.peer?
-
Labelコントロールの背景をグラ...
おすすめ情報