Pregunta

Estoy configurando una GUI donde debo tomar la información ingresada desde los elementos del formulario y manipular la información. Esto requiere que use algunos elementos para acceder a otros.

Por ejemplo, tengo un cuadro de entrada ( JTextField ) y un botón ( JButton ) al lado. Cuando se presiona el botón, debo poder manipular el texto ingresado en el cuadro de entrada. Todo lo que he intentado hacer hasta ahora para hacer esto ha fallado.

Esto es lo que parece mi código en este momento (incrusté mis preguntas en los comentarios):

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?
    }
}

¡Gracias por cualquier ayuda!

¿Fue útil?

Solución

Esto es en gran medida un problema de alcance variable.

Actualmente, el campo de texto y el botón están dentro del alcance del método main , por lo que tener una clase separada para el ActionListener significa que no tendrá acceso a esas variables.

Hay algunas maneras de lograr esto:

(1) Cree una clase interna ListenerClass en MyClass , y convierta myTextField y myTextFieldSubmit en una instancia campos de 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) Cree una clase interna anónima en el método main , y esto permitirá que myTextField y myTextFieldSubmit permanezcan en el mismo lugar , siempre y cuando se declaren 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) Cree una clase local que sea local al método main . Una vez más, esto requerirá que el campo de texto y el botón se declaren final para permitir el acceso desde la clase interna.

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) Proporcionar una referencia a ListenerClass , por ejemplo en el constructor, y también hacer de myTextField y myTextFieldSubmit una variable de instancia.

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) Convierta myTextField y myTextFieldSubmit en los campos static , y permita el acceso directo desde 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("");
  }
}

Probablemente todavía haya más formas de lograr esto y puede haber mejores formas de implementar esto. La elección del enfoque que tome realmente depende del diseño deseado de la aplicación.

Otros consejos

Puede pasar una referencia a MyClass en el constructor a ListenerClass .

Su problema es común al uso de oyentes para cualquier propósito en Java: cómo permitir que el controlador acceda al objeto que notificó a los oyentes o sus compañeros.

Generalmente hay dos convenciones.

Una es obtener el objeto directamente del objeto de evento. Podrías hacer esto con getSource (). Pero entonces solo obtendrías el widget que lo hizo.

Otra opción es hacer que la clase de escucha pueda acceder a los widgets. Una forma es usar clases internas no estáticas (depende de cómo lo declare), en cuyo caso está permitido acceder a los miembros de la clase que lo contiene.

Sin embargo, en este caso, sus widgets son variables, no miembros (¿está seguro de que desea hacer eso?). Entonces, su única solución sería tener miembros manteniéndolos en la clase Listner, y luego, en lugar de crear el oyente en la llamada addListener, cree un oyente, pase los widgets relevantes y agregue el oyente. El oyente ahora puede acceder a esos widgets a través de sus propias referencias a ellos que se almacenan en los miembros.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top