多くのサイトを見て、色々考えているのですが、イマイチ理解が及びません。以下のような風に思っていていいのでしょうか。
・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で質問しましょう!
似たような質問が見つかりました
- CAD・DTP 「機能ブロック図」の描画用フリーソフトを教えてください 1 2022/09/23 16:12
- その他(アニメ・マンガ・特撮) 名探偵コナンって主人公酷いヒロイン可哀想を強調したい作品ですか? 色んな漫画恋愛漫画数々読んできたも 1 2022/07/27 04:54
- 美術・アート トレパク疑惑をかけられにくくするには ここ最近いわゆるトレパク警察のいいがかりがが厳しくなったようで 1 2023/08/21 09:59
- Visual Basic(VBA) VBA リボンののリカバリーでオーバーフローエラーになります 2 2023/07/04 19:07
- 日本語 助詞「は」と「が」の使い方の違いを教える簡単な方法 21 2022/08/16 08:06
- その他(悩み相談・人生相談) 漫画業界ってフォロワー多ければ簡単なんですか? 価値 希望 可能性 将来性がある人間ってどんな人です 1 2022/04/26 21:56
- 英語 描写述語の条件(本来の性質、一時的な属性、又は両方)について 2 2022/07/25 13:41
- 数学 最大エントロピー原理をpythonで実装したい 2 2022/06/21 13:10
- 一眼レフカメラ SONYα7Rⅳの画質 2 2023/03/22 14:01
- マンガ・コミック 漫画の練習方について 1 2022/06/06 19:26
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
JAVAでの背景画像表示
-
画面のちらつきの原因が知りた...
-
VB.NET フォーム上に描いたグ...
-
MFCでMSペイントみたいなツー...
-
javaでクイズ
-
複数画像表示切り替え Visual c++
-
<JFreeChart> 縦軸の値の間隔を...
-
javaアプレットで太字を描く方法。
-
C# DataGridView のCellPaintin...
-
SwingとEDT(イベントディスパッ...
-
canvasで表示されてる画像を1...
-
「タイプ初期化子が例外をスロ...
-
変数名の付け方
-
エクセルVBAで、条件に一致する...
-
複数の変数を宣言する時、同時...
-
C# インスタンスの破棄
-
インスタンス参照でアクセスで...
-
関数内の変数に<summary>コメン...
-
VB.NET getとsetの概念がわかり...
-
main()を持つクラスが2つ以上...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
JAVAでの背景画像表示
-
VB.NET フォーム上に描いたグ...
-
VB.NETのSendMessageを教えてく...
-
C# DataGridView のCellPaintin...
-
SwingとEDT(イベントディスパッ...
-
描画してもウィンドウをリサイ...
-
GDI+で描画した画像を消去する...
-
C# リストビューの特定のセルの...
-
画面のちらつきの原因が知りた...
-
重なった要素上でのイベントで...
-
C#のGraphicsクラスについてです。
-
アクセスで他アプリから復帰し...
-
Javaで文字の角度を変えて表示...
-
Canvas等の図形を移動する時,直...
-
canvasで表示されてる画像を1...
-
複数画像表示切り替え Visual c++
-
PictureBoxのDrawWidthの設定
-
C# でパネルのマウスイベントが...
-
JavaScriptについて
-
このプログラミングをどう組み...
おすすめ情報