如何使用侦听器访问其他元素?
-
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中出于任何目的使用侦听器是很常见的问题:如何让处理程序访问通知侦听器或其对等方的对象。
通常有两种惯例。
一种是直接从事件对象获取对象。你可以用getSource()做到这一点。但是那时你只会得到完成它的小部件。
另一个选择是让侦听器类能够访问窗口小部件。一种方法是使用非静态内部类(这取决于您如何声明它),在这种情况下,允许访问包含类的成员。
但是,在这种情况下,您的小部件是变量,而不是成员(您确定要这样做吗?)。所以你唯一的解决方案就是让成员在Listner类中保存它们,然后在addListener调用中创建一个监听器,创建一个监听器,传递相关的小部件,然后添加监听器。监听器现在可以通过他们对存储在成员中的对它们的引用来访问这些小部件。