Codigo executando duas vezes, por que?

12 respostas
F

Aí gurizada, o código abaixo é do teste que estou fazendo com um combo box, o esquema é o seguinte quero que quando o usuário der enter dentro do combo dispare um método, nesse teste fiz um método simples que apenas pega o que tá no combo e mostra na tela, o que tá acontecendo é muito estranho, a primeira vez que dou enter ele executa o método duas vezes, aí nas próximas apenas uma, se eu escrever algo no combo e depois der enter na primeira vez ele executa duas vezes e nas próximas apenas uma, aí se eu alterar o combo de novo, ele na primeira executa o método 2 vezes e depois apenas uma, tá meio confuso mas se vcs executarem o código vão ver o que estou tentando explicar, por que será que acontece isso ??

import java.awt.<em>;

import java.awt.event.</em>;

import javax.swing.*;

public class TesteCombo extends JFrame {

private JComboBox CMBteste;

public TesteCombo() {
    try {
        mostra();
    } catch(Exception ex) {
        ex.printStackTrace();
    }
}

private void mostra() throws Exception {

    this.getContentPane().setLayout(null);
    this.getContentPane().setBackground(new Color(204, 204, 204));
    this.setSize(336, 230);
    this.setLocation(343, 207);
    this.setTitle("Teste Combo");
    this.setResizable(false);

    CMBteste = new JComboBox();
    CMBteste.setBounds(new Rectangle(70, 35, 150, 20));
    CMBteste.setEditable(true);
    this.getContentPane().add(CMBteste, null);
    CMBteste.addActionListener (new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          MostraConteudoCombo();
        }
    });

    this.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
            aoFechar();
        }
    });
}

private void MostraConteudoCombo() {
    System.out.println(CMBteste.getSelectedItem());
}

private void aoFechar() {
    System.exit(0);
}

public static void main(String args[]) {
    new TesteCombo().show();
}

}

12 Respostas

brlima

Estranho mesmo… Eu testei aqui, e vi que ele passa so a primeira vez no ItemListener. Parece que qdo vc altera o conteudo ( edita ), e pressiona enter, ele dispara o ItemListener tb. Acho q isso provoca o ActionListener de ser disparado duas vezes. :roll:

Mas to procurando entender isso tb, pq pode me dar problema aqui… :roll: :shock:

Flw!

brlima

Aí imagina o resto: o Action do combo dispara o ItemEvent, que é a seleção na Popup. Logo, na primeira vez q vc digita e aperta ENTER ele seleciona no popup E dispara o do textfield. Depois so o do Textfield.

Q coisa !!! :roll: :shock:

brlima

Tenta separar : adiciona action pro editor e outro ItemListener pro jcombo. Deve funcionar…

Flw!

F

Como assim, agora não entendi mais nada…

:frowning: :frowning: :frowning: :frowning:

bLaCkWiZaRd

Pelo que eu entendi qnd você tem um combo e digita a sua escolha… O fato de você

digitar o combo ja lança um event e ai qnd você tecla o enter ele lança outro evento. Ou

seja, eventos duplicados… E qnd já está selecionado e você tecla enter ele lança

apenas 1 evento…

Espero ter ajudado, corrigam-me se estiver errado

_fs

O que ele falou é que, ao apertar o enter pela primeira vez, o item recebe dois eventos:

  1. Combo box ganhando foco
  2. Enter pressionado no item

Então o seu action listener recebe duas ações, portanto executa o método duas vezes.

Já nas outras vezes que você aperta enter o combobox já está selecionado, portanto apenas o evento Enter Pressionado Item é disparado.

O que ele sugeriu como solução é colocar o listener do evento nos itens, e não no combobox.

Falei merda?

brlima

Pelo que entendi, o Editor é separado do JComboBox em si…
Dai, quando pressionado o Enter dentro do editor, ele dispara um ActionEvent no proprio editor. Ateh aki blz…

Só que, um ActionEvent disparado dentro do editor, força uma selecao no JComboBox, que por sua vez, dispara que houve um item selecionado (ItemEvent). O itemEvent é a acao default do JComboBox, entao o ActionEvent do combo é disparado.

Quando se esta dentro do ActionEvent do combo, ele escuta o do Editor e depois do JComboBox (ItemEvent).

Mas o ItemEvent so eh disparado a primeira vez que vc edita o conteudo, pois ele seleciona o item que vc digitou, e ja q nao houve alteracao na segunda vez, ele nem seleciona, e nem dispara nada, disparando so o ActionEvent do editor.

Evento - Editor - ComboBox
Enter 1 - ActionEvent - ActionEvent(ItemEvent) - Selecionado na lista
Enter 2 - ActionEvent - None

Depois de alterado:

Evento - Editor - ComboBox
Enter 3 - ActionEvent - ActionEvent(ItemEvent) - Selecionando na lista
Enter 4 - ActionEvent - None
F

Desculpem se eu estou viajando, mas ainda não entendi o que eu tenho que mudar no meu código para que execute apenas uma vez sempre, peço paciência de vcs pois é dúvida de principiante. Valeu, abraços.

brlima

Adiciona um listener no Editor ( ACtionListener ) e outro no ItemEvent do JCombobox.

Com isso vc conseue separar os dois eventos que ocorrem juntos no ActionPerformed da JCbombox.

combo.getEditor().addActionListener();
combo.addItemListener();

got it!?

F

Aí Bruno tê te enchendo o saco né veio !!! última duvida: então adicionando estes eu tiro o ActionPerformed ?? ou viajei de novo ?? poderia me mostrar no meu exemplo ?? abaixo está o meu exemplo original, se não for pedir demais, como ficaria ??

CMBteste = new JComboBox();

CMBteste.setBounds(new Rectangle(70, 35, 150, 20));

CMBteste.setEditable(true);

this.getContentPane().add(CMBteste, null);

CMBteste.addActionListener (new ActionListener() {

public void actionPerformed(ActionEvent e) {

MostraConteudoCombo();

}

});
brlima

Nao mudaria qse nada…

CMBteste = new JComboBox();
		CMBteste.setBounds(new Rectangle(70, 35, 150, 20));
		CMBteste.setEditable(true);
		this.getContentPane().add(CMBteste, null);
		
		CMBteste.getEditor().addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.out.println("teste");
			}
		});
		
		CMBteste.addItemListener(new ItemListener(){
			public void itemStateChanged(ItemEvent e){
				System.out.println("Item event");
			}
		});

Agora seria bom vc controlar quem chama o que e qdo… A partir dai depende do que vc quer fazer… :smiley:

Flw!

F

Aí Bruno, agora sim funcionou, valeu mesmo, era isso que eu precisava, estou chamando o métod que eu quero apenas no editor, pois quando o usuário selecionar não quero que faça nada mesmo.
Obrigado.

:smiley: :smiley: :smiley:

[]s,

Fabrício.

Criado 19 de maio de 2004
Ultima resposta 20 de mai. de 2004
Respostas 12
Participantes 4