Boa noite a todos.
Em primeiro lugar, o ideal para você criar o seu próprio TableModel, e criar um classe que herde (extenda) de AbstractTableModel.
Eu fiz uma classe dessa para o meu uso pessoal, só que ela é um TableModel genérico que serve para todas as tabelas do banco de dados, procurei assim não engessar muito esta classe, pois a finalidade principal do AbstractTableModel e você dinamizá-a ao máximo para o seu próprio uso.
Nesta classe, eu passo com parâmetro no seu construtor, um objeto ResultSet populado com os dados que vem do banco, pois quando você executa uma instrução “Select…” no SQL, ele popula justamente um ResultSet, onde e o passo diretamente para a classe.
Vamos a classe:
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.table.AbstractTableModel;
public class ResultSetGridModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private List<Map><String,Object>> dataset = null;
private Map<String, Object> fields = null;
private int columncount = 0;
private String[] columns = null;
public ResultSetGridModel(ResultSet rs){
try {
columns = new String[rs.getMetaData().getColumnCount()];
columncount = rs.getMetaData().getColumnCount();
dataset = new ArrayList<>();
for (int i = 0; i < this.columncount; i++){
columns[i] = new String();
columns[i] = rs.getMetaData().getColumnName(i+1).toLowerCase();
}
while (rs.next()){
fields = new HashMap<>();
for (int i = 1; i < columncount; i++){
fields.put(rs.getMetaData().getColumnName(i).toLowerCase(), rs.getObject(i));
}
this.dataset.add(fields);
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
@Override
public int getRowCount() {
return dataset.size();
}
@Override
public int getColumnCount() {
return columncount;
}
@Override
public String getColumnName(int column){
return columns[column];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Map<String,Object> row = dataset.get(rowIndex);
return row.get(columns[columnIndex]);
}
public List<Map><String,Object>> getDataSet(){
return dataset;
}
public Map<String,Object> getRow(int row) {
return dataset.get(row);
}
public void insertRow(Map<String,Object> rowvalue){
dataset.add(rowvalue);
fireTableDataChanged();
}
public void removeRow(int row) {
dataset.remove(row);
fireTableDataChanged();
}
}
Repare que dentro da classe, eu pego os dados do ResultSet e os passo para um objeto HashMap, onde o primeiro índice será o nome do campo, e o segundo o seu valor.
Agora instancie o seu JTable desta forma, e crie também um método getModel() para que você não ficar fazendo casting do seu Model a toda hora que precisar dele, assim:
.....
JTable meuJTable = new JTable(new ResutSetGridModel(getDao().getResultSet()));
.....
// Criando o método getModel()
public ResultSetGridModel getModel() {
return (ResultSetGridModel) meuJTable.getModel();
}
Quando você quiser pegar todos os dados de uma linha do seu JTable, instancie um objeto HashMap e o pegue no evento do click do mouse assim:
meuJTable.addMouseListener(new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent e) {
Integer row = meuJTable.getSelectedRow();
Map field = getModel().getRow(row);
txtNomeClient.setText(field.get("Nome_Cliente");
txtCPF.setText(field.get("CPF");
......
......
// E por ai vai....
}
});
Repare que os txtNome… e txtCPF, podem ser JTextFields que você por ventura tenha declarado e instanciado na classe, e com o método getModel() eu não preciso ficar fazendo casting do model do JTable a toda hora, senão eu teria que fazer assim:
......
Integer row = meuJTable.getSelectedRow();
Map field = (ResultSetGridModel) meuJTable.getModel().getRow(row);
.....
Observe que para que você possa utilizar a classe AbstractTableModel, conforme foi configurada, necessário é você criar um método getResultSet() dentro do seu DAO, e passá-la diretamente para dentro da classe no momento de instanciar o seu JTable ou você pode instanciar o seu JTable e depois setar o seu model assim:
JTable meuJTable = new JTable();
meuJTable.setModel(new ResultSetGridModel(getDao().getResultSet());
Ai vai do gosto de cada um.
Isto lhe dá também a opção de quando fizer um filtro dentro da tabela com uma instrução “Select…” do SQL, você pode reiniciar o seu JTable com a instrução abaixo:
meuJTable.setModel(new ResultSetGridModel(getDao().getResultSet());
Não se esqueça de remodelar o seu JTable da seguinte forma:
meuJTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// Ocultando a primeira coluna (ID) do JTable
meuJTable.getColumnModel().getColumn(0).setMinWidth(0);
meuJTable.getColumnModel().getColumn(0).setMaxWidth(0);
// Redimensionando as demais colunas
meuJTable.getColumnModel().getColumn(1).setPreferredWidth(350);
meuJTable.getColumnModel().getColumn(1).setHeaderValue("Nome");
meuJTable.getColumnModel().getColumn(2).setPreferredWidth(100);
meuJTable.getColumnModel().getColumn(2).setHeaderValue("CPF");
.....
.....
Espero ter ajudado.