3

我正在设置一个 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?
    }
}

谢谢你的帮助!

4

3 回答 3

5

这在很大程度上是一个可变范围问题。

目前,文本字段和按钮都在该main方法的范围内,因此拥有一个单独的类ActionListener将意味着它无法访问这些变量。

有几种方法可以实现这一点:

(1) 在 中创建一个内部类ListenerClassMyClass并将myTextFieldmyTextFieldSubmit变成 的实例字段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,这将允许myTextFieldmyTextFieldSubmit保持在同一个地方,只要它们被声明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,例如在构造函数中,以及创建myTextFieldmyTextFieldSubmit实例变量。

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) makemyTextFieldmyTextFieldSubmitintostatic字段,并允许从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("");
  }
}

可能还有更多方法可以实现这一点,并且可能有更好的方法来实现这一点。您采用哪种方法的选择实际上取决于应用程序的所需设计。

于 2009-05-03T03:06:01.583 回答
0

您可以将MyClass构造函数中的引用传递给ListenerClass.

于 2009-05-03T02:59:40.180 回答
0

您的问题对于在 Java 中出于任何目的使用侦听器都很常见:如何让处理程序访问通知侦听器或其对等方的对象。

一般有两种约定。

一种是直接从事件对象中获取对象。你可以用 getSource() 来做到这一点。但是你只会得到做到这一点的小部件。

另一种选择是让侦听器类能够访问小部件。一种方法是使用非静态内部类(这取决于您如何声明它),在这种情况下,它可以访问包含类的成员。

但是,在这种情况下,您的小部件是变量,而不是成员(您确定要这样做吗?)。因此,您唯一的解决方案是让成员将它们保存在 Listner 类中,然后在 addListener 调用中创建侦听器,而不是创建侦听器,传递相关的小部件,然后添加侦听器。侦听器现在可以通过他自己对存储在成员中的引用访问这些小部件。

于 2009-05-03T03:03:17.673 回答