Как я могу использовать слушателей для доступа к другим элементам? - PullRequest
3 голосов
/ 03 мая 2009

Я настраиваю графический интерфейс, где мне нужно брать информацию, введенную из элементов формы, и манипулировать информацией. Это требует, чтобы я использовал некоторые элементы для доступа к другим.

Например, у меня есть поле ввода (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?
    }
}

Спасибо за любую помощь!

Ответы [ 3 ]

4 голосов
/ 03 мая 2009

Это очень большая проблема с переменной областью действия.

В настоящее время текстовое поле и кнопка находятся в области действия метода main, поэтому наличие отдельного класса для ActionListener будет означать, что у него не будет доступа к этим переменным.

Есть несколько способов добиться этого:

(1) Создайте внутренний класс ListenerClass в MyClass и превратите 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("");
  }
}

Вероятно, есть еще способы достичь этого, и, возможно, есть более эффективные способы реализации этого. Выбор того, какой подход вы выберете, действительно зависит от желаемого дизайна приложения.

0 голосов
/ 03 мая 2009

Ваша проблема характерна для использования слушателей для любых целей в Java: как разрешить обработчику доступ к объекту, который уведомил слушателей или его пиров.

Обычно существует два соглашения.

Один из них - получить объект непосредственно из объекта события. Вы можете сделать это с помощью getSource (). Но тогда вы получите только виджет, который это сделал.

Другой вариант - иметь класс слушателя для доступа к виджетам. Один из способов - использовать нестатические внутренние классы (это зависит от того, как вы их объявляете), и в этом случае разрешается доступ к членам содержащего класса.

Однако в этом случае ваши виджеты являются переменными, а не членами (вы уверены, что хотите это сделать?). Таким образом, ваше единственное решение состояло бы в том, чтобы члены удерживали их в классе Listner, а затем вместо создания слушателя в вызове addListener создайте слушателя, передайте соответствующие виджеты и добавьте слушателя. Теперь слушатель может получить доступ к этим виджетам через свои собственные ссылки на них, которые хранятся в элементах.

0 голосов
/ 03 мая 2009

Вы можете передать ссылку на MyClass в конструкторе на ListenerClass.

...