0

私は現在、グループの最初の学期の試験プロジェクトのGUI部分に取り組んでおり、コールバックとイベント処理に関して奇妙な問題に遭遇しました。

少し外れたトピック:私はこれを一生懸命ググったが、Javaでコールバックを使用する具体的な例を見つけることができなかったので、私が集めたものから...定義上...ここで私がしていることは実際にはコールバック(理由を説明できるか、それを完全に説明しているページを教えていただければ素晴らしいと思います)

コードは次のとおりです。

private FocusListener callback = new FocusListener(){
    @Override public void focusGained(FocusEvent e){
        if(hasBeenSet){}else{tfield.setText("");hasBeenSet=true;}
    } @Override public void focusLost(FocusEvent e){}};

    ...

    tfield = new JTextField("Insert CPR number", 8);
    constraint.gridx = 0;
    constraint.gridy = 1;
    constraint.gridwidth = 2;
    panel.add(tfield, constraint);

            tfield.addFocusListener(callback);

    tfield = new JTextField("Type new password", 8);
    constraint.gridx = 0;
    constraint.gridy = 2;
    panel.add(tfield, constraint);

            tfield.addFocusListener(callback);

    tfield = new JTextField("Retype new password", 8);
    constraint.gridx = 0;
    constraint.gridy = 3;
    panel.add(tfield, constraint);

            tfield.addFocusListener(callback);

GUIを起動すると、これらの3つのテキストフィールドがあり、ユーザーがテキストフィールドにフォーカスしたときにテキストを削除するという考え方があります。これは3つのテキストフィールドすべてで機能するはずですが、どのテキストフィールドをクリックしても、最後のテキストフィールドのみが空の文字列に設定されるようです。各オブジェクトは個別にインスタンス化されるため、これについて最も興味があります。

ここでの明らかな回避策は、tfieldの名前を「tfield [1-3]」のように変更することですが、これでユーモアを交えていただければ幸いです:)

また、すべてのGUIコードは実際にはコンストラクター内にあることに注意してください。はい、これは完全にばかげていることを私は知っていますが、私たちの設計は、コンストラクターが完了した後にすべてのロジックとデータ処理が行われることを示唆しています...したがって、ここで脅威はないはずですが、これがそうなるかどうかはわかりませんどういうわけかFocusListenerのコールバックメソッドと競合します。

ありがとうございました。:)

PS「新しいパスワードの再入力/入力」フィールドについては、JComponent JPasswordFieldを承認します。これは、この問題が修正された後に変更されます。したがって、セキュリティ警告は必要ありません:)

4

1 に答える 1

2

tfield変数は、の最後のインスタンスへの参照を保持ますJTextField。あなたが望むことをする方法はこれです:

private FocusListener callback = new FocusListener() {
    @Override public void focusGained(FocusEvent e){
        JTextField jtf = (JTextField) e.getSource();
        if(hasBeenSet){}else{jtf.setText("");hasBeenSet=true;}
    }
    ...

注:コードが現時点で読み取られるように、hasBeenSet3つのテキストフィールドすべてで共有されます。

アップデート:

Javaはクロージャをサポートしていないため、実行時に、listernerがインストールされたときの値ではなく、focusGainedの最後の値が表示されます。tfieldtfield

hasBeenSetは外部クラスのメンバーとして定義されているようで、3つのテキストフィールドすべてについて同じ変数をfocusGainedチェックしているようです。これがあなたがやろうとしていると私が思うことを処理する方法です:

tfield = new JTextField("Insert CPR number", 8);
tfield.putClientProperty("originalText", tfield.getText());

次に、focusGainedで:

    @Override public void focusGained(FocusEvent e){
        JTextField jtf = (JTextField) e.getSource();
        if(jtf.getClientProperty("originalText").equals(jtf.getText())){
             jtf.setText("");
        }
    }

putClientProperty/getClientPropertyメソッドはクラスで定義されてJComponentいるため、から継承するすべてのSwingGUIコンポーネントで使用できますJComponent。指定された文字列を保存/取得しObjectます。この場合、文字列「originalText」は、を初期化するために最初に使用された値を保持しますJTextField。フォーカスを取得しても、フィールドにその値が含まれている場合は、空白に設定されます。focusLost同様に、フィールドが空白の場合、「originalText」に対して取得された値に設定するという同様の操作を実行できます。

于 2012-05-24T17:46:51.850 に答える