イベント処理

さて、画面ができたので、イベント処理です。

DirectoryFieldEditor クラスは PropertyChangeEvent が扱えるそうなので、さっそく次のようなコードを書いてみました。

        home.setPropertyChangeListener(new IPropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                if(event.getProperty().equals(FieldEditor.VALUE)) {     
                    System.out.println("LG3D Home: " + home.getStringValue()); 
                }
            }
        });

実行してみてわかったのですが、PropertyChangeListener なのでフォーカスが変わったときやファイルチューザーが閉じたときにイベントが発生するようです。

逆にいえば、[Apply] や [OK] が押されたときには分からないのです。当たり前ですけど。

[Apply] や [OK] が押されたときは、DirectoryFieldEditor からはフォーカスがはずれるので、1 度はイベントがとれるのですが...

さて、どうしたものか?

困ったときは何はなくとも Javadoc。

DirectoryFieldEditor クラスは調べてもあまり意味がなさそうなので、このプリファレンス画面を構成している PreferenceData クラスの Javadoc を見てみました。

そうすると、ありました。あやしそうなメソッドが。

  • public void applyData(Object data);
  • public boolean okToLeave();
  • protected void performApply();
  • public boolean performCancel();
  • protected void performDefaults();
  • public boolean performOk();

このあたりのメソッドがにおいます ^^;; それにしても同じようなメソッド名なのに public だったり、protected だったりするのはなぜなんでしょう? それに戻り値も void と boolean が混ざっているのはなにか意味があるのでしょうか?

考えてもしかたないので、やってみます。というわけで、こんなコードを書いてみました。

    public void applyData(Object data) {
        System.out.append("applyData");
    }
    
    public boolean okToLeave() {
        System.out.println("okToLeave");
        
        return true;
    }

    protected void performApply() {
        System.out.println("performApply");
    }

    public boolean performCancel() {
        System.out.println("performCancel");
        return true;
    }
    
    protected void performDefaults() {
        System.out.println("performDefaults");
    }
    
    public boolean performOk() {
        System.out.println("performOK");
        
        return true;
    }

実行すると、

  • Apply ボタン -> performApply
  • Restore Defaults ボタン -> performDefaults
  • OK ボタン -> performOK
  • Cancel ボタン -> performCancel
  • 何もボタンを押さずに他の Project Looking Glass でない項目に移動 -> okToLeave
  • 他の項目で OK ボタン -> どれもコールされない
  • 他の項目で Cancel ボタン -> どれもコールされない

という結果が得られました。

これでだいたい分かったわけですが、問題は他の項目に移ってしまった後に OK を押された場合、LG3D Home を更新すべきかどうかです。

でも、この時は OK が押されたのか Cancel が押されたのか分からないので、どうするべきか。

他の項目を見てみると、どうやら項目を移ったときに値を更新しているようなので、ここでもそうすることにします。

ようするに performApply メソッドと performOk メソッドと okToLeave メソッドで同じ処理をさせるということです。

とりあえず、この 3 つのメソッドでは updateHome をコールするようにしました。

    private void updateHome() {
        System.out.println("LG3D Home: " + home.getStringValue()); 
    }

次はこの値のロードとセーブです。