Pergunta

Estou configurando uma GUI onde preciso obter informações inseridas dos elementos de formulário e manipular as informações. Isso exige que eu use alguns elementos para acessar outros.

Por exemplo, eu tenho uma caixa de entrada (JTextField) e um botão (JButton) ao lado dele. Quando o botão é pressionado, preciso manipular o texto inserido na caixa de entrada. Tudo o que tentei fazer até agora para fazer isso falhou.

É assim que meu código parece agora (incorporei minhas perguntas nos comentários):

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

Obrigado por qualquer ajuda!

Foi útil?

Solução

Esse é um problema de escopo variável.

Atualmente, o campo de texto e o botão estão no escopo do main método, portanto, ter uma classe separada para o ActionListener significará que não terá acesso a essas variáveis.

Existem algumas maneiras de conseguir isso:

(1) Faça uma classe interna ListenerClass dentro MyClass, e girar o myTextField e myTextFieldSubmit em campos de instância 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) fazer uma classe interna anônima na main método, e isso permitirá myTextField e myTextFieldSubmit permanecer no mesmo lugar, desde que sejam declarados 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) Faça uma classe local que seja local para o main método. Novamente, isso exigirá que o campo de texto e o botão sejam declarados final Para permitir o acesso da classe 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) entregando uma referência ao ListenerClass, por exemplo, no construtor, e também fazendo myTextField e myTextFieldSubmit uma variável de instância.

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) fazer myTextField e myTextFieldSubmit em static campos e permitir acesso direto do 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("");
  }
}

Provavelmente ainda existem mais maneiras de conseguir isso, e pode haver melhores maneiras de implementar isso. A escolha de qual abordagem você adota realmente depende do design desejado do aplicativo.

Outras dicas

Você pode passar em uma referência a MyClass no construtor para ListenerClass.

Seu problema é comum ao uso de ouvintes para qualquer finalidade em Java: como deixar o manipulador acessar o objeto que notificava os ouvintes ou seus colegas.

Geralmente, existem duas convenções.

Um é obter o objeto diretamente do objeto de evento. Você pode fazer isso com getSource (). Mas então você só conseguiria o widget que o fez.

Outra opção é que a classe do ouvinte possa acessar os widgets. Uma maneira é usar classes internas não estáticas (depende de como você o declara); nesse caso, é permitido acessar os membros da classe que contém.

No entanto, neste caso, seus widgets são variáveis, não membros (você tem certeza de que deseja fazer isso?). Portanto, sua única solução seria que os membros os mantenham na classe Listner e, em vez de criar o ouvinte na chamada addlistener, criar um ouvinte, passar os widgets relevantes e adicionar o ouvinte. O ouvinte agora pode acessar esses widgets através de suas próprias referências a eles que são armazenados nos membros.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top