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

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

  •  03-07-2019
  •  | 
  •  

Вопрос

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

Например, у меня есть поле ввода ( 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) Создайте внутренний класс 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("");
  }
}

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

Другие советы

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top