Как я могу использовать слушателей для доступа к другим элементам?
-
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 создайте прослушиватель, передайте соответствующие виджеты и добавьте прослушиватель. Теперь слушатель может получить доступ к этим виджетам через свои собственные ссылки на них, которые хранятся в элементах. Р>