JTable: Listener que detecta a alteração, via teclado, de qual linha está selecionada

7 respostas
M

Olá pessoal!
Um colega me perguntou se existe algum evento disparado no momento em que, em uma JTable, troca-se a linha selecionada utilizando as setas do teclado. Já tentamos utilizar o KeyListener mas não foi satisfatório, uma vez que o evento é capturado antes de sabermos qual a nova linha selecionada.
Alguém tem alguma sugestão?
Valeu!

7 Respostas

F

Crie uma classe que estenda JTable, e sobrescreva o método “valueChanged”, para fazer o que você precisa quando muda de linha.

Só não esqueça de chamar o “método original”: super.valueChanged(e).

M

Desculpe, mas acho que não fui claro.
A minha intenção é realizar uma determinada ação em resposta a simples troca de linha selecionada, e não em resposta a alteração de algum dado da tabela.
O exemplo é o seguinte: Temos uma JTable com vários registros e alguns JTextField. A idéia é que os JTextField apresentem dados referentes ao registro selecionado na JTable. Se o foco está na JTable, e o usuário aperta, por exemplo, a seta para baixo, gostariamos de responder a esse evento de tal forma que os JTextFields mostrassem agora os dados referentes ao registro que acabou de ser selecionado.
Alguma sugestão de como fazer isso?

M

Bom, a única solução que consegui imaginar é utilizando KeyListener mesmo… Não sei se esa solução é um workaround ou se não há mesmo outra forma de fazer. Aí vai:

new KeyAdapter() {
	public void keyPressed(KeyEvent e) {
		TableModel tm = jTable1.getModel();
		int r, c;
		switch(e.getKeyCode()) {
			case KeyEvent.VK_DOWN:
				r = Math.min(
					jTable1.getSelectedRow() + 1,
					tm.getRowCount() - 1
				);
				if(r == jTable1.getSelectedRow())
					return;
				for(c = 0; c < tm.getColumnCount(); c++) {
					System.out.println(
						tm.getColumnName(c) + ": " + 
						tm.getValueAt(r, c)
					);
				}
				break;
			case KeyEvent.VK_UP:
				r = Math.max(
					jTable1.getSelectedRow() - 1,
					0
				);
				if(r == jTable1.getSelectedRow())
					return;
				for(c = 0; c < tm.getColumnCount(); c++) {
					System.out.println(
						tm.getColumnName(c) + ": " + 
						tm.getValueAt(r, c)
					);
				}
		}
	}
}

Aparentemente isso funcionou bem… Mas ainda gostaria que a galere dessem sugestões caso conheçam alguma forma mais trivial de lhe dar com essa problemática.
Valeu pessoal!

S

Olá,

Não sei se entendi direito os requisitos, mas será que o ListSelectionListener no selectionmodel não serve?

table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                ...
            }
        });

[]s,
Sami

F

Mantu…acho que você não olhou direito esse método. Ele é a implementação da interface ListSelectionListener, e serve exatamente para o que você quer.

Diretamente do Javadoc:
“Invoked when the row selection changes – repaints to show the new selection.”

Ou seja: nada a ver com mudança nos dados das células.

Mas provavelmente a solução do Sami também vai funcionar.

S

Ah, sim, vi agora. A sugestão do fenrir e a minha são práticamente a mesma coisa. O efeito pelo menos é o mesmo.

A classe JTable implementa ListSelectionListener e registra ele mesmo para saber das mudanças de seleção. Então sobre-escrevendo esse método terá o mesmo efeito que registrando um novo listener.

Acho que eles poderiam ter dado um nome melhor para o método. Causa confusão. Algo tipo selectionChanged seria melhor.

[]s,
Sami

F

O nome traz confusao mesmo… selectionChanged seria muito mais claro…

de quqer jeito, obrigado a sami e fenrir… era esse listener mesmo q eu estava precisando e desconhecia…

Criado 26 de fevereiro de 2007
Ultima resposta 27 de fev. de 2007
Respostas 7
Participantes 4