リスナーを使用して他の要素にアクセスするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/816188

  •  03-07-2019
  •  | 
  •  

質問

フォーム要素から入力された情報を取得し、その情報を操作する必要があるGUIをセットアップしています。このため、他の要素にアクセスするにはいくつかの要素を使用する必要があります。

たとえば、入力ボックス( JTextField )とその横にボタン( JButton )があります。ボタンが押されたら、入力ボックスに入力されたテキストを操作できるようにする必要があります。これを成し遂げるためにこれまでにやろうとしたことはすべて失敗しました。

これは私のコードが今どのように見えるかです(コメントに質問を埋め込みました):

public class MyClass
{
    public static void main(String args[])
    {
        // Form elements are in here
        JTextField myTextField = new JTextField(10);
        JButton myTextFieldSubmit = new JButton("Submit");
        myTextFieldSubmit.addActionListener(new ListenerClass());
    }
}

class ListenerClass implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        // This is what happens when these elements are used
        // I need to be able to access the form elements from MyClass in here, but this doesn't seem possible with my current setup
        // For example, when the Submit button is pressed, I need to be able to myTextField.getText() and edit MyClass members
        // How should my setup be changed to accommodate these needs?
    }
}

ご協力ありがとうございます!

役に立ちましたか?

解決

これは非常に可変スコープの問題です。

現在、テキストフィールドとボタンは main メソッドのスコープ内にあるため、 ActionListener に個別のクラスがあると、アクセスできなくなりますそれらの変数。

これを達成するにはいくつかの方法があります:

(1) MyClass で内部クラス ListenerClass を作成し、 myTextField および myTextFieldSubmit をインスタンスに変換します MyClass のフィールド。

public class MyClass
{
  final static JTextField myTextField = new JTextField(10);
  final static JButton myTextFieldSubmit = new JButton("Submit");

  public static void main(String args[])
  {
    myTextFieldSubmit.addActionListener(new ListenerClass());
  }

  static class ListenerClass implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {
      myTextField.setText("");
    }
  }
}

(2) main メソッドで匿名内部クラスを作成すると、 myTextField myTextFieldSubmit が同じ場所に残ることができます、 final と宣言されている限り。

public class MyClass
{
  public static void main(String args[])
  {
    final JTextField myTextField = new JTextField(10);
    final JButton myTextFieldSubmit = new JButton("Submit");

    myTextFieldSubmit.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {
            myTextField.setText("");
        }
    });
  }
}

(3) main メソッドに対してローカルなローカルクラスを作成します。この場合も、内部クラスからのアクセスを許可するには、テキストフィールドとボタンを final として宣言する必要があります。

public class MyClass
{
  public static void main(String args[])
  {
    final JTextField myTextField = new JTextField(10);
    final JButton myTextFieldSubmit = new JButton("Submit");

    class ListenerClass implements ActionListener
    {
      public void actionPerformed(ActionEvent e)
      {
        myTextField.setText("");
      }
    }

    myTextFieldSubmit.addActionListener(new ListenerClass());
  }
}

(4)コンストラクターなどで ListenerClass への参照を渡し、さらに myTextField および myTextFieldSubmit をインスタンス変数にします。

public class MyClass
{
  JTextField myTextField = new JTextField(10);
  JButton myTextFieldSubmit = new JButton("Submit");

  public MyClass()
  {
    myTextFieldSubmit.addActionListener(new ListenerClass(this));
  }

  public static void main(String args[])
  {
    new MyClass();
  }
}

class ListenerClass implements ActionListener
{
  MyClass myClass;

  public ListenerClass(MyClass myClass)
  {
    this.myClass = myClass;
  }

  public void actionPerformed(ActionEvent e)
  {
    myClass.myTextField.setText("");
  }
}

(5) myTextField および myTextFieldSubmit static フィールドにし、 ListerClass から直接アクセスできるようにします。

public class MyClass
{
  static JTextField myTextField = new JTextField(10);
  static JButton myTextFieldSubmit = new JButton("Submit");

  public static void main(String args[])
  {
    myTextFieldSubmit.addActionListener(new ListenerClass());
  }
}

class ListenerClass implements ActionListener
{
  public void actionPerformed(ActionEvent e)
  {
    MyClass.myTextField.setText("");
  }
}

これを実現する方法はまだまだあり、これを実装するより良い方法があるかもしれません。どのアプローチを選択するかは、実際にアプリケーションの設計に依存します。

他のヒント

コンストラクタ内の MyClass への参照を ListenerClass に渡すことができます。

あなたの問題は、Javaのあらゆる目的でリスナーを使用する場合によくあります。リスナーまたはそのピアに通知したオブジェクトにハンドラーがアクセスできるようにする方法。

通常、2つの規則があります。

1つは、イベントオブジェクトからオブジェクトを直接取得することです。 getSource()でこれを行うことができます。しかし、その後は、それを実行したウィジェットのみを取得します。

もう1つのオプションは、リスナークラスがウィジェットにアクセスできるようにすることです。 1つの方法は、非静的内部クラスを使用することです(宣言方法によって異なります)。その場合、包含クラスのメンバーへのアクセスが許可されます。

ただし、この場合、ウィジェットはメンバーではなく変数です(実行してもよろしいですか?)。したがって、唯一の解決策は、メンバーをListnerクラスに保持し、addListener呼び出しでリスナーを作成する代わりに、リスナーを作成し、関連するウィジェットを渡し、リスナーを追加することです。リスナーは、メンバーに保存されている独自の参照を介して、これらのウィジェットにアクセスできるようになりました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top