みんゴル続き

作者のid:mshimuraさんにレスと解決策の提案を戴きました。
http://d.hatena.ne.jp/mshimura/20070224

そもそもの話だった

結論から行きますと、今回のうちの仕様ではやはりFocusLostでのバリデーションは無理でした。

顧客マスタから顧客を指定しなくてはいけないのですが、このマスタはコード体系がなく、名称と住所からユーザーさんが特定して指定しなければいけないんですけども、顧客検索ダイアログを出してそこで検索された一覧から指定したいのを選んでもらう形になります。そうすると、元画面の顧客入力欄は編集不可で指定されたデータをアプリ側でsetText()してやるんですが、これがValueModelに入らなくなっちゃう。

こればっかりはしょうがないですよね。

そんな訳で、結局FocusLostでのコミットはfalseで行く事にしました。

フォーカス移動してみた

これで終わっては申し訳ないので、強制フォーカス移動をやってみた結果を報告します。

まずは本筋と関係ない所で勉強になった所。ご提案して戴いた、

KeyboardFocusManager.getCurrentKeyboardFocusManager()
      .addKeyEventDispatcher(new KeyEventDispatcher(){
        public boolean dispatchKeyEvent(KeyEvent evt){ 
                 int keyCode = evt.getKeyCode();
                if ( keyCode == KeyEvent.VK_F9) {
                    KeyboardFocusManager.getCurrentKeyboardFocusManager()
            .focusNextComponent();
                    formManager.getFormValidationManager().Validate(true);
                }
                return false;
            } 
        });

の方法ですと、モーダルで開かれた別ダイアログで押されたF9まで拾っちゃいまして、ダイアログから元画面に戻って来たら登録処理が走っちゃいました。あと、JFrameを閉じてからもインスタンスが生きてる内は拾われちゃいますね。

dipatchKeyEventでreturn falseを返してるって事はディスパッチすんなって事のような気もするんですけど、もしかしたらevt.setKeyCode(0)とかやってにぎりつぶさないとダメかも知れません。

なんて事に気が付いた時にはもうリポジトリからソースを元に戻しちゃった後だったので、これまでファンクションのキーアサインは、ActionとInputMapとActionMapを使ったやり方でやってましたので(面倒くさいなあと思いつつ)、そっちでやってみました。

Action actionF9KeyEvent = new AbstractAction() {
    public void actionPerformed(ActionEvent actionEvent) {
        KeyboardFocusManager.getCurrentKeyboardFocusManager()
                .focusNextComponent();
        formManager.getFormValidationManager().Validate(true);
        //ここにF9の処理
    }
};

InputMap im = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_F9,0),actionF9KeyEvent);
ActionMap am = getRootPane().getActionMap();
am.put( actionF9KeyEvent , actionF9KeyEvent );

で、やってみたんですが、動きはOKです。ただ、バリデーションエラーが出るたびにフォーカスが移動して行くのが、うーん、意見の分かれる所でしょうかねぇ。やっぱり。

要望

実際に画面を作ってる部下からの要望がございまして。半分くらいは私からでもありますが。

  • ErrorとWarningの他に、Infoのメッセージも出したい。
    • ソースを読んだらなんとなく準備はされている予感が・・・。
  • 一つのコンポーネントにValidatorを複数Bindしたい。
    • csvに複数書けたら嬉しい。
    • それは難儀そうなので、VaidatorChainみたいなのがあると嬉しい。
  • FocusLostでのコミットの設定は、Bind設定のcsvファイルに列を追加してコンポーネント単位で設定出来るといいな〜。
  • サードパーティなどから入手したコンポーネントとのBindingをしたいんだけど、ある程度自前で書いてもいいのでハウツーみたいなのがあれば知りたい。
    • 特にそのコンポーネントの直接の継承元がもうJComponentだったりするとお手上げ。
    • もしかして、JGoodiesのAPIをちゃんと勉強すれば済むとかそう云う話かも知れない・・・すんません。

どうもわがままばっかで済みません。