Olá pessoal...
Implementei meu própio TableModel seguindo os exemplos do fórum...
Estou com um probleminha, com relação a GUI ou ao TableModel, não sei. :roll:
Vou descrever um cenário do que está acontecendo comigo aqui:
Estou desenvolvendo um sistema básico, pequeno, o mesmo deve gerar determinados relatórios por 'Bairros', construi um Form para o cadastro desses bairros (para padronizá-los), cadastra, atualiza e deleta normalmente, porém está ocorrendo uma pequena peculiaridade:
1 - Quando cadastro um novo registro o mesmo é inserido com sucesso na base de dados e a minha JTable é atualizada corretamente com o novo registro inserido;
2 - Quando atualizo um registro o mesmo é atualizado com sucesso na base de dados e também no meu TableModel, com a minha JTable sendo redesenhada corretamente;
3 - Quando seleciono um registro na JTable e clico no botão 'Excluir' a deleção é feita com sucesso tanto no DB quando no TableModel e a JTable é renderizada normalmente;
O problema está acontecendo quando executo o passo 2 antes do passo 1, por exemplo, inicializo a janela de cadastro, clico em um registro na tabela, dai eu atualizo (Passo 2), ok... atualiza normalmente no DB e JTable, PORÉM, se eu resolver INCLUIR (Passo 1) um novo registro, ele insere normalmente no DB, insere uma última linha na JTable com os dados do novo registro MAS também AUTUALIZA (apenas na JTable, no DB continua normal) aquele registro anterior que eu havia atualizado.
Eu não sei porque mistérios ele faz isso...
Alguém tem idéia do que pode ser?
Posto aqui também o código do meu TableModel para vocês verificarem se há algo errado
package br.view;
import br.model.vo.BairroVO;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.swing.table.AbstractTableModel;
/**
*
* @author Leandro
*/
public class BairrosTableModel extends AbstractTableModel {
private List<BairroVO> linhas;
private String colunas[] = new String[] {"Código", "Nome", "Descrição"};
public BairrosTableModel() {
this.linhas = new ArrayList<>();
}
public BairrosTableModel(List<BairroVO> lista) {
this.linhas = new ArrayList<>(lista);
}
@Override
public int getRowCount() {
return linhas.size();
}
@Override
public int getColumnCount() {
return colunas.length;
}
@Override
public String getColumnName(int columnIndex) {
return colunas[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch(columnIndex) {
case 0: //ID
return Integer.class;
case 1: //Nome
return String.class;
case 2: //Descrição
return String.class;
default:
throw new IndexOutOfBoundsException("Índice informado fora dos limites.");
}
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
BairroVO vo = linhas.get(rowIndex);
switch(columnIndex) {
case 0: //ID
return vo.getID();
case 1: //Nome
return vo.getNome();
case 2: //Descrição
return vo.getDescricao();
default:
throw new IndexOutOfBoundsException("Índice informado fora dos limites.");
}
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
// BairroVO vo = linhas.get(rowIndex);
// switch(columnIndex) {
// case 0: //ID
// vo.setID(Integer.parseInt(aValue.toString()));
// case 1: //Nome
// vo.setNome(aValue.toString());
// case 2: //Descrição
// vo.setDescricao(aValue.toString());
// }
// fireTableCellUpdated(rowIndex, columnIndex);
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
/*
* Implementações particulares:
*/
public BairroVO getBairro(int rowIndex) {
return linhas.get(rowIndex);
}
public void addBairro(BairroVO vo) {
linhas.add(vo);
int lastIndex = getRowCount()-1;
fireTableRowsInserted(lastIndex, lastIndex);
}
public void removeBairro(int rowIndex) {
linhas.remove(rowIndex);
fireTableRowsDeleted(rowIndex, rowIndex);
}
public void addListaBairros(List<BairroVO> lista) {
int tamanhoAntigo = getRowCount();
linhas.addAll(lista);
fireTableRowsInserted(tamanhoAntigo, getRowCount()-1);
}
public void limpar() {
if(!linhas.isEmpty()) {
linhas.clear();
fireTableDataChanged();
}
}
public boolean isEmpty() {
return linhas.isEmpty();
}
public void ordenarPorID() {
Collections.sort(linhas, new Comparator<BairroVO>(){
@Override
public int compare(BairroVO o1, BairroVO o2) {
return o1.getID()-o2.getID();
}
});
fireTableDataChanged();
}
public void ordenarPorNome() {
Collections.sort(linhas, new Comparator<BairroVO>() {
@Override
public int compare(BairroVO o1, BairroVO o2) {
return o1.getNome().compareTo(o2.getNome());
}
});
fireTableDataChanged();
}
public void ordenarPorDescricao() {
Collections.sort(linhas, new Comparator<BairroVO>() {
@Override
public int compare(BairroVO o1, BairroVO o2) {
return o1.getDescricao().compareTo(o2.getDescricao());
}
});
fireTableDataChanged();
}
}
package br.presenter;
import br.model.dao.BairroDAO;
import br.model.vo.BairroVO;
import br.presenter.listeners.CadBairrosMouseListeners;
import br.presenter.listeners.CadBairrosWindowListeners;
import br.view.BairrosTableModel;
import br.view.CadastroBairrosView;
import java.awt.Component;
import java.util.List;
import javax.swing.JOptionPane;
/**
*
* @author Leandro
*/
public class CadastroBairrosPresenter {
private BairroVO vo;
private BairroDAO dao;
private CadastroBairrosView view;
private BairrosTableModel tableModel;
public CadastroBairrosPresenter(BairroDAO dao, CadastroBairrosView view) {
this.vo = new BairroVO();
this.dao = dao; //Recebe por uma Factory de DAOS
this.view = view;
//Popula o modelo de tabela na sua inicialização:
this.tableModel = new BairrosTableModel(this.dao.listarTodos());
/*
* Seta o TableModel da JTable, sem isso teremos uma'java.lang.ClassCastException',
* pois o modelo pradrão do JTable que é 'DefaultTableModel' não implementa
* a interface 'TableModel', porém o modelo 'BairrosTableModel'
* (extends AbstractTableModel) implementa 'TableModel', permitindo
* assim o casting no momento em que formos recuperar o modelo da View.
*/
view.setBairrosTableModel(tableModel);
}
public void criarJanela() {
this.setUpViewListeners();
this.ativarEdicao(true);
this.view.ativarBtnAtualizar(false);
this.view.ativatBtnExcluir(false);
this.view.packAndShow();
}
public void ocultarJanela() {
fechar();
}
public CadastroBairrosView getView() {
return this.view;
}
//Atualiza o modelo a partir da visão:
public void updateModelFromView() {
this.vo.setNome(view.getNome());
this.vo.setDescricao(view.getDescricao());
}
//Atualiza o modelo a partir da tabela na visão:
public void updateModelFromTable() {
this.tableModel = view.getBairrosTableModel();
this.vo = tableModel.getBairro(view.getLinhaSelecionadaTabela());
//Renderiza a view:
view.ativarNomeTextField(true);
view.ativarDescricaoTextArea(true);
view.ativarBtnLimpar(true);
view.ativatBtnExcluir(true);
view.ativarBtnCancelar(true);
view.ativarBtnSalvar(false);
view.ativarBtnAtualizar(true);
}
//Atualiza a visão a partir do modelo:
public void updateViewFromModel() {
if(vo != null) {
this.view.setNome(vo.getNome());
this.view.setDescricao(vo.getDescricao());
}
else {
view.limparCampos();
}
}
public void ativarEdicao(boolean b) {
view.ativarNomeTextField(b);
view.ativarDescricaoTextArea(b);
view.ativarBtnSalvar(b);
view.ativarBtnAtualizar(b);
view.ativarBtnLimpar(b);
view.ativatBtnExcluir(b);
view.ativarBtnCancelar(b);
}
public void limparCamposView() {
this.view.limparCampos();
this.view.limparSelecaoTabela();
this.view.ativatBtnExcluir(false);
this.view.ativarBtnAtualizar(false);
this.view.ativarBtnSalvar(true);
}
public void repopularTabela() {
List<BairroVO> lista = dao.listarTodos();
view.setBairrosTableModel(new BairrosTableModel(lista));
view.atualizarTabelaBairros();
}
//Atualiza na JTable valores inseridos ou deletados:
public void updateTableModel(int op) {
//Inserir
if(op == 0) {
vo.setID(dao.listarUltimoID());
view.getBairrosTableModel().addBairro((BairroVO)vo.clone());
}
//Deletar
else if(op == 1) {
view.getBairrosTableModel().removeBairro(view.getLinhaSelecionadaTabela());
}
}
//Chama 'updateTableModel' para renderizar a JTable:
public void inserirBairro() {
this.updateModelFromView();
this.dao.inserir(vo);
//Atualiza na JTable:
this.updateTableModel(0);
view.atualizarTabelaBairros();
}
//Não coloquei nada para atualizar no TableModel (pelo menos penso isso), mas mesmo assim atualiza sozinho (não sei porque):
public void atualizarBairro() {
this.updateModelFromView();
this.dao.atualizar(vo);
//Renderiza a view:
view.atualizarTabelaBairros();
limparCamposView();
}
//Chama 'updateTableModel' para renderizar a JTable:
public void deletarBairro() {
//Se não selecionou nenhum registro:
if(view.getLinhaSelecionadaTabela() == -1) {
JOptionPane.showMessageDialog((Component)getView(), "Selecione um registro para excluir!",
"Excluir registro", JOptionPane.WARNING_MESSAGE);
}
else {
this.updateModelFromTable();
deletar();
//Atualiza na JTable:
this.updateTableModel(1);
view.atualizarTabelaBairros();
}
}
/**
* Método para encerrar a aplicação.
* Pergunta ao usuário se realmente deseja sair,
* caso contrário a execução do aplicativo continua.
*/
private void fechar () {
// TODO add your handling code here:
//Modifica o texto dos botões.
Object [] options = {"Sim",
"Não"};
//Variável ´n´ recebe o valor da opção clicada.
int n = JOptionPane.showOptionDialog ((Component)getView(),
"Deseja realmente sair da aplicação?",
"Encerrar aplicação",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options [1]);
//Se Clicou para sair.
if (n==0) {
/*
* Torna a janela invisível em seguida
* termina a execução do objeto.
*/
view.ocultar();
view.destruir();
}
}
private void deletar() {
// TODO add your handling code here:
//Modifica o texto dos botões.
Object [] options = {"Sim",
"Não"};
//Variável ´n´ recebe o valor da opção clicada.
int n = JOptionPane.showOptionDialog ((Component)getView(),
"Deseja realmente excluir o registro?",
"Exclusão de registro",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options [1]);
//Se Clicou para sair.
if (n==0) {
/*
* Torna a janela invisível em seguida
* termina a execução do objeto.
*/
this.dao.deletar(vo);
}
}
public void setUpViewListeners() {
view.setSalvarActionListener(new CadBairrosWindowListeners.SalvarActionListener(this));
view.setAtualizarActionListener(new CadBairrosWindowListeners.AtualizarActionListener(this));
view.setLimparActionListener(new CadBairrosWindowListeners.LimparActionListener(this));
view.setExcluirActionListener(new CadBairrosWindowListeners.ExcluirActionListener(this));
view.setCancelarActionListener(new CadBairrosWindowListeners.CancelarActionListener(this));
view.setFormularioWindowAdpter(new CadBairrosWindowListeners.FormularioWindowAdapter(this));
view.setFieldNomeFocusListener(new CadBairrosWindowListeners.FieldNomeFocusListener(this));
view.setFieldDescricaoFocusListener(new CadBairrosWindowListeners.FieldDescricaoFocusListener(this));
view.setTableBairrosMouseListener(new CadBairrosMouseListeners.TabelaBairrosMouseListener(this));
}
}
Aguardo uma ajuda pra resolver este mistério.. haha
Muito obrigado pessoal... :D
