Melhor forma de estruturar os "Actions"

7 respostas
ArchV

Olá, estou afim de saber qual é a forma mais elegante em projetos sérios de tratar eventos (é uma pergunta meio genérica, mas irão entender) por exemplo, existe um JFrame principal, sendo que este contém botões que irão receber eventos. A Melhor maneira de estruturar seria fazendo o JFrame implementar a interface ActionListener (no actionPerformed, irei ter que fazer vários ifs - se existir vários botões para descobrir o getSource(); Ou criando uma private class que implements ActionListener sendo assim, cada objeto addActionListener(new MinhaClassePrivate()), aqui eu poderia fazer um getActionCommand() e comparar os nomes de todos os botões, e dessa forma as formas de resolver o problema irei ter o mesmo trabalho.

Vocês já passaram por esta situação em projetos sérios, qual a opnião?

7 Respostas

M

Eu costumo usar classes anônimas que apenas chamam algum método (e esse método é quem faz toda a lógica da ação). Não que seja a melhor forma, pois existem várias outras, mas costuma fazer algo como:

meuBotao.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        fazerAlgoRelacionadoAEsseBotao(); // aqui eu chamo algum método
    }
});
ArchV

marcobiscaro2112:
Eu costumo usar classes anônimas que apenas chamam algum método (e esse método é quem faz toda a lógica da ação). Não que seja a melhor forma, pois existem várias outras, mas costuma fazer algo como:

meuBotao.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fazerAlgoRelacionadoAEsseBotao(); // aqui eu chamo algum método } });

Também já usei classes anônimas (gosto bastante), acho que é a forma que mais economiza linhas de códigos.
vlw marco.
Mas alguém tem algo a discutir sobre o assunto?

walissongpi

ArchV:
marcobiscaro2112:
Eu costumo usar classes anônimas que apenas chamam algum método (e esse método é quem faz toda a lógica da ação). Não que seja a melhor forma, pois existem várias outras, mas costuma fazer algo como:

meuBotao.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fazerAlgoRelacionadoAEsseBotao(); // aqui eu chamo algum método } });

Também já usei classes anônimas (gosto bastante), acho que é a forma que mais economiza linhas de códigos.
vlw marco.
Mas alguém tem algo a discutir sobre o assunto?

É a forma mais indicada para eventos. Isso é fato.

sergiotaborda

ArchV:
Olá, estou afim de saber qual é a forma mais elegante em projetos sérios de tratar eventos (é uma pergunta meio genérica, mas irão entender) por exemplo, existe um JFrame principal, sendo que este contém botões que irão receber eventos. A Melhor maneira de estruturar seria fazendo o JFrame implementar a interface ActionListener (no actionPerformed, irei ter que fazer vários ifs - se existir vários botões para descobrir o getSource(); Ou criando uma private class que implements ActionListener sendo assim, cada objeto addActionListener(new MinhaClassePrivate()), aqui eu poderia fazer um getActionCommand() e comparar os nomes de todos os botões, e dessa forma as formas de resolver o problema irei ter o mesmo trabalho.

Vocês já passaram por esta situação em projetos sérios, qual a opnião?

  1. Nunca faça um JComponent implementar um Listener. Isso é um anti=pattern. Use inner classes, ou melhor ainda use classes diferentes.

  2. Quem recebe o evento de aplicação deve ser um objeto não-swing, conhecido como presenter. Ele recebe o evento e responde a ele.
    2.1. Também não faça um JComponent ser um Presenter

  3. use os listeners para transformar entre eventos do swing e de aplicação

Veja que botão é botão mas apertar um botão “sair” pode ter o mesmo efeito que apertar a cruz no canto da janela. São dois eventos swing diferentes que produzem o mesmo evento de aplicação, no caso sair.

Vc programaria assim:

vc cria um objeto não-swing , um POJO da vida. vamos chama-lo Presenter.
O presenter tem um método para cada coisa que vc precisa. Por exemplo, sair, salvar, etc…
no botão vc associar um actionListener como uma inner classe que chama o evento no presenter

public class MinhaTela extends JFrame {

   private final MinhaTelaPresenter presenter  = new MinhaTelaPresenter (); // melhor se injetado no contutor

  public MinhaTela (){
   setUpDisplay();
}

   private void setUpDisplay(){ 

 // monta os objetos swing no lugar
// em algum ponto vc fará

  JButton button = new JButton("Salvar");
  button.addActionlistener (new ActionListener(){
        public void performAction(ActinoEvent e){
                presenter.save();
        }
  });

   }

  // este estou fazendo de memoria, não lembro direito se as asinaturas são estas
   this.addWindowlistener (new WindowListener{
          public void onClose(){
                 presenter.sair();
         }

    }
  
} 

}

Entenda que cada objeto tem o seu listener. Vc pode compartilhar listeners se a ação forma mesma.
por exemplo poderia ter um botao e um menu para “sair”, como ambos aceita actionListerns blz, mas no caso do windowClose já não dá.

Pense OO. Escreva OO.

ArchV

sergiotaborda:

(…)
Pense OO. Escreva OO.

Legal, vlw entendi o conceito.

O tópico então irá permanecer em aberto, caso alguém desejar comentar mais alguma coisa.

Obrigado a todos.

R

classes anônimas tem que implementar o metodo actionPerformed para cada componente ? assin nao é mais codigo ?

sergiotaborda

é mais codigo. E dai?

O objetivo é ter codigo limpo, não pouco codigo.

Contudo se vc não quiser ter isso facilmente va implementa um mecanismo de proxy que funcione assim:

button.addActionPerformed ( PresenterBind.buind(Presenter.class, "save"));

Menos código :smiley: :smiley: :smiley:

Criado 11 de fevereiro de 2010
Ultima resposta 12 de fev. de 2010
Respostas 7
Participantes 5