Listener JTable?

Estou fazendo um projeto com uso de JTable, onde fiz um TableModel com a ajuda de um tutorial, Porém, quando edito a JTable com o código rodando, ele chama um método da classe TableModel que parece com um Listener, mas não entendo o porquê disso.

Gostaria de aplicar um Listener desse tipo na classe da JTable para que pudesse adicionar objetos em um array cada vez que a JTable fosse editada. Porém usando a listener na classe do TableModel, toda edição sobrescreve a arrayList que eu armazeno os dados.

Podem me ajudar a resolver essa questão?

Segue o código da TableModel, no qual está com esse “Listener” setValueAt:

public class EstoqueTableModel extends AbstractTableModel implements ConverteParaString, TableModelListener {

/**
 * 
 */
private static final long serialVersionUID = 1403943570357475859L;
private List<Estoque> estoquesDTO;
private List<Estoque> listaDeEstoques;
private String[] colunas = new String[] { "Cód Estoque", "Descrição Estoque" };

public EstoqueTableModel(List<Estoque> estoquesDTO) {
	this.estoquesDTO = estoquesDTO;
}

public EstoqueTableModel() {
	this.estoquesDTO = new ArrayList<Estoque>();
}

@Override
public int getColumnCount() {
	return colunas.length;
}

@Override
public int getRowCount() {
	return estoquesDTO.size();
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
	Estoque estoqueSelecionado = estoquesDTO.get(rowIndex);
	String valueObject = null;

	switch (columnIndex) {
	case 0:
		valueObject = convertLongToString(estoqueSelecionado.getIdEstoque());
		break;
	case 1:
		valueObject = estoqueSelecionado.getDescricaoEstoque();
		break;

	default:
		System.err.println("Índice inválido para propriedade de Estoque.cl");
		break;
	}
	return valueObject;
}

@Override
public String getColumnName(int columnIndex) {
	return colunas[columnIndex];
}

@Override
public Class<?> getColumnClass(int columnIndex) {
	return String.class;
}

public void setValueAt(Estoque aValue, int rowIndex) {
	Estoque estoqueDTO = estoquesDTO.get(rowIndex);
	estoqueDTO.setIdEstoque(aValue.getIdEstoque());
	estoqueDTO.setDescricaoEstoque(aValue.getDescricaoEstoque());

	fireTableCellUpdated(rowIndex, 0);
	fireTableCellUpdated(rowIndex, 1);

}

@Override
public void setValueAt(Object novoValorAtualizado, int linhaSelecionada, int colunaSelecionada) {
	Estoque estoqueDTO = estoquesDTO.get(linhaSelecionada);
	EstoqueController estoqueController = new EstoqueController();
	listaDeEstoques = new ArrayList<Estoque>();

	//JOptionPane.showMessageDialog(null, "rowIndex: " + linhaSelecionada);
	//JOptionPane.showMessageDialog(null, "Object aValue: " + novoValorAtualizado);
	//JOptionPane.showMessageDialog(null, "estoquesDTO.get: " + estoquesDTO.get(linhaSelecionada).toString());
	
	switch (colunaSelecionada) {
	case 0:
		estoqueDTO.setIdEstoque(convertStringToLong(novoValorAtualizado.toString()));

	case 1:
		estoqueController.validaDescricaoEstoque(novoValorAtualizado.toString());
		estoqueDTO.setDescricaoEstoque(novoValorAtualizado.toString());
		TelaListarEstoques tl = new TelaListarEstoques();
		tl.addEstoqueLista(estoqueDTO);
		//listaDeEstoques.add(estoqueDTO);
		//estoqueController.atualizar(estoqueDTO);
		//JOptionPane.showMessageDialog(null, tl.getEstoquesDTO().size());
	}
	fireTableCellUpdated(linhaSelecionada, colunaSelecionada);
}

@Override
public boolean isCellEditable(int linhaSelecionada, int colunaSelecionada) {
	if (colunaSelecionada > 0) {
		return true;
	} else {
		return false;
	}
}

public Estoque getEstoque(int indiceLinha) {
	return estoquesDTO.get(indiceLinha);
}

public void addEstoque(Estoque e) {
	estoquesDTO.add(e);

	int ultimoIndice = getRowCount() - 1;

	fireTableRowsInserted(ultimoIndice, ultimoIndice);
}

public void removeEstoque(int indiceLinha) {
	estoquesDTO.remove(indiceLinha);

	fireTableRowsDeleted(indiceLinha, indiceLinha);
}

public void addListaDeEstoques(List<Estoque> novosEstoques) {
	int tamanhoAntigo = getRowCount();
	estoquesDTO.addAll(novosEstoques);
	fireTableRowsInserted(tamanhoAntigo, getRowCount() - 1);
}

public void limpar() {
	estoquesDTO.clear();
	fireTableDataChanged();
}

public boolean isEmpty() {
	return estoquesDTO.isEmpty();
}

Agradeço se me explicarem também o porquê de estar chamando esse método.

@Override
public void setValueAt(Object novoValorAtualizado, int linhaSelecionada, int colunaSelecionada) {
	Estoque estoqueDTO = estoquesDTO.get(linhaSelecionada);
	EstoqueController estoqueController = new EstoqueController();
	listaDeEstoques = new ArrayList<Estoque>(); // é porque aqui você sempre está criando uma nova lista
1 curtida

Obrigado pela atenção staroski!

Vou alterar agora e posto o resultado!
Esse método funciona como listener mesmo?
É correto eu montar a lista nessa classe?

staroski
1h

fabiio2:
toda edição sobrescreve a arrayList que eu armazeno os dados.
@Override
public void setValueAt(Object novoValorAtualizado, int linhaSelecionada, int colunaSelecionada) {
Estoque estoqueDTO = estoquesDTO.get(linhaSelecionada);
EstoqueController estoqueController = new EstoqueController();
listaDeEstoques = new ArrayList(); // é porque aqui você sempre está criando

Staroski,

o código ficou assim agora e funcionou:

public void setValueAt(Object novoValorAtualizado, int linhaSelecionada, int colunaSelecionada) {
	Estoque estoqueDTO = estoquesDTO.get(linhaSelecionada);
	EstoqueController estoqueController = new EstoqueController();
	//listaDeEstoques = new ArrayList<Estoque>();

	//JOptionPane.showMessageDialog(null, "rowIndex: " + linhaSelecionada);
	//JOptionPane.showMessageDialog(null, "Object aValue: " + novoValorAtualizado);
	//JOptionPane.showMessageDialog(null, "estoquesDTO.get: " + estoquesDTO.get(linhaSelecionada).toString());


	
	switch (colunaSelecionada) {
	case 0:
		estoqueDTO.setIdEstoque(convertStringToLong(novoValorAtualizado.toString()));

	case 1:
		estoqueController.validaDescricaoEstoque(novoValorAtualizado.toString());
		estoqueDTO.setDescricaoEstoque(novoValorAtualizado.toString());
		//TelaListarEstoques tl = new TelaListarEstoques();
		//tl.addEstoqueLista(estoqueDTO);
		listaDeEstoques.add(estoqueDTO);
		//estoqueController.atualizar(estoqueDTO);
		JOptionPane.showMessageDialog(null, listaDeEstoques.size());
	}
	fireTableCellUpdated(linhaSelecionada, colunaSelecionada);
}

Acha que é correto montar a lista na classe TableModel?
Esse método setValueAt funciona sempre como Listener mesmo?
Consigo aplicar esse listener na classe principal da tabela, uma vez que ela já herda de JFrame?

Sim, a JTable invoca este método quando você altera o conteúdo do editor de uma célula.
Veja a documentação.

1 curtida

Obrigado pela atenção @staroski