• 締切済み

FocusLostでイベント処理を中断させたい

TextFieldでフォーカスを失った時に 入力値をチェックするプログラムがあります。 入力値が不正な場合、メッセージを表示します。 また、終了ボタンで終了するか確認するメッセージを 表示します。 このとき、TextFieldに不正な値を入力し、 終了ボタンを選択するとメッセージが2回表示されます。 TextFieldのFocusAdapterのFocusLost処理により、 他のイベント処理をさせないようにしたいのですが、 戻り値がvoidということもあり、 制御でなきないのでしょうか? よい方法はありますか? キーイベントとマウスイベントで フォーカスのあるコンポーネントを保持し、 変更されたら入力値チェックを行う。 と考えてみましたが、何か問題が起きてしまいそうで。 よろしくお願いします。

みんなの回答

  • takaP-
  • ベストアンサー率79% (83/105)
回答No.2

>フォーカスが外れた時点でDBからデータを取ってきてまして、自動表示をさせたい箇所があるんです。 うーん、必然性がいまいち理解できませんが、どうしてもフォーカスイベントで処理したいという事だけは解かりました。 で、2つのイベント発生の内、一方のイベント処理を無効にする一番単純な方法は判定用フラグを使う方法でしょうかね。 要するに、windowClosing() メソッドが呼ばれた場合は、同時に発生する focusLost() メソッド内の処理を行わなければ良いのですから、、、 boolean flag=true; と、メンバ領域でブール変数 flag を宣言しておき、フォーカスロストイベント内の処理を実行する時は、、、 public void focusLost(FocusEvent e){   if (flag){     // DB からのデータの取得..etc...   } } と、判定用のブール値が真の場合にだけにします。 で、次はウインドウクローズ内の処理です、、、 public void windowClosing(WindowEvent e){   flag=false;   final Dialog d=new Dialog();   Button close=new Button("CLOSE");   close.addActionListener(new ActionListener(){     public void actionPerformed(ActionEvent ae) {       System.exit(0);     }   });   Button cancel=new Button("CANCEL");   cancel.addActionListener(new ActionListener(){     public void actionPerformed(ActionEvent ae){       d.setVisible(false);       flag=true;     }   });   // サイズ指定や、ボタン組み込み等の処理は省略 } と、まずは判定用ブール値を偽にします。 これで、この後でフォーカスロストイベントが呼び出されても DB 等へのアクセス処理は実行されません。 終了するのでしたら判定用ブール値はそのままで構いませんが、もし終了をキャンセルした場合には再度判定値を真へ戻さなくてはいけませんので、キャンセルボタンを押したときにその処理をしています。 しかし、一抹の不安として「どのプラットフォーム、VM でも必ず WindowEvent→FocusEvent」という同じ順序でイベントが発生する保証があるのかどうか不明な点です。 ですから、本当だったらフォーカスイベントとウィンドウイベント2つのイベントが同時に処理され得るという事態は避けた方が無難なのですけどね。

yuyama
質問者

お礼

ありがとうございます。 やっぱり確実性は不明ですね。 イベントは思い通りにならないようで。 なんとかやってみます。

  • takaP-
  • ベストアンサー率79% (83/105)
回答No.1

TextField にフォーカスが当たった状態から、Frame 右上の閉じるボタン「×」が押された場合に WindowEven、FocusEvent の両方が発生し2つダイアログ(又は、それに類するメッセージ・応答処理)が表示されてしまうという事でしょうか? 上記の解釈が正しいと仮定して、気になる点があります。 ユーザから見て、閉じるボタンを押すという事は「作業を途中であっても停止し、アプリケーションを終わらせたい」場合だと思います。 もちろん、押し間違えという事も考えられますが、今回の場合は終了時にも終了等の了承確認をする訳ですから、その対応で押し間違え等の問題回避は出来ている訳です。 そのユーザの意思決定に関わらず、TextField への入力が完了していない場合は終了よりも優先して強制的な入力完了を強いるというのはアプリケーション上問題があると感じました(下手に厳しい入力条件であれば終了が出来ないという悲劇にもなりかねません・笑) ですから、今回の場合、WindowEvent と FocusEvent でどちらを捨てるのかといえば FocusEvent の方になると思うのですがいかがでしょうか。 と、話しが多々脱線してしまいましたが、解決策を(笑 ここの掲示板などもそうですが、記入項目毎に入力値チェックをするのではなく、ユーザが記入を済ませたと「思った」時点で「OK」などの確認用ボタンを押してもらい、その時点で入力項目のチェックをするという手順を踏めば良いのではないかと思います。 まぁ、でもこの手の問題はケース・バイ・ケースですから上の方法を取れない場合もあるかと思います。 その場合は、その理由を補足して下さい。 そうすれば、それに合わせた回答なりアドバイスなりができると思いますので。

yuyama
質問者

お礼

ありがとうございます。 フォーカスが外れた時点でDBからデータを取ってきてまして、自動表示をさせたい箇所があるんです。 他についてはアドバイスいただいたように確認用ボタンでチェックするようにしています。 なので、終了する前にチェックが行われてしまう、という状況に陥っています。 また何か手がありましたら教えてください。

関連するQ&A