- ベストアンサー
setEnabledが効かない理由とは?
- setEnabledが効かない原因と解決方法を教えてください。
- イベント処理メソッド内でsetEnabledが効かない理由を教えてください。
- ダミーメソッド呼び出し後のsetEnabledの動作について説明してください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
>なぜ、新規生成したスレッドの中でメッセージダイアログが閉じないのか? あれ?私の環境では問題無く了解ボタンで閉じられますが(Win98,SDK1.4.2-beta) >なぜ、スレッドの同期をとると、新規スレッド内で行っているsetEnabledが効かなくなるのか? これもEventDispatchThreadの問題です。 簡単に言うと、actionPerformed()を実行しているのもsetEnabled()の再描画を実行するのも同じスレッドだという事です。 要するに、要求を出す側と要求を実行する側が同じスレッドを使いますので、要求を出す側の処理が終了しない限りは要求を実行する事が出来ないという事です。 ですから、要求を出す側がsleep()やjoin()をしたからといって、その間にsetEnabled()の処理が実行されるという訳にはいかないという事です。 もちろん要求はされてますので、actionPerformed()が終わり次第、順次setEnabled()は実行されますが、連続でfalse→trueとなる為に見た目は処理されていないように見えるだけです。実際には実行されているわけです。 以上の説明ではなかなかピンとはこないかもしれません。 けれど、この辺の事は避けて通る訳にもいかないと思います、資料を集めて一通り理解しておく事をお奨めします。
その他の回答 (2)
- takaP-
- ベストアンサー率79% (83/105)
ああ、、、記述ミスです。訂正させてもらいます。 ×EventDispachThread ○EventDispatchThread 「t」が抜けてました。済みません。
- takaP-
- ベストアンサー率79% (83/105)
jButton1ActionPerformed()というメソッドが、どの様に 呼び出されるのかが解からないのではっきりした事は言え ませんが、恐らくEventDispachThreadから呼び出されて いるのではないかと思われます。 EventDispachThreadがどのようなものかは検索エンジン などで調べてみてください。 対策としてはEventDispachThread以外のスレッドに jButton1ActionPerformed()の処理を任せれば良いかも。 Runnable runnable=new Runnable(){ public void run(){ jButton1.setEnabled(false); jButton2.setEnabled(true); dummyMethod(); //try { // Thread.sleep(2000); //} catch (InterruptedException ie) { //} jButton1.setEnabled(true); jButton2.setEnabled(false); } } ; とRunnableを定義しておいて。 private void jButton1ActionPerformed(ActionEvent e){ new Thread(runnable).start(); } とでもしておけば希望通り(?)に動くのではないかと。 もっと良い方法があるかもしれませんが参考までに。
補足
ご回答ありがとうございます。 早速やってみました。ほぼ希望通りです。 ですが、どうしても未だ突破出来ない部分があります。 dummyMethodからリターンコードを受け、それにより メッセージダイアログを出力させようとしています。新しく生成したスレッド内の dummyMethod呼び出し直後に下のコーディングを行うと、 表示はされるのですが、了解ボタンをクリックしてもメッセージダイアログが消せません。 クローズボックス(×)で消えます。 new JOptionPane().showMessageDialog(null, "Test Test", "", JOptionPane.ERROR_MESSAGE); なぜでしょうか? それで、今度は呼び出し元の方でメッセージダイアログを出力させればいいと思い、 その為には同期する必要があるので、下の様に呼び出し元をコーディングしたのですが、 今度はまたまた、setEnabledが効かなく、元通りになってしまいました。 try { Thread thread = new Thread(measStartRun); thread.start(); thread.join(); } catch (InterruptedException ie) { } new JOptionPane().showMessageDialog(null, "Test Test", "", JOptionPane.ERROR_MESSAGE); なぜ、新規生成したスレッドの中でメッセージダイアログが閉じないのか? なぜ、スレッドの同期をとると、新規スレッド内で行っているsetEnabledが効かなくなるのか? この2点について再度お答え願い無いでしょうか? 以上、よろしくお願いします。
お礼
良くわかりました。納得です。あと、簡単なプログラムを作成し、同じように子スレッド内でJOptionPaneを使用したらうまく、了解ボタンで閉じました。これについては、別途調査します。ありがとうございました。