Você precisa criar um TableCellEditor com o botão. Associa-lo a sua tabela vinculado a um tipo de dado (como JButton.class) e, em seguida, alterar no seu model as colunas de botão para retornarem JButton.class no getValueAt;
Faça seu model retornar false no método setEditable apenas para as colunas que não são botões.
Se você não sabe direito o que é esse model que estou falando (e não é o DefaultTableModel), dê uma lida nos links da minha assinatura, em especial, ao lado do texto em vermelho. Se quer fazer tabelas mais poderosas, é essencial que você saiba mexer corretamente num TableModel.
ElesisLink
Olá, ViniGodoy,
1° Foi mal pelo post em local errado, tinha certeza de que era no Java básico… :oops:
2° Não tenho a menor idéia de como usar AbstractTableModel, e eu vi os artigos aqui do fórum e não entendi!!! Vou dar
uma olhada, e peço que me ajude com o que precisar!!!
ViniGodoy
Tente e poste as dúvidas.
Porque o DefaultTableModel é beeem mais difícil que o Abstract. Não se deixe assustar pelo tamanho dos códigos. Aquele é todo código necessário para fazer uma tabela editável. E ele fica concentrado em um lugar só.
No Default, você acaba com muito mais código do que aquilo, espalhado pela sua classe de interface gráfica. Sem falar em vários casts inseguros, na necessidade de duplicar dados e de muitas vezes expor colunas desnecessárias ao usuário (como as de ID).
ElesisLink
Tem algum exemplo de AbstractTan]bleModel com banco de dados ?
Eu num entendi muito bem a parte de inserir os dados na tabela…
ViniGodoy
O TableModel trabalha com um ArrayList de dados da sua classe de negócio.
Quem faz a carga e salva esse ArrayList no banco são as classes DAO (Data Access Objects).
Você não tem classes de negócio para suas entidades?
ElesisLink
Se vc ta falando de uma classe desse tipo:
publicclassUsuario{privateStringnome;privateStringlogin;privateStringsenha;privateStringconfirm;privateintperfil;privateintsituacao;// nome/** * @return the nome */publicStringgetNome(){returnnome;}/** * @param nome the nome to set */publicvoidsetNome(Stringnome){this.nome=nome;}// login/** * @return the login */publicStringgetLogin(){returnlogin;}/** * @param login the login to set */publicvoidsetLogin(Stringlogin){this.login=login;}// senha/** * @return the senha */publicStringgetSenha(){returnsenha;}/** * @param senha the senha to set */publicvoidsetSenha(Stringsenha){this.senha=senha;}// confirm/** * @return the confirm */publicStringgetConfirm(){returnconfirm;}/** * @param confirm the confirm to set */publicvoidsetConfirm(Stringconfirm){this.confirm=confirm;}// perfil/** * @return the perfil */publicintgetPerfil(){returnperfil;}/** * @param perfil the perfil to set */publicvoidsetPerfil(intperfil){this.perfil=perfil;}/** * @return the situacao */publicintgetSituacao(){returnsituacao;}/** * @param situacao the situacao to set */publicvoidsetSituacao(intsituacao){this.situacao=situacao;}}
Não tinha, mas desenvolvi uma agora…
ViniGodoy
Legal. A classe DAO é aquele que transforma os dados do banco, num List de uma classe desse tipo:
public class UsuarioDao {
public List<Usuario> carregarUsuarios() {
//Aqui vc faz a consulta SQL e carrega a lista
}
}
O TableModel então desenha a lista de usuários.
ElesisLink
Sinto muito ficar perguntando toda hora, mas num entendo como setar estes valores na tabela… como eu insiro esses dados no List e como faço para desenhá-los na tabela… Eu to tentando, mesmo, mas ta complicado…
ViniGodoy
Você sabe usar banco de dados?
De onde estão vindo os valores que atualmente estão na sua tabela?
ElesisLink
Acho melhor postar o código do geito q tava antes:
importjava.awt.Color;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjavax.swing.BorderFactory;importjavax.swing.JComboBox;importjavax.swing.JLabel;importjavax.swing.JPanel;importjavax.swing.JPasswordField;importjavax.swing.JScrollPane;importjavax.swing.JTable;importjavax.swing.JTextField;importjavax.swing.table.DefaultTableModel;@SuppressWarnings({"serial"})publicclassCon_UsuarioextendsJPanel{@SuppressWarnings("unused")privateJLabellblNome,lblLogin,lblSenha,lblConfirm,lblPerfil,lblSituacao,lblPesquisa;@SuppressWarnings("unused")privateJTextFieldtxtNome,txtLogin,txtPesquisa;privateJPasswordFieldpswSenha,pswConfirm;privateJComboBoxcmbPerfil;JTabletabela;DefaultTableModelmodelo;JScrollPanebarra;publicPreparedStatementpstmt;Stringcolunas[]={"Código","Nome","Login","Perfil de Acesso","Situação"};Stringdados[][];JPanelpanelCon;FiltraUsuariofilt;publicCon_Usuario(){setLayout(null);initComponents();}publicvoidinitComponents(){filt=newFiltraUsuario();add(getMyLabel());add(getMyText());add(getMyTabela());}publicJLabelgetMyLabel(){if(lblPesquisa==null){//instancia sua label aqui lblPesquisa=newJLabel("Pesquisa por nome: ");lblPesquisa.setBounds(25,25,140,25);add(lblPesquisa);}returnlblPesquisa;}publicJTextFieldgetMyText(){if(txtPesquisa==null){//instancia seu text aqui txtPesquisa=newJTextField();txtPesquisa.setBounds(160,25,160,25);txtPesquisa.addKeyListener(filt);add(txtPesquisa);}returntxtPesquisa;}publicJScrollPanegetMyTabela(){if(barra==null){//instancia seu text aqui modelo=newDefaultTableModel(dados,colunas){publicbooleanisCellEditable(introwIndex,intmColIndex){returnfalse;}@SuppressWarnings("unused")publicbooleanisColumnSelected(intmColIndex){returnfalse;}};tabela=newJTable(modelo);tabela.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);tabela.getColumnModel().getColumn(0).setPreferredWidth(200);tabela.getColumnModel().getColumn(1).setPreferredWidth(130);tabela.getColumnModel().getColumn(2).setPreferredWidth(120);tabela.getColumnModel().getColumn(3).setPreferredWidth(100);carregarTabela();barra=newJScrollPane(tabela);barra.setBorder(BorderFactory.createLineBorder(Color.black,1));barra.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);barra.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);barra.setBounds(100,100,600,200);add(barra);}returnbarra;}publicvoidcarregarTabela(){modelo.setNumRows(0);Conexao.Conecta();try{// procedimentos para obter os dados de uma tabelaStringSQL="SELECT * FROM usuario";pstmt=Conexao.connection.prepareStatement(SQL);ResultSetrs=pstmt.executeQuery();while(rs.next()){Stringcod=rs.getString("id");Stringnome=rs.getString("nome");Stringlogin=rs.getString("usuario");Stringperf=rs.getString("perfil_acesso");Stringsitu=rs.getString("situacao");modelo.addRow(newObject[]{cod,nome,login,perf,situ});}rs.close();tabela.removeColumn(tabela.getColumn("Código"));}catch(SQLExceptionex){System.out.println("SQLException: "+ex.getMessage());System.out.println("SQLState: "+ex.getSQLState());System.out.println("VendorError: "+ex.getErrorCode());}Conexao.Fecha();}classFiltraUsuarioimplementsKeyListener{@OverridepublicvoidkeyPressed(KeyEventarg0){// TODO Auto-generated method stub}@OverridepublicvoidkeyReleased(KeyEventarg0){// TODO Auto-generated method stubmodelo.setNumRows(0);Stringtext=txtPesquisa.getText();Conexao.Conecta();try{// procedimentos para obter os dados de uma tabelaStringSQL="SELECT * FROM usuario WHERE nome LIKE '"+text+"%'";pstmt=Conexao.connection.prepareStatement(SQL);ResultSetrs=pstmt.executeQuery();while(rs.next()){Stringcod=rs.getString("id");Stringnome=rs.getString("nome");Stringlogin=rs.getString("usuario");Stringperf=rs.getString("perfil_acesso");Stringsitu=rs.getString("situacao");modelo.addRow(newObject[]{cod,nome,login,perf,situ});}rs.close();}catch(SQLExceptionex){System.out.println("SQLException: "+ex.getMessage());System.out.println("SQLState: "+ex.getSQLState());System.out.println("VendorError: "+ex.getErrorCode());}Conexao.Fecha();}@OverridepublicvoidkeyTyped(KeyEventarg0){// TODO Auto-generated method stub}}}
ViniGodoy
Então sua classe UsuarioDao ficaria assim:
public class UsuarioDao {
public List<Usuario> carregarUsuarios(String nome) {
Conexao.Conecta();
try{
// procedimentos para obter os dados de uma tabela
String SQL = "SELECT * FROM usuario WHERE nome LIKE ?"
pstmt = Conexao.connection.prepareStatement(SQL);
pstmt.setString(1, nome + "%");
ResultSet rs = pstmt.executeQuery();
List<Usuario> usuarios = new ArrayList<Usuario>();
while(rs.next()){
Usuario usuario = new Usuario();
usuario.setId(rs.getInt("id"));
usuario.setNome(rs.getString("nome"));
usuario.setLogin(rs.getString("usuario"));
usuario.setPerfil(rs.getInt("perfil_acesso"));
usuario.setSituacao(rs.getInt("situacao"));
usuarios.add(usuario);
}
rs.close();
} catch(SQLException ex){
throw new RuntimeException(ex);
} finally {
Conexao.Fecha();
}
}
E você usaria assim (no botão buscar):
UsuarioTableModel model = new UsuarioTableModel(new UsuarioDao.carregarUsuarios(nome));
suaTabela.setModel(model);
ElesisLink
Ufa, finalmente consegui fazer funcionar o JTable com AbstractTableModel, mas so preciso compreender mais uma coisa:
Como eu seto a célula que desejo ser editável(Aquela que ficará o botão) ?
Se eu permitir edição, ele vai deixar Digitação ? abaixo a classe que implementa o botão na JTable
(EDIT) Também configurar essa classe do meu jeito, num entendi muito bem seu funcionameto!!!
ViniGodoy
Um dos métodos do AbstractTableModel que você pode implementar é o isCellEditable(int row, int column).
Basta retornar true quando a coluna for editável, e false quando não. Vamos supor que vc queira que todas as colunas menores que a 4ª não sejam editáveis:
public bool isCellEditable(int row, int col) {
return col >= 4;
}
Assim, basta implementar o isCellEditable corretamente, que a JTable probirá a digitação nas colunas que retornar false, mas permitirá o clique nos botões das colunas onde ele retorna true.
ElesisLink
Valeu, ViniGodoy, vc me fez uma pessoa melhor com AbstractTableModel…
Peço descupas por ser tão noob, mas faz pouco tempo que estou mexendo com JTable( menos de uma semana)…
Sou seu fã, cara e valeu por não me dieixar na mão…
ViniGodoy
Não é à toa que eu iniciei a campanha de “Morte ao DefaultTableModel”.