Por que seleções JList ocorrem duas vezes?
Pergunta
Eu tenho uma JList com alguns itens. Eu adicionei um ouvinte para quando um item na lista é selecionado. Aqui está o código para o que acontece quando um item na lista é selecionado:
private void questionaireNamesListValueChanged(ListSelectionEvent evt) {
try {
inputPanel.setEnabled(false);
inputPanel.setVisible(false);
inputTextField.setText("");
inputStatusLabel.setText("");
int questionaireIndex = questionaireNamesList.getSelectedIndex();
// Why will this be printed twice?
System.out.println("Questionaire Index: " + questionaireIndex);
if (remoteQuestionServer.getQuestionCount(questionaireIndex) == 5) {
answerQuestionButton.setEnabled(true);
addQuestionButton.setEnabled(false);
} else {
addQuestionButton.setEnabled(true);
answerQuestionButton.setEnabled(false);
}
} catch (RemoteException ex) {
ex.printStackTrace();
}
}
Como você pode acima Coloquei uma declaração System.out.print
e cada vez que eu clicar em algo na lista Recebo dois ouputs para esse item, por exemplo.
Questionaire Index: 4
Questionaire Index: 4
Questionaire Index: 2
Questionaire Index: 2
Questionaire Index: 0
Questionaire Index: 0
Questionaire Index: 2
Questionaire Index: 2
Qualquer idéia de por que isso está acontecendo?
Obrigado, Patrick
Solução
Quando você alterar uma seleção, um ou dois eventos podem ocorrer, dependendo da implementação. Se o índice # 4 é selecionado e você clicar no segundo item, em seguida, ocorre o seguinte:
- Em primeiro lugar, o índice # 4 é desmarcada. Dependendo do modelo,
questionaireNamesList.getSelectedIndex()
pode legalmente voltar 2 ou -1. - segunda, índice # 2 está selecionado. Neste ponto,
questionaireNamesList.getSelectedIndex()
certamente irá retornar 2.
Assim, existem dois eventos disparados. A definição de como esses eventos são gerados permite margem de manobra para diferentes implementações de JVM fazer as coisas vão um pouco diferente.
NOTA: Você provavelmente deve verificar o valor de ListSelectionEvent#getValueIsAdjusting()
para ver se o evento que você está processando é um em uma série de eventos. Você provavelmente precisará ignorar todos os eventos onde esta retornos true
.
Outras dicas
Na sequência da resposta pelo olhar Eddie pelo método getValueIsAdjusting sobre o evento.