Preciso saber como e feita a captura de uma linha selecionada pelo usuario, dei uma pesquisada mas não resolveu. Alguem pode ajudar?
Capturar linha selecionada de uma JTable!
97 Respostas
Para saber a linha selecionada:
nomeDaTabela.getSelectedRow(); //retorna um inteiro
Para pegar um valor da linha:
nomeDaTabela.getValueAt(linha,coluna);
//retorna o objeto correspondente ao tipo determinado no momento da criação da coluna da tabela
Dá uma pesquisada na API da JTable:
http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTable.html
Abraços
Boa, tava precisando disso também…
Valeu 
Caso sua tabela suporte seleção múltipla, existe também o método no plural:
int[] linhas = suaTable.getSelectedRows();
Para pegar um valor da linha, o ideal é consultar o model. O método getValueAt não deve ser chamado diretamente:
SuaClasse obj = seuModel.get(linha);
Para criar um model, veja o link na minha assinatura.
Bom, a minha ideia seria a seguinte:
Com a linha selecionada, se pressionaria um botao para apagar esse registro selecionado. Depois de pegar a linha selecionada, qual seria o proximo passo?
Aí vc pede para o model excluir a linha:
seuModel.remove(linha);
A implementação disso no seu model vai ser mais ou menos assim:
public void remover(int linha) {
lista.remove(linha);
fireTableRowsDeleted(linha, linha);
}
Acho que me expressei errado, gostaria que esse registro/linha selecionada fosse removida do meu Banco de Dados, por exemplo, um registro de cadastro de um produto…
Uai, aí é com você. Você precisa executar a operação adequada, a partir da seleção do registro. Se você vai deletar o registro usando JDBC ou então JPA ou Hibernate, depende de como você está acessando o banco.
Se você precisa de um componente JTable integrado a uma tabela de banco de dados, pode tentar checar o Beans Binding:
https://beansbinding.dev.java.net/
Infelizmente nunca cheguei a mexer com isso para poder lhe explicar como é que isso funciona.
Cara, aí depende mto de como sua tabela ta montada e, principalmente, como sua camada de persistência esta montada.
Eu tenho algo parecido com o q vc ta falando.
- Minha persistência é com JPA/Hibernate;
- meu model da tabela jáme retorna o Objeto completo (exemplo obj Pessoa)
Com o obj Pessoa selecionado, eu tento deletar ele do BD, utilizando, no JPA, um método remove.
Caso obtenha sucesso, eu apago da tabela a informação, depois de enviar uma msg de confirmação p o usuário.
Se seu model não retorna um obj, pode retornar o ID de quem vc quer deletar.
Daí, faz a busca no BD por este ID e depois deleta.
Como eu disse, depende muito de como vc ta fazendo a persistência.
Abraços
Utilizo IDE Net Beans.
Uso o seguinte metodo para popular a JTable:
String[] colunas = new String[]{"Código", "Nome", "Endereco", "Bairro", "Telefone"};
String[][] dados = new String[][]{{"", "", "", "", ""}};
DefaultTableModel modelo = new DefaultTableModel(dados, colunas);
tabelaAmigos.setModel(modelo);
tabelaAmigos.getTableHeader().setResizingAllowed(false);
tabelaAmigos.getColumnModel().getColumn(0).setMaxWidth(50);
tabelaAmigos.getColumnModel().getColumn(1).setMaxWidth(230);
tabelaAmigos.getColumnModel().getColumn(2).setMaxWidth(280);
tabelaAmigos.getColumnModel().getColumn(3).setMaxWidth(80);
tabelaAmigos.getColumnModel().getColumn(4).setMaxWidth(100);
bancoAmigos.conecta();
try {
bancoAmigos.stmt = bancoAmigos.con.createStatement();
String SQL = "SELECT * FROM AMIGOS ORDER BY NOME";
rs = bancoAmigos.stmt.executeQuery(SQL);
int cont = 0;
while (rs.next()) {
tabelaAmigos.setValueAt(rs.getString("CODIGO"), cont, 0);
tabelaAmigos.setValueAt(rs.getString("NOME"), cont, 1);
tabelaAmigos.setValueAt(rs.getString("ENDERECO"), cont, 2);
tabelaAmigos.setValueAt(rs.getString("BAIRRO"), cont, 3);
tabelaAmigos.setValueAt(rs.getString("TELEFONE"), cont, 4);
modelo.addRow(new String[]{"", "", "", "", ""});
cont++;
}
modelo.removeRow(cont--);
} catch (Exception e) {
e.printStackTrace();
}
}
Gostaria de saber, se seria necessario um campo boolean para marcar a linha, se sim como seria feito?
Outra coisa: Depois que se pega a linha selecionada, sera necessario fazer uma comparação com o BD com algum campo para assim usar como criterio para excluir, mas nao ideia de como fazer.
Você está usando o DefaultTableModel.
Isso te tratá diversas dificuldades, e é uma maneira bastante incorreta de se manipular o JTable.
Sugiro fortemente que você:
a) Defina suas classes de negócio;
b) Define as classes de DAO, que irão fazer as operações de banco (cadastrar um objeto, remove-lo, etc);
c) Defina o seu TableModel, filho de AbstractTableModel, para trabalhar com suas classes de negócio (link com explicação para isso na minha assinatura);
A) Se puder detalhar mais seria de grande ajuda (Iniciante detected).
B) Seria o mesmo que usar funçoes em vez de desenvolver todo o codigo? (Nao gosto de usar funcoes)
C) Dei uma olhada por cima e parece algo complicado de se desenvolver.
Posso sim, na verdade, tem diversos tópicos no assunto. Comece então tentando fazer a classe de negócios, e postando aqui, que dou as dicas do que está certo/errado.
Aprenda a gostar. É praticamente impossível desenvolver algo, mesmo que um trabalho de faculdade, sem usar funções.
O código fica 500% mais difícil.
Acredite, vale cada segundo do esforço de aprender.
No começo é um pouco mais complicado sim.
Mas acredite, o esforço vale.
A medida que o sistema cresce, ele vai ficando dificílimo de manter se você não tiver organização. Código profissional, na verdade, é 20% lógica 80% organização. Não é à toa que temos diversos livros só disso.
Bom, para iniciar, preciso saber o que seria uma classe de negocios, ou entao algum link que posso me ajudar, se nao for pedir demais.
Meu primeiro contato com funcoes foi um desastre, comecei usando funçoes criadas por um programador mas nao conseguia me achar, sem javadoc ou ate mesmo com o javadoc eis meu desprezo por elas.
Bom, para iniciar, preciso saber o que seria uma classe de negocios, ou entao algum link que posso me ajudar, se nao for pedir demais. Meu primeiro contato com funcoes foi um desastre, comecei usando funçoes criadas por um programador mas nao conseguia me achar, sem javadoc ou ate mesmo com o javadoc eis meu desprezo por elas.
Sim, vc tem que começar criando suas próprias funções. Usar a dos outros, principalmente sem documentação, pode ser traumático mesmo. Mas você já usa diversas funções, como as que a API do Java te fornece. Labels, Buttons, Statements e a própria classe String são exemplos de código criado pela Sun, usado as estruturas do próprio Java. Código com o que vc terá que montar.
Você já aprendeu orientação à objetos? Por exemplo, os dados da sua tabela referem-se ao que? Amigos?
Nesse caso, é provável que vá haver uma classe:
public class Amigo {
private String nome;
private String endereco;
private String bairro;
private String telefone;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
//Continua aqui, com gets e sets para os outros campos
}
Nao aprendi orientaçao a objetos, digamos que fiz um curso basico de java a uns 5 anos atras.
Somente agora comecei a “mecher” por conta e fui avançando, mas sempre usando a IDE NetBeans, que facilita minha vida.
Muitos termos tecnicos (ate os mais simples =/) nao tenho conhecimento, uso a classe banco onde nele tem as funcoes conecta() e desconecta(). A ideia dessas funcoes e desenvolve-las fora do meu projeto, em um classe especifica, e depois somente chama-las quando necessario, certo?
Tenho uma tela chamada amigos e nela os seguintes campos:
Nome, Endereço, Bairro e telefone.
Esses metodos getNome e setNome sera necessario faze-los assim:
package Menus;
public class Amigos {
private String nome;
private String endereco;
private String bairro;
private String telefone;
public String getNome() {
return nome;
}
public String getEndereco() {
return endereco;
}
public String getBairro() {
return bairro;
}
public String getTelefone() {
return telefone;
}
public void setNome(String nome) {
this.nome = nome;
}
public void setEndereco(String endereco) {
this.endereco = endereco;
}
public void setBairro(String bairro) {
this.bairro = bairro;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}
}
Sei que get ele pega o valor e set ele seta ou atribui um valor, e isso?
Qual a funçao desses metodos? Desculpa tantas duvidas. Isso e coisa facil para voce!
Isso, a classe é assim mesmo. Faltou apenas um atributo para o código, do tipo int. E um set e um get para ele.
Esses métodos permitem que você leia e altere os valores da classe. Não é aconselhável deixar o usuário da classe alterar os atributos diretamente, pois você pode fazer validação. Por exemplo, vamos supor que você não queira que o campo "endereço" contenha valores nulos. Você pode alterar o seu setEndereco para ficar assim:
public void setEndereco(String endereco) {
if (endereco == null) { //Está tentando colocar um endereço nulo?
throw new IlllegalArgumentException("O endereço não pode ser nulo!"); //Erro nele!
}
//Caso contrário, atribuímos o endereço
this.endereco = endereco;
}
Você também pode definir, por exemplo, que um determinado atributo é de "somente leitura". Basta remover o método setter.
Uma coisa, o nome da classe fica no singular, não no plural. A classe representa um amigo. Geralmente, só listas ganham nomes no plural.
Então, agora que você fez sua classe Amigo, é hora de carregar amigos do banco de dados. Crie uma classe chamada AmigoDAO, que é quem vai fazer isso. Dao é a sigla de Data Access Object (objeto de acesso a dados), e nada mais é que a classe que transforma tabelas do banco em objetos da classe Amigo, e vice-versa.
Seu objetivo agora é criar uma classe com um método chamado carregar(), que te retornará um List de amigos.
Provavelmente vai ficar parecido com isso:
public class AmigoDAO {
public List<Amigo> carregar() {
try {
List<Amigo> amigos = new ArrayList<Amigo>();
//Código para carregar os amigos do banco aqui
PreparedStatement stmt = bancoAmigos.con.prepareStatement("SELECT * FROM Amigos ORDER BY nome");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
//Criamos um novo amigo
Amigo amigo = new Amigo();
amigo.setCodigo(rs.getInt("codigo"));
amigo.setNome(rs.getString("nome"));
amigo.setEndereco(rs.getString("endereco"));
amigo.setBairro(rs.getString("bairro"));
amigo.setTelefone(rs.getString("Telefone"));
//Colocamos ele na lista
amigos.add(amigo);
}
//Retornamos a lista de amigos
return amigos;
} catch (SQLException e) {
//Se ocorrer erros, disparamos na forma de uma RuntimeException
//Isso evitará que tenhamos que ficar tratando erros que raramente ocorrem.
//E que não podemos fazer muita coisa para nos recuperar é o caso das SQLException.
throw new RuntimeException(e);
}
}
O DAO também conterá métodos como:
public void salvar(Amigo amigo);
public void remover(Amigo amigo);
Deixo para você a tarefa de pensar em como fica a implementação deles. Mas note que a classe DAO só tem uma única preocupação: Lidar com o banco de dados, mais nada. Se tiver que inserir algum código para mexer no banco, onde você irá coloca-lo? No DAO. Se algum erro de banco aparecer onde você procura pelo problema? No DAO também.
Tente montar o seu DAO e obter suas listas. Em seguida passamos para o TableModel.
Em relaçao ao codigo, eu so uso ele no Banco de Dados como AUTO_INCREMENT. Quando e feito um cadastro de um novo amigo, nao e possivel escolher um codigo para ele.
Essa classe DAO, e ela que vai cadastrar, remover, alterar, neste caso, um novo amigo?
Esse metodo list, e usado para capturar os dados, gravar, listar?
No caso, para fazer uma gravaçao no BD, onde voce citou:
public void salvar(Amigo amigo);
Seria assim, outro metodo:
public void salvarAmigo() {
//Codigo para salvar
}
Classe DAO:
package Menus;
import com.mysql.jdbc.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class AmigoDAO {
Menus.Banco bancoAmigos = new Menus.Banco();
public List<Amigo> carregar() {
try {
List<Amigo> amigos = new ArrayList<Amigo>();
//Código para carregar os amigos do banco aqui
PreparedStatement stmt = (PreparedStatement) bancoAmigos.con.prepareStatement("SELECT * FROM Amigos ORDER BY nome");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
//Criamos um novo amigo
Amigo amigo = new Amigo();
amigo.setCodigo(rs.getInt("codigo"));
amigo.setNome(rs.getString("nome"));
amigo.setEndereco(rs.getString("endereco"));
amigo.setBairro(rs.getString("bairro"));
amigo.setTelefone(rs.getString("Telefone"));
//Colocamos ele na lista
amigos.add(amigo);
}
//Retornamos a lista de amigos
return amigos;
} catch (SQLException e) {
//Se ocorrer erros, disparamos na forma de uma RuntimeException
//Isso evitará que tenhamos que ficar tratando erros que raramente ocorrem.
//E que não podemos fazer muita coisa para nos recuperar é o caso das SQLException.
throw new RuntimeException(e);
}
}
}
Esta correta?
Sim, o normal é usar Auto_Increment mesmo. Mas você precisa ter o campo código na sua classe amigo para quando for alterar o registro. É necessário saber código de quem você está alterando.
A classe DAO que postei deve estar correta. Se não estiver, está próximo de estar, você mesmo pode fazer as correções.
Sim, o outro método é daquele jeito. Só precisa colocar o código para salvar. Eu geralmente faço assim:
public void salvar(Amigo amigo) {
if (amigo.getCodigo() == -1) {
inserir(amigo); //Faz um INSERT no banco
} else {
atualizar(amigo); //Faz um UPDATE no banco.
}
}
Não esqueça que o método inserir deverá fazer um setCodigo no amigo recebido, para atualizar o registro com o código que o banco gerou.
O list que usei é uma classe que representa uma lista. Você pode ver mais informações sobre ela aqui:
http://www.guj.com.br/posts/list/74068.java#389435
Entendi. Pelo codigo que o BD vai diferenciar e filtrar todos os registros.
O metodo salvar vai ter outro metodo dentro que e o inserir, correto?
No modo gambiarra eu fazia da seguinte maneria:
bancoAmigo.conecta();
try {
if (verifica()) {
bancoAmigo.stmt.execute("INSERT INTO AMIGOS VALUES(0,"
+ "'" + campoNome.getText() + "',"
+ "'" + campoEndereco.getText() + "',"
+ "'" + campoBairro.getText() + "',"
+ "'" + campoTel.getText() + "')");
} else {
JOptionPane.showMessageDialog(this, "Preencher os campos Obrigatorios!");
}
bancoAmigo.stmt.execute("COMMIT");
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, e);
}
bancoAmigo.desconecta();
Entao o metodo inserir seria + ou -:
public void inserir{
//Misterio
}
Outra coisa: Para toda classe que tenho seria interresante fazer uma DAO e a classe com os sets e gets para ficar mais organizado, ou entao deixar tudo junto?
Geralmente para cada classe é um DAO.
Outra coisa, é uma boa usar o PreparedStatement. Ele deixa o código sem concatenação e evita problemas:
public void inserir (Amigo amigo) {
try {
//Fazemos a inserção do amigo no banco
PreparedStatement stmt = bancoAmigo.conn.prepareStatement(
"INSERT INTO Amigos (nome, endereco, bairro, tel) VALUES(?,?,?,?)");
stmt.setString(1, amigo.getNome());
stmt.setString(2, amigo.getEndereco());
stmt.setString(3, amigo.getBairro());
stmt.setString(4, amigo.getTelefone());
stmt.executeUpdate();
//Obtemos a chave criada automaticamente
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
amigo.setCodigo(rs.getInt(1));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
A vantagem do PreparedStatement são as seguintes:
1. Permite que você use objetos de data, sem ter que se preocupar com formato do banco de dados. Isso também deixa o código mais portável, já que os formatos de data podem mudar de banco para banco;
2. Permite que você use Strings, sem ter que se preocupar com caracteres como as aspas simples (considere o que ocorreria no seu código se um usuário inserisse aspas simples no endereço ou no nome);
3. Evita a falha de segurança de SQL Injection;
4. Deixa o código mais claro, já que evita aquele monte de concatenação;
Classe AmigoDAO está da seguinte maneira:
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class AmigoDAO {
Menus.Banco bancoAmigo = new Menus.Banco();
public List<Amigo> carregar() {
try {
List<Amigo> amigos = new ArrayList<Amigo>();
//Código para carregar os amigos do banco aqui
PreparedStatement stmt = (PreparedStatement) bancoAmigo.con.prepareStatement("SELECT * FROM Amigos ORDER BY nome");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
//Criamos um novo amigo
Amigo amigo = new Amigo();
amigo.setCodigo(rs.getInt("codigo"));
amigo.setNome(rs.getString("nome"));
amigo.setEndereco(rs.getString("endereco"));
amigo.setBairro(rs.getString("bairro"));
amigo.setTelefone(rs.getString("Telefone"));
//Colocamos ele na lista
amigos.add(amigo);
}
//Retornamos a lista de amigos
return amigos;
} catch (SQLException e) {
//Se ocorrer erros, disparamos na forma de uma RuntimeException
//Isso evitará que tenhamos que ficar tratando erros que raramente ocorrem.
//E que não podemos fazer muita coisa para nos recuperar é o caso das SQLException.
throw new RuntimeException(e);
}
}
public void salvar(Amigo amigo) {
if (amigo.getCodigo() == -1) {
inserir(amigo); //Faz um INSERT no banco
} else {
atualizar(amigo); //Faz um UPDATE no banco.
}
}
public void inserir(Amigo amigo) {
try {
//Fazemos a inserção do amigo no banco
PreparedStatement stmt = (PreparedStatement) bancoAmigo.con.prepareStatement(
"INSERT INTO Amigos (nome, endereco, bairro, tel) VALUES(?,?,?,?)");
stmt.setString(1, amigo.getNome());
stmt.setString(2, amigo.getEndereco());
stmt.setString(3, amigo.getBairro());
stmt.setString(4, amigo.getTelefone());
stmt.executeUpdate();
//Obtemos a chave criada automaticamente
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
amigo.setCodigo(rs.getInt(1));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void atualizar(Amigo amigo) {
try {
//Fazemos a inserção do amigo no banco
java.sql.PreparedStatement stmt = bancoAmigo.con.prepareStatement(
"UPDATE INTO Amigos (nome, endereco, bairro, tel) VALUES(?,?,?,?)");
stmt.setString(1, amigo.getNome());
stmt.setString(2, amigo.getEndereco());
stmt.setString(3, amigo.getBairro());
stmt.setString(4, amigo.getTelefone());
stmt.executeUpdate();
//Obtemos a chave criada automaticamente
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
amigo.setCodigo(rs.getInt(1));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Então, qual seria o proximo passo?
Cuidado. O UPDATE não tem a palavra INTO. E você precisa especificar no WHERE sobre qual ID vc está fazendo o UPDATE.
Como no momento do Update a chave é conhecida, não há a necessidade de obter do banco novamente qual chave foi inserida.
Entao, seria + ou menos assim:
public void atualizar(Amigo amigo) {
try {
//Fazemos a inserção do amigo no banco
java.sql.PreparedStatement stmt = bancoAmigo.con.prepareStatement(
"UPDATE Amigos WHERE CODIGO (nome, endereco, bairro, tel) VALUES(?,?,?,?)");
stmt.setString(1, amigo.getNome());
stmt.setString(2, amigo.getEndereco());
stmt.setString(3, amigo.getBairro());
stmt.setString(4, amigo.getTelefone());
stmt.executeUpdate();
//Obtemos a chave criada automaticamente
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
amigo.setCodigo(rs.getInt(1));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
No caso, a parte do codigo ali seria a variavel, o metodo getCodigo ou o campo no bando de dados?
java.sql.PreparedStatement stmt = bancoAmigo.con.prepareStatement(
"UPDATE Amigos SET nome=?, endereco=?, bairro=?, tel=? WHERE codigo=?");
stmt.setString(1, amigo.getNome());
stmt.setString(2, amigo.getEndereco());
stmt.setString(3, amigo.getBairro());
stmt.setString(4, amigo.getTelefone());
stmt.setInt(5, amigo.getCodigo()); //Precisamos informar quem está sendo alterado
Não tente programar por tentativa e erro, aí não funciona mesmo. Procure pela sintaxe do SQL, senão não vai funcionar nunca. Mas minha grande frustração com SQL, e que nunca entendi, é pq nunca fizeram a sintaxe do INSERT e do UPDATE parecidas. Por mim, todas tinham que seguir a do update.
O INSERT deixa o nome dos campos longe dos valores, é dependente de ordem. Nenhum desses problemas ocorre na sintaxe do UPDATE.
Ja não algo assim tão facil de se entender, e so tende a ficar mais dificil.
stmt.setString(5, amigo.getCodigo());
Nessa linha deu erro, mas o codigo nao seria um Integer?
stmt.setInt(5, amigo.getCodigo());
Ops, seria sim. Sorry, me empolguei no copy&paste. hehhee
Entao, minha classe DAO com as devidas correçoes:
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class AmigoDAO {
Menus.Banco bancoAmigo = new Menus.Banco();
public List<Amigo> carregar() {
try {
List<Amigo> amigos = new ArrayList<Amigo>();
//Código para carregar os amigos do banco aqui
PreparedStatement stmt = (PreparedStatement) bancoAmigo.con.prepareStatement("SELECT * FROM Amigos ORDER BY nome");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
//Criamos um novo amigo
Amigo amigo = new Amigo();
amigo.setCodigo(rs.getInt("codigo"));
amigo.setNome(rs.getString("nome"));
amigo.setEndereco(rs.getString("endereco"));
amigo.setBairro(rs.getString("bairro"));
amigo.setTelefone(rs.getString("Telefone"));
//Colocamos ele na lista
amigos.add(amigo);
}
//Retornamos a lista de amigos
return amigos;
} catch (SQLException e) {
//Se ocorrer erros, disparamos na forma de uma RuntimeException
//Isso evitará que tenhamos que ficar tratando erros que raramente ocorrem.
//E que não podemos fazer muita coisa para nos recuperar é o caso das SQLException.
throw new RuntimeException(e);
}
}
public void salvar(Amigo amigo) {
if (amigo.getCodigo() == -1) {
inserir(amigo); //Faz um INSERT no banco
} else {
atualizar(amigo); //Faz um UPDATE no banco.
}
}
public void inserir(Amigo amigo) {
try {
//Fazemos a inserção do amigo no banco
PreparedStatement stmt = (PreparedStatement) bancoAmigo.con.prepareStatement(
"INSERT INTO Amigos (nome, endereco, bairro, tel) VALUES(?,?,?,?)");
stmt.setString(1, amigo.getNome());
stmt.setString(2, amigo.getEndereco());
stmt.setString(3, amigo.getBairro());
stmt.setString(4, amigo.getTelefone());
stmt.executeUpdate();
//Obtemos a chave criada automaticamente
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
amigo.setCodigo(rs.getInt(1));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void atualizar(Amigo amigo) {
try {
//Fazemos a inserção do amigo no banco
java.sql.PreparedStatement stmt = bancoAmigo.con.prepareStatement(
"UPDATE Amigos SET nome=?, endereco=?, bairro=?, tel=? WHERE codigo=?");
stmt.setString(1, amigo.getNome());
stmt.setString(2, amigo.getEndereco());
stmt.setString(3, amigo.getBairro());
stmt.setString(4, amigo.getTelefone());
stmt.setInt(5, amigo.getCodigo()); //Precisamos informar quem está sendo alterado
stmt.executeUpdate();
//Obtemos a chave criada automaticamente
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
amigo.setCodigo(rs.getInt(1));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Tudo em ordem? Se sim, qual seria o proximo passo?
Bom, o próximo passo é montar o TableModel.
Veja bem, agora vc tem um List<Amigo>, certo? Fica fácil carregar seus amigos do banco e salva-los lá. Chegou a hora de exibi-los.
Dê uma olhada nesses tópicos, que explicam como criar um TableModel:
http://www.guj.com.br/posts/list/149034.java#808003
http://www.guj.com.br/posts/list/132698.java#714736
Deve ser bem fácil adaptar para o seu caso.
Alterei este exemplo:
package Teste;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
public class AmigoTableModel extends AbstractTableModel {
private static final int COL_CODIGO = 0;
private static final int COL_NOME = 1;
private static final int COL_ENDERECO = 2;
private static final int COL_BAIRRO = 3;
private static final int COL_TELEFONE = 4;
private List<Amigo> valores;
//Esse é um construtor, que recebe a nossa lista de livros
public TableModel(List<Amigo> valores) {
this.valores = new ArrayList<Amigo>(valores);
}
public int getRowCount() {
//Quantas linhas tem sua tabela? Uma para cada item da lista.
return valores.size();
}
public int getColumnCount() {
//Quantas colunas tem a tabela? Nesse exemplo, só 2.
return 2;
}
public String getColumnName(int column) {
//Qual é o nome das nossas colunas?
if (column == COL_CODIGO) {
return "Codigo";
}
if (column == COL_NOME) {
return "Nome";
}
if (column == COL_ENDERECO) {
return "Endereço";
}
if (column == COL_BAIRRO) {
return "Bairro";
}
if (column == COL_TELEFONE) {
return "Telefone";
}
return ""; //Nunca deve ocorrer
}
public Object getValueAt(int row, int column) {
//Precisamos retornar o valor da coluna column e da linha row.
Amigo titulo = valores.get(row);
if (column == COL_CODIGO) {
return titulo.getCodigo();
} else if (column == COL_NOME) {
return titulo.getNome().getNome();
} else if (column == COL_ENDERECO){
return titulo.getEndereco().getEndereco();
} else if (column == COL_BAIRRO){
return titulo.getBairro().getBairro();
} else if (column == COL_TELEFONE){
return titulo.getTelefone().getTelefone();
}
return ""; //Nunca deve ocorrer
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
//Vamos alterar o valor da coluna columnIndex na linha rowIndex com o valor aValue passado no parâmetro.
//Note que vc poderia alterar 2 campos ao invés de um só.
if (columnIndex == COL_NOME) {
titulo.setTitulo(aValue.toString());
} else if (columnIndex == COL_AUTOR) {
titulo.getAutor().setNome(aValue.toString());
}
}
public Class<?> getColumnClass(int columnIndex) {
//Qual a classe das nossas colunas? Como estamos exibindo texto, é string.
return String.class;
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
//Indicamos se a célula da rowIndex e da columnIndex é editável. Nossa tabela toda é.
return true;
}
//Já que esse tableModel é de livros, vamos fazer um get que retorne um livro inteiro.
//Isso elimina a necessidade de chamar o getValueAt() nas telas.
public Amigo get(int row) {
return valores.get(row);
}
}
E por ai mesmo?
E nessa parte:
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
//Vamos alterar o valor da coluna columnIndex na linha rowIndex com o valor aValue passado no parâmetro.
//Note que vc poderia alterar 2 campos ao invés de um só.
if (columnIndex == COL_NOME) {
titulo.setTitulo(aValue.toString());
} else if (columnIndex == COL_AUTOR) {
titulo.getAutor().setNome(aValue.toString());
}
}
Aqui e necessario inserir todos os campos desde codigo ate telefone?
E esta variavel titulo, onde ela e declarada/criada?
No setValueAt vc põe todas as colunas que você queira que o usuário altere na sua tabela. Se sua tabela não for editável, o setValueAt pode estar completamente vazio. Como no isCellEditable vc indicou que todas as suas células são editáveis, então vc precisará colocar o código para todas as colunas.
O que acontece. O seu usuário dá dois cliques numa célula, que contém um valor:
- O seu JTable chama o método isCellEditable para aquela célula. Se retornar true, então ele abrirá um editor e deixará o usuário editar a célula. Se o seu model retornar false, ele não deixará editar a célula;
- O usuário digita no editor o novo valor para a célula;
- O JTable chama o método setValueAt do model, indicando para ele esse novo valor. O model então atualiza o dado, se desejar;
- O JTable chama o método getValueAt do model, para pegar o valor. O valor obtido será exibido.
Se seu setValueAt não alterar o objeto que está dentro do model, assim que o usuário sair do editor ele voltará a ver o valor antigo, antes da edição, já que quando a tabela chegar ao passo 4, ela voltará a obter o valor não modificado. Essa é a forma padrão de tratar entradas inválidas em tabelas.
Quanto ao setValueAt, faltou colocar a linha
Amigo titulo = valores.get(row);
Logo no início, como vc fez para o getValueAt. Outra coisa. A palavra “titulo” tem a ver com livros.
Troque o nome de titulo para amigo no seu caso. 
Eu havia pensado em fazer um alterar da seguinte maneira:
Deixar a tabela somente para listar os registros, o usuario iria selecionar o registro e clicar no botao alterar, onde iria abrir uma tela com os dados carregados para poderem ser alterados.
public Object getValueAt(int row, int column) {
//Precisamos retornar o valor da coluna column e da linha row.
Amigo amigo = valores.get(row);
if (column == COL_CODIGO) {
return amigo.getCodigo();
} else if (column == COL_NOME) {
return amigo.getNome().getNome();
} else if (column == COL_ENDERECO) {
return amigo.getEndereco().getEndereco();
} else if (column == COL_BAIRRO) {
return amigo.getBairro().getBairro();
} else if (column == COL_TELEFONE) {
return amigo.getTelefone().getTelefone();
}
return ""; //Nunca deve ocorrer
}
Neste getValueAt, esta dando ero nos gets(Nome, Endereco, Bairro e Telefone):
Qual seria a ideia de usar dois get um seguido de outro?
Ué, não é para fazer assim, por isso dá erro!
public Object getValueAt(int row, int column) {
//Precisamos retornar o valor da coluna column e da linha row.
Amigo amigo = valores.get(row);
if (column == COL_CODIGO) {
return amigo.getCodigo();
} else if (column == COL_NOME) {
return amigo.getNome();
} else if (column == COL_ENDERECO) {
return amigo.getEndereco();
} else if (column == COL_BAIRRO) {
return amigo.getBairro();
} else if (column == COL_TELEFONE) {
return amigo.getTelefone();
}
return ""; //Nunca deve ocorrer
}
Seria assim?
Isso. Tente entender o que o método está fazendo. Ele é usado pelo JTable para perguntar para seu model. “Ei, o que eu desenho na linha line, coluna row?”
Hmm… entendi.
Tenho uma duvida neste setValueAt:
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
//Vamos alterar o valor da coluna columnIndex na linha rowIndex com o valor aValue passado no parâmetro.
//Note que vc poderia alterar 2 campos ao invés de um só.
Amigo amigo = valores.get(columnIndex);
if (columnIndex == COL_NOME) {
amigo.setNome(aValue.toString());
} else if (columnIndex == COL_ENDERECO) {
amigo.setEndereco(aValue.toString());
} else if (columnIndex == COL_BAIRRO) {
amigo.setEndereco(aValue.toString());
} else if (columnIndex == COL_TELEFONE){
amigo.setTelefone(aValue.toString());
}
}
Ja que e para alteração, o codigo deveria ser incluso no metodo acima?
Não entendi… que código?
Codigo do Amigo, acredito que nao deva ser alterado?
Geralmente você não deixa o usuário alterar o código. Você até pode colocar ele numa das colunas, a título de informação para seu usuário. Mas deixe-a como não editável. Pra isso, basta retornar false naquele método “isEditable” para a coluna do código.
Quem vai alterar o código é apenas o sistema, quando o Amigo for salvo (que daí sairá de -1 para o código que ele usará para sempre).
Seria dentro do metodo, isCellEditable?
Como poderia ser feita essa verificaçao?
Seria dentro do metodo, isCellEditable?
Como poderia ser feita essa verificaçao?
Isso, esse método é o que o JTable usa para perguntar se determinada célula é editável ou não.
Ela seria simplesmente:
@Override
public boolean isCellEditable(int row, int col) {
if (col == COL_ID) {
return false;
} else {
return true;
}
}
Note que esse if é didático, o código mesmo poderia ser simplificado para:
return col != COL_ID;
Hmm… entendo.
Bom, estando tudo em ordem!?, minha tabledModel esta assim:
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
public class AmigoTableModel extends AbstractTableModel {
private static final int COL_CODIGO = 0;
private static final int COL_NOME = 1;
private static final int COL_ENDERECO = 2;
private static final int COL_BAIRRO = 3;
private static final int COL_TELEFONE = 4;
private List<Amigo> valores;
//Esse é um construtor, que recebe a nossa lista de livros
public AmigoTableModel(List<Amigo> valores) {
this.valores = new ArrayList<Amigo>(valores);
}
public int getRowCount() {
//Quantas linhas tem sua tabela? Uma para cada item da lista.
return valores.size();
}
public int getColumnCount() {
//Quantas colunas tem a tabela? Nesse exemplo, só 2.
return 2;
}
public String getColumnName(int column) {
//Qual é o nome das nossas colunas?
if (column == COL_CODIGO) {
return "Codigo";
}
if (column == COL_NOME) {
return "Nome";
}
if (column == COL_ENDERECO) {
return "Endereço";
}
if (column == COL_BAIRRO) {
return "Bairro";
}
if (column == COL_TELEFONE) {
return "Telefone";
}
return ""; //Nunca deve ocorrer
}
public Object getValueAt(int row, int column) {
//Precisamos retornar o valor da coluna column e da linha row.
Amigo amigo = valores.get(row);
if (column == COL_CODIGO) {
return amigo.getCodigo();
} else if (column == COL_NOME) {
return amigo.getNome();
} else if (column == COL_ENDERECO) {
return amigo.getEndereco();
} else if (column == COL_BAIRRO) {
return amigo.getBairro();
} else if (column == COL_TELEFONE) {
return amigo.getTelefone();
}
return ""; //Nunca deve ocorrer
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
//Vamos alterar o valor da coluna columnIndex na linha rowIndex com o valor aValue passado no parâmetro.
//Note que vc poderia alterar 2 campos ao invés de um só.
Amigo amigo = valores.get(rowIndex);
if (amigo == COL_CODIGO) {
amigo.setCodigo();
} else if (columnIndex == COL_NOME) {
amigo.setNome(aValue.toString());
} else if (columnIndex == COL_ENDERECO) {
amigo.setEndereco(aValue.toString());
} else if (columnIndex == COL_BAIRRO) {
amigo.setBairro(aValue.toString());
} else if (columnIndex == COL_TELEFONE) {
amigo.setTelefone(aValue.toString());
}
}
public Class<?> getColumnClass(int columnIndex) {
//Qual a classe das nossas colunas? Como estamos exibindo texto, é string.
return String.class;
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
//Indicamos se a célula da rowIndex e da columnIndex é editável. Nossa tabela toda é.
if (columnIndex == COL_CODIGO) {
return false;
} else {
return true;
}
}
//Já que esse tableModel é de livros, vamos fazer um get que retorne um livro inteiro.
//Isso elimina a necessidade de chamar o getValueAt() nas telas.
public Amigo get(int row) {
return valores.get(row);
}
}
Qual seria o proximo passo?
Cuidado que o código é um inteiro. Então, no getColumnClass vc deve retornar Integer.class para a coluna dele.
Bom, agora é só integrar tudo na sua interface gráfica.
Seu método para popular o JTable agora deve ficar assim:
//Carrega os amigos do banco
List<Amigos> amigos = new AmigosDAO().carregar();
//Cria o model
AmigosTableModel model = new AmigosTableModel(amigos);
//Define na tabela
tabelaAmigos.setModel(amigos);
E aí, não fica muito melhor que o código que vc tinha anteriormente?
Cuidado que o código é um inteiro. Então, no getColumnClass vc deve retornar Integer.class para a coluna dele.Bom, agora é só integrar tudo na sua interface gráfica.
Bom, entao seria necessario dizer que tipo e para todas as minhas colunas?
Como seria feito?
Bom, entao seria necessario dizer que tipo e para todas as minhas colunas?
Como seria feito?
Isso. Mas só o código é inteiro. O resto é tudo String.
Pense um pouco. O método te informa que coluna ele quer saber o tipo. E você deve retornar o tipo.
@Override
public Class<?> getColumnClass(int columnIndex) {
//Qual a classe das nossas colunas? Como estamos exibindo texto, é string.
if (columnIndex == COL_CODIGO) {
return Integer.class;
}else if (columnIndex == COL_NOME){
return String.class;
}else if (columnIndex == COL_ENDERECO){
return String.class;
}else if (columnIndex == COL_BAIRRO){
return String.class;
}else if (columnIndex == COL_TELEFONE){
return String.class;
}
return String.class;
}
Seria isso? Fiquei em duvida, pq telefone e string?
Isso mesmo. Mas como todos os elses retornam o mesmo tipo de dado, vc pode simplificar esse método para:
@Override
public Class<?> getColumnClass(int columnIndex) {
return columnIndex == COL_CODIGO ? Integer.class : String.class;
}
Telefone é um String porque, na prática, você não faz contas com um telefone.
Também existem números como *222 ou #222.
E há também a possibilidade de um número começar com 0. E esse zero estar a esquerda e ser importante.
Bom, minha tabledModel estaria pronta?
Ela estaria listando, gravando, so faltaria remover. Para remover um registro do BD, e similiar ao Inserir e Atualizar?
E para chamar os metodos, como e feito?
public void remover(Aluno aluno)
E lá vc põe o código do DELETE.
Aí depende de como vc organizou sua interface gráfica. Se você tiver um botão de remover para apagar o aluno selecionado, o código vai ficar mais ou menos assim:
public void remover() {
int selected = table.getSelectedIndex();
if (selected == -1) //Nenhuma linha selecionada?
return;
//Obtém o aluno no índice selecionado
Aluno aluno = model.get(selected);
//Remove o aluno do banco
new AlunoDAO().remover(aluno);
//Se deu certo, remove também do JTable
model.remover(selected);
}
Para o seu TableModel ser modificável, você precisaria ainda adicionar os método adicionar e remover nele:
public void adicionar(Aluno aluno) {
valores.add(aluno); //Adiciona o aluno na lista
//Avisa a tabela para se redesenhar
fireTableRowsInserted(valores.size()-1, valores.size()-1);
}
public void remover(int linha) {
valores.remove(linha); //Remove o aluno da lista
fireTableRowsDeleted(linha, linha); //Informa a tabela
}
Isso vai dentro do DAO?
Seria similar ao adicionar ou atualizar?
public void remover(Aluno aluno)
Este codigo abaixo vai no DAO também?
public void remover() { int selected = table.getSelectedIndex(); if (selected == -1) //Nenhuma linha selecionada? return; //Obtém o aluno no índice selecionado Aluno aluno = model.get(selected); //Remove o aluno do banco new AlunoDAO().remover(aluno); //Se deu certo, remove também do JTable model.remover(selected); }
Nessa linha deu o seguinte erro:
[img]http://uploaddeimagens.com.br/imagem/ver/0299imagem.JPG[/img]
Seria necessario conveter ou codigo esta incorreto?
Meio perdido aqui...
Isso vai dentro do DAO? Seria similar ao adicionar ou atualizar?
Sim, aquilo vai dentro do DAO.
Este codigo abaixo vai no DAO também?public void remover() { int selected = table.getSelectedIndex(); if (selected == -1) //Nenhuma linha selecionada? return; //Obtém o aluno no índice selecionado Aluno aluno = model.get(selected); //Remove o aluno do banco new AlunoDAO().remover(aluno); //Se deu certo, remove também do JTable model.remover(selected); }
Não. Aquele código vai na interface gráfica. Seria o código que o botão "remover" roda. Veja que ele apenas está usando as classes que criamos, ele não é parte da implementação dessas classes.
Seria necessario conveter ou codigo esta incorreto? Meio perdido aqui...O código é um inteiro. Então você deve pegar o valor assim:
amigo.setCodigo((Integer)aValue);
Entretanto, como o código não é editável, você nem sequer precisa do if e desse set. Pode deixar seu setValueAt a partir do setNome.
Entendi, entretanto, remover deu esse erro:
A variavel model também deu erro, mas e necessario declarar ela, em que pacote eu faço isso?
Como poderia fazer para adicionar um campo Boolean na minha tabela?
Desculpe, é getSelectedRow() não getSelectedIndex().
Você em algum momento criou o seu tablemodel, certo? Ele deve ser guardado naquela variável model ali.
Procure entender certinho tudo o que foi feito aqui e você naturalmente responderá sua pergunta de como incluir um campo boolean na tabela.
Não entendi.
Procure entender certinho tudo o que foi feito aqui e você naturalmente responderá sua pergunta de como incluir um campo boolean na tabela.
Dentro do tablemodel, devo criar outra coluna da tabela sendo essa um boolean?
Sim. Essa coluna seria para que, especificamente?
Seria um Check box, para ser marcado ou desmarcado. Isso mudaria o jeito como e feito o remover?
Sobre a variavel model listada acima, no tabledModel unica variavel que achei foi o List Amigo, seria essa?
Muda até bastante coisa no model. Só permitir que o usuário selecione a linha usando ctrl ou shift não é suficiente?
Preciso saber de uma coisa: No caso de remover registros, e possivel remover mais de um registro apenas selecionando varios registros e clicando no botao apagar, ou so poderia apagar um de cada vez?
É possível sim. A tabela suporta seleção multipla.
Existe um método chamado getSelectedRows() que retorna um array de ints, contendo todas as linhas selecionadas.
Aí vc faz um método remover no seu model assim:
public void remover(int[] linhas) {
for (int linha = linhas.size()-1; linha >= 0; i--) {
valores.remove(linha);
fireTableRowDeleted(linha, linha);
}
}
Entendi… entretanto ainda nao resolvi o problema do model. Pode ajudar?
Ok, até onde vc foi? E que problema vc está tendo? Conseguiu pelo menos exibir a tabela usando esse model até agora?
Entendi, entretanto, remover deu esse erro:
Seria este erro no model, ainda nao decidi se vou permitir seleçao multipla na minha tabela. Nao sei qual variavel substitui essa model. Olhei no dao so tem uma variavel la, entao?
Como eu falei, o nome é getSelectedRow() não getSelectedIndex().
Você criou alguma variável para guardar seu model? Pode postar o código onde você cria o model e o insere dentro da JTable?
DAO:
package Cadastros;
import com.mysql.jdbc.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class AmigoDAO {
Menus.Banco bancoAmigo = new Menus.Banco();
public List<Amigo> carregar() {
try {
List<Amigo> amigos = new ArrayList<Amigo>();
//Código para carregar os amigos do banco aqui
PreparedStatement stmt = (PreparedStatement) bancoAmigo.con.prepareStatement("SELECT * FROM Amigos ORDER BY nome");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
//Criamos um novo amigo
Amigo amigo = new Amigo();
amigo.setCodigo(rs.getInt("codigo"));
amigo.setNome(rs.getString("nome"));
amigo.setEndereco(rs.getString("endereco"));
amigo.setBairro(rs.getString("bairro"));
amigo.setTelefone(rs.getString("Telefone"));
//Colocamos ele na lista
amigos.add(amigo);
}
//Retornamos a lista de amigos
return amigos;
} catch (SQLException e) {
//Se ocorrer erros, disparamos na forma de uma RuntimeException
//Isso evitará que tenhamos que ficar tratando erros que raramente ocorrem.
//E que não podemos fazer muita coisa para nos recuperar é o caso das SQLException.
throw new RuntimeException(e);
}
}
public void salvar(Amigo amigo) {
if (amigo.getCodigo() == -1) {
inserir(amigo); //Faz um INSERT no banco
} else {
atualizar(amigo); //Faz um UPDATE no banco.
}
}
public void inserir(Amigo amigo) {
try {
//Fazemos a inserção do amigo no banco
PreparedStatement stmt = (PreparedStatement) bancoAmigo.con.prepareStatement(
"INSERT INTO Amigos (nome, endereco, bairro, tel) VALUES(?,?,?,?)");
stmt.setString(1, amigo.getNome());
stmt.setString(2, amigo.getEndereco());
stmt.setString(3, amigo.getBairro());
stmt.setString(4, amigo.getTelefone());
stmt.executeUpdate();
//Obtemos a chave criada automaticamente
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
amigo.setCodigo(rs.getInt(1));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void atualizar(Amigo amigo) {
try {
//Fazemos a inserção do amigo no banco
java.sql.PreparedStatement stmt = bancoAmigo.con.prepareStatement(
"UPDATE Amigos SET nome=?, endereco=?, bairro=?, tel=? WHERE codigo=?");
stmt.setString(1, amigo.getNome());
stmt.setString(2, amigo.getEndereco());
stmt.setString(3, amigo.getBairro());
stmt.setString(4, amigo.getTelefone());
stmt.setInt(5, amigo.getCodigo()); //Precisamos informar quem está sendo alterado
stmt.executeUpdate();
//Obtemos a chave criada automaticamente
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
amigo.setCodigo(rs.getInt(1));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void remover(Amigo amigo){
}
}
Default
package Cadastros;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
public class AmigoTableModel extends AbstractTableModel {
private static final int COL_CODIGO = 0;
private static final int COL_NOME = 1;
private static final int COL_ENDERECO = 2;
private static final int COL_BAIRRO = 3;
private static final int COL_TELEFONE = 4;
private List<Amigo> valores;
//Esse é um construtor, que recebe a nossa lista de amigos
public AmigoTableModel(List<Amigo> valores) {
this.valores = new ArrayList<Amigo>(valores);
}
public int getRowCount() {
//Quantas linhas tem sua tabela? Uma para cada item da lista.
return valores.size();
}
public int getColumnCount() {
//Quantas colunas tem a tabela? Nesse exemplo, só 2.
return 2;
}
public String getColumnName(int column) {
//Qual é o nome das nossas colunas?
if (column == COL_CODIGO) {
return "Codigo";
}
if (column == COL_NOME) {
return "Nome";
}
if (column == COL_ENDERECO) {
return "Endereço";
}
if (column == COL_BAIRRO) {
return "Bairro";
}
if (column == COL_TELEFONE) {
return "Telefone";
}
return ""; //Nunca deve ocorrer
}
public Object getValueAt(int row, int column) {
//Precisamos retornar o valor da coluna column e da linha row.
Amigo amigo = valores.get(row);
if (column == COL_CODIGO) {
return amigo.getCodigo();
} else if (column == COL_NOME) {
return amigo.getNome();
} else if (column == COL_ENDERECO) {
return amigo.getEndereco();
} else if (column == COL_BAIRRO) {
return amigo.getBairro();
} else if (column == COL_TELEFONE) {
return amigo.getTelefone();
}
return ""; //Nunca deve ocorrer
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
//Vamos alterar o valor da coluna columnIndex na linha rowIndex com o valor aValue passado no parâmetro.
//Note que vc poderia alterar 2 campos ao invés de um só.
Amigo amigo = valores.get(rowIndex);
if (columnIndex == COL_NOME) {
amigo.setNome(aValue.toString());
} else if (columnIndex == COL_ENDERECO) {
amigo.setEndereco(aValue.toString());
} else if (columnIndex == COL_BAIRRO) {
amigo.setBairro(aValue.toString());
} else if (columnIndex == COL_TELEFONE) {
amigo.setTelefone(aValue.toString());
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
//Qual a classe das nossas colunas? Como estamos exibindo texto, é string.
if (columnIndex == COL_CODIGO) {
return Integer.class;
} else if (columnIndex == COL_NOME) {
return String.class;
} else if (columnIndex == COL_ENDERECO) {
return String.class;
} else if (columnIndex == COL_BAIRRO) {
return String.class;
} else if (columnIndex == COL_TELEFONE) {
return String.class;
}
return String.class;
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
//Indicamos se a célula da rowIndex e da columnIndex é editável. Nossa tabela toda é.
if (columnIndex == COL_CODIGO) {
return false;
} else {
return true;
}
}
public Amigo get(int row) {
return valores.get(row);
}
}
Ou essa variavel deveria ser criada no codigo fonte da minha tela?
Demorei um pouco para postar mas esta ai os codigos.
Não, estou pedindo para você postar o código da sua tela, onde você tem o JTable.
package Cadastros;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
public class Amigos extends javax.swing.JDialog {
/** Creates new form Clientes */
public Amigos(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension screenSize = tk.getScreenSize();
setLocation((screenSize.width - getSize().width) / 2,
(screenSize.height - getSize().height) / 2);
campoNome.requestFocus();
botaoApagar.setEnabled(false);
atualizar();
}
Menus.Banco bancoAmigos = new Menus.Banco();
ResultSet rs;
String Selecione;
public void remover() {
int selected = tabelaAmigos.getSelectedRow();
if (selected == -1) //Nenhuma linha selecionada?
return;
//Obtém o aluno no índice selecionado
Amigo amigo = Amigo.get(selected);
//Remove o aluno do banco
new AmigoDAO().remover(amigo);
//Se deu certo, remove também do JTable
AmigoTableModel.remover(selected);
}
public void limpar() {
campoNome.setText(null);
campoEndereco.setText(null);
campoBairro.setText(null);
campoTel.setText(null);
}
private boolean verifica() {
if (campoNome.getText().compareTo("") == 0) {
JOptionPane.showMessageDialog(this, "Informe o Nome!");
campoNome.requestFocus();
return false;
}
if (campoEndereco.getText().compareTo("") == 0) {
JOptionPane.showMessageDialog(this, "Informe o Endereço!");
campoEndereco.requestFocus();
return false;
}
return true;
}
public boolean verificaLinha() {
return true;
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jTabbedPane1 = new javax.swing.JTabbedPane();
jPanel1 = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
campoBairro = new javax.swing.JTextField();
campoEndereco = new javax.swing.JTextField();
campoNome = new javax.swing.JTextField();
jLabel9 = new javax.swing.JLabel();
campoTel = new javax.swing.JFormattedTextField();
jPanel2 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
tabelaAmigos = new javax.swing.JTable();
jToolBar1 = new javax.swing.JToolBar();
BotaoCadastrar = new javax.swing.JButton();
jSeparator1 = new javax.swing.JToolBar.Separator();
botaoApagar = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle("Amigos");
setResizable(false);
jLabel2.setText("Nome:");
jLabel3.setText("Endereço:");
jLabel4.setText("Bairro:");
jLabel9.setText("Telefone:");
try {
campoTel.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.MaskFormatter("(##) ####-####")));
} catch (java.text.ParseException ex) {
ex.printStackTrace();
}
org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
.addContainerGap()
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
.add(org.jdesktop.layout.GroupLayout.LEADING, campoEndereco, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE)
.add(org.jdesktop.layout.GroupLayout.LEADING, campoNome, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE)
.add(org.jdesktop.layout.GroupLayout.LEADING, jLabel3)
.add(org.jdesktop.layout.GroupLayout.LEADING, jPanel1Layout.createSequentialGroup()
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jLabel4)
.add(campoBairro, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 135, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.add(7, 7, 7)
.add(jLabel9))
.add(jPanel1Layout.createSequentialGroup()
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(campoTel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 138, Short.MAX_VALUE))))
.add(org.jdesktop.layout.GroupLayout.LEADING, jLabel2))
.addContainerGap())
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.add(jLabel2)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(campoNome, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jLabel3)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(campoEndereco, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabel4)
.add(jLabel9))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(campoBairro, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(campoTel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.add(102, 102, 102))
);
jTabbedPane1.addTab("Informações", jPanel1);
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Dados Cadastrados", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 11), new java.awt.Color(102, 102, 102))); // NOI18N
jScrollPane1.setEnabled(false);
tabelaAmigos.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Código", "Nome", "Endereço", "Bairro", "Telefone"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
};
boolean[] canEdit = new boolean [] {
false, false, false, false, false
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane1.setViewportView(tabelaAmigos);
tabelaAmigos.getColumnModel().getColumn(0).setMinWidth(20);
tabelaAmigos.getColumnModel().getColumn(0).setPreferredWidth(20);
tabelaAmigos.getColumnModel().getColumn(0).setMaxWidth(25);
org.jdesktop.layout.GroupLayout jPanel2Layout = new org.jdesktop.layout.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 565, Short.MAX_VALUE)
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 152, Short.MAX_VALUE)
);
jToolBar1.setRollover(true);
BotaoCadastrar.setFont(new java.awt.Font("Tahoma", 1, 11));
BotaoCadastrar.setText("CADASTRAR");
BotaoCadastrar.setToolTipText("");
BotaoCadastrar.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
BotaoCadastrarActionPerformed(evt);
}
});
jToolBar1.add(BotaoCadastrar);
jToolBar1.add(jSeparator1);
botaoApagar.setFont(new java.awt.Font("Tahoma", 1, 11));
botaoApagar.setText("APAGAR");
botaoApagar.setToolTipText("");
botaoApagar.setFocusable(false);
botaoApagar.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
botaoApagar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
botaoApagar.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
botaoApagarActionPerformed(evt);
}
});
jToolBar1.add(botaoApagar);
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jToolBar1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 911, Short.MAX_VALUE)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(jTabbedPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 304, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jPanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.add(jToolBar1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 25, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(18, 18, 18)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
.add(jTabbedPane1, 0, 0, Short.MAX_VALUE)
.add(jPanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Amigos dialog = new Amigos(new javax.swing.JFrame(), true);
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
});
dialog.setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton BotaoCadastrar;
private javax.swing.JButton botaoApagar;
private javax.swing.JTextField campoBairro;
private javax.swing.JTextField campoEndereco;
private javax.swing.JTextField campoNome;
private javax.swing.JFormattedTextField campoTel;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel9;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JToolBar.Separator jSeparator1;
private javax.swing.JTabbedPane jTabbedPane1;
private javax.swing.JToolBar jToolBar1;
private javax.swing.JTable tabelaAmigos;
// End of variables declaration
}
É possível sim. A tabela suporta seleção multipla.Existe um método chamado getSelectedRows() que retorna um array de ints, contendo todas as linhas selecionadas.
Aí vc faz um método remover no seu model assim:
public void remover(int[] linhas) { for (int linha = linhas.size()-1; linha >= 0; i--) { valores.remove(linha); fireTableRowDeleted(linha, linha); } }
Posso aproveitar o tópico para fazer uma pergunta? rsss
minha tela de consulta é exatamente igual a que vcs vem montando mas minha tabela tem um campo boolean, quero excluir mais de uma linha do tableModel por vez, todas que estiverem selecionada, até ai estou bem, mas só consigo usando Ctrl + click.
o que gostaria de fazer é usar o checkbox da linha para controlar a seleção (das linhas da tabela).
se o checkBox estiver marcado a linha será incluida na lista de exclusão, se estiver desmarcado a linha não estara na lista para excluir.
Do jeito normal quando eu desmarco um checkBox e em seguida clico no botão excluir a linha será excluida porque a linha retorna true para o metodo getSelectdRow certo?!.
falando de outro jeito eu gostaria de usar o evento StateChenged do checkBox para add ou excluir aquela linha da lista de exclusão.
tem como fazer?
meu método de exclusão é esse:
tenho o seguinte codigo no botão Excluir:
int selecionados[] = tabela.getSelectedRows();
if (selecionados.length > 0){
ArrayList<Produto> seraoExcluidos = new ArrayList<Produto>();
for (int i=0; i<selecionados.length; i++)
seraoExcluidos.add(model.getCliente(selecionados[i]));
for (Produto p : seraoExcluidos)
model.excluir(p);
>
Pode postar seu TableModel?
Se você não quiser usar a seleção normal da tabela, vai ter que percorrer seu model para achar quais linhas tem o valor selecionado.
Pode postar seu TableModel?Se você não quiser usar a seleção normal da tabela, vai ter que percorrer seu model para achar quais linhas tem o valor selecionado.
Achei o que eu estava tentando fazer, vergonhoso mas era só isso:
if (lista.size() > 0){
ArrayList<Produto> seraoExcluidos = new ArrayList<Produto>();
for (int i=0; i<lista.size(); i++)
if((Boolean)jTable1.getValueAt(i, 2) == true)//essa é a linha
seraoExcluidos.add(model.getCliente(i));
for (Produto p : seraoExcluidos)
model.excluir(p);
}
a unica coisa é que funciona apenas na primeira vez que clico no botão excluir. O q eu estou tentando fazer é um sistema de contas a pagar em que a tabela de dados listaria as contas por cliente e o usuario seleciona apenas as contas a serem pagas. No sistema da minha empresa qndo eu termino a baixa altomaticamente a janela é fechada, se o meu sistema imitar o deles esse bug nem será um problema…rsss
Obrigado pela disponibilidade.>
O ideal é jamais usar o getValueAt. Esse método deveria ser de uso do JTable.
Seu model deve ter informações suficientes para você fazer algo como:
model.excluirMarcados();
oi
Oi ViniGodoy, parabens esse foi o melhor post q já vi aqui no GUJ.
eu sou novato tbm tentando aprender sobre o tableModel, entao eu estou alterando os dados para a minha necessidade. (uso o netbeans)
porém tem um erro que nao estou conseguindo detectar. Na linha 71. Veja como ficou;
você poderia me dar uma mãozinha?
Grato
public class TableModelProduto extends AbstractTableModel {
private static final int COL_CODIGO = 0;
private static final int COL_PRODUTO = 1;
private static final int COL_VALORPRODUTO = 2;
private static final int COL_ATIVO = 3;
private static final int COL_TIPOPRODUTO = 4;
private List<Produto> listaProdutos;
//Esse é um construtor, que recebe a nossa lista de livros
public TableModelProduto(List<Produto> listaProdutos) {
this.listaProdutos = new ArrayList<Produto>(listaProdutos);
}
@Override
public int getRowCount() {
//Quantas linhas tem sua tabela? Uma para cada item da lista.
return listaProdutos.size();
}
@Override
public int getColumnCount() {
//Quantas colunas tem a tabela? Nesse exemplo, só 2.
return 2;
}
@Override
public String getColumnName(int column) {
//Qual é o nome das nossas colunas?
if (column == COL_CODIGO) {
return "CÓDIGO";
}
if (column == COL_PRODUTO) {
return "PRODUTO";
}
if (column == COL_VALORPRODUTO) {
return "VALOR";
}
if (column == COL_ATIVO) {
return "PRODUTO ATIVO";
}
if (column == COL_TIPOPRODUTO) {
return "TIPO DE PRODUTO";
}
return ""; //Nunca deve ocorrer
}
@Override
public Object getValueAt(int row, int column) {
//Precisamos retornar o valor da coluna column e da linha row.
Produto produto = listaProdutos.get(row);
if (column == COL_CODIGO) {
return produto.getIdProduto();
} else if (column == COL_PRODUTO) {
return produto.getProduto();
} else if (column == COL_VALORPRODUTO) {
return produto.getValorProduto();
} else if (column == COL_ATIVO) {
return produto.getProdutoContinuado();
} else if (column == COL_TIPOPRODUTO) {
return produto.getTipoProduto();
}
return ""; //Nunca deve ocorrer
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
//Vamos alterar o valor da coluna columnIndex na linha rowIndex com o valor aValue passado no parâmetro.
//Note que vc poderia alterar 2 campos ao invés de um só.
Produto produto = listaProdutos.get(rowIndex);
if (produto == COL_CODIGO) {
produto.setIdProduto(rowIndex);
} else if (columnIndex == COL_PRODUTO) {
produto.setProduto(aValue.toString());
} else if (columnIndex == COL_VALORPRODUTO) {
produto.setValorProduto(Double.parseDouble(aValue.toString()));
} else if (columnIndex == COL_ATIVO) {
produto.setProdutoContinuado(Boolean.parseBoolean(aValue.toString()));
} else if (columnIndex == COL_TIPOPRODUTO) {
produto.setTipoProduto(aValue.toString());
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
//Qual a classe das nossas colunas? Como estamos exibindo texto, é string.
return Integer.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
//Indicamos se a célula da rowIndex e da columnIndex é editável. Nossa tabela toda é.
if (columnIndex == COL_CODIGO) {
return false;
} else {
return true;
}
}
//Já que esse tableModel é de livros, vamos fazer um get que retorne um livro inteiro.
//Isso elimina a necessidade de chamar o getValueAt() nas telas.
public Produto get(int row) {
return listaProdutos.get(row);
}
Deveria ser:
if (columnIndex == COL_CODIGO) {
Você fez com produto no lugar de columnIndex.
Vini Obrigadão, finalmente eu consegui implementar a minha tableModel.
Agora outra duvida, eu estou conseguindo fazer alteração normal, porém ela nao atualiza em tempo de execução. tenho que fechar e abrir a janela para ela atualizar.
o que eu preciso fazer?
grato
Vini Obrigadão, finalmente eu consegui implementar a minha tableModel.Agora outra duvida, eu estou conseguindo fazer alteração normal, porém ela nao atualiza em tempo de execução. tenho que fechar e abrir a janela para ela atualizar.
o que eu preciso fazer?grato
Dê um revalidate() e repaint() no seu JTable toda vez que você atualizar os valores da tabela.
Rafael_Leal…
Obrigado pela dica
eu coloquei dentro do botao salvar e nao funcinou, coloquei no lugar errado?
revalidate() e repaint()
dentro do botão salvar?
Pois é…
Vc quer é atualizar o valor da table quando vc seta os valors via codigo?
Se sim toda vez que vc setar… faça o que disse. Pois esses metodos somente atualiza a exibiçao dos valores dos componentes javax.swing caso os mesmos forem alterados via código.
Se for via teclado nem precisa.
Se vc fizer isso no botao salvar… vc sô vai arializar a tela ao salvar.
Não consegui fazer funcionar. teria outra ideia?
abs
Explica é contexto de novo…?
Qual exatamente o erro, acontece quando e deveria ser qdo?
Se possível pode a Classe que tem o JTable pelo menos. (Se possível)
Abraço
Não deveria ser necessário chamar repaint. Poste seu model completo e a claase que tem o Table.
Entao eu tenho, umas jTextfields. e dois botoes, gravar e excluir.
qdo faço modificações nas Jt a jtable nao atualiza (Não insere, não excluir e não altera) na hora, e tem q fechar e abrir de novo a Jframe dai ela atualiza.
já tentei colocar umas linhas mas acho q não coloquei as corretas.
segue a tableModel:
Lembrando que no banco de dados esta tudo ok, em relação as atualizações o problema é somente na table
depois tenho uma outra bem boa pra vcs que essa eu nao achei aqui no forum rsrs
public class ProdutoTableModel extends AbstractTableModel {
private static final int COL_CODIGO = 0;
private static final int COL_PRODUTO = 1;
private static final int COL_VALORPRODUTO = 2;
private static final int COL_ATIVO = 3;
private static final int COL_TIPOPRODUTO = 4;
private List<Produto> listaProdutos;
//Esse é um construtor, que recebe a nossa lista de livros
public ProdutoTableModel(List<Produto> listaProdutos) {
this.listaProdutos = new ArrayList<Produto>(listaProdutos);
}
@Override
public int getRowCount() {
//Quantas linhas tem sua tabela? Uma para cada item da lista.
return listaProdutos.size();
}
@Override
public int getColumnCount() {
//Quantas colunas tem a tabela? Nesse exemplo, só 5.
return 5;
}
@Override
public String getColumnName(int column) {
//Qual é o nome das nossas colunas?
if (column == COL_CODIGO) {
return "CÓDIGO";
}
if (column == COL_PRODUTO) {
return "PRODUTO";
}
if (column == COL_VALORPRODUTO) {
return "VALOR";
}
if (column == COL_ATIVO) {
return "PRODUTO ATIVO";
}
if (column == COL_TIPOPRODUTO) {
return "TIPO DE PRODUTO";
}
return ""; //Nunca deve ocorrer
}
@Override
public Object getValueAt(int row, int column) {
//Precisamos retornar o valor da coluna column e da linha row.
Produto produto = listaProdutos.get(row);
if (column == COL_CODIGO) {
return produto.getIdProduto();
} else if (column == COL_PRODUTO) {
return produto.getProduto();
} else if (column == COL_VALORPRODUTO) {
return produto.getValorProduto();
} else if (column == COL_ATIVO) {
return produto.getProdutoContinuado();
} else if (column == COL_TIPOPRODUTO) {
return produto.getTipoProduto();
}
return ""; //Nunca deve ocorrer
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
Produto produto = listaProdutos.get(rowIndex);
if (columnIndex == COL_CODIGO) {
produto.setIdProduto(rowIndex);
} else if (columnIndex == COL_PRODUTO) {
produto.setProduto(aValue.toString());
} else if (columnIndex == COL_VALORPRODUTO) {
produto.setValorProduto(Double.parseDouble(aValue.toString()));
} else if (columnIndex == COL_ATIVO) {
produto.setProdutoContinuado(Boolean.parseBoolean(aValue.toString()));
} else if (columnIndex == COL_TIPOPRODUTO) {
produto.setTipoProduto(aValue.toString());
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
//Qual a classe das nossas colunas? Como estamos exibindo texto, é string.
return Integer.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
//Indicamos se a célula da rowIndex e da columnIndex é editável. Nossa tabela toda é.
// if (columnIndex == COL_CODIGO) {
// return false;
// } else {
// return true;
// }
return false; // Aqui todas as celulas nao serão editaveis
}
public Produto get(int row) {
return listaProdutos.get(row);
}
public void setRemoveRow(int row) {
fireTableRowsDeleted(row, row);
}
}
SeuModel.getValueAt(SeuModel.getSelectedRow(), 0).toString()) // o 0 é a 1ª coluna
Ué, mas cadê os métodos de atualização da JTable?
Deveria ter método assim no seu model:public void remove(int row) {
//Remove da lista
listaProdutos.remove(row);
//Avisa a tabela que foi removido
fireTableRowsDeleted(row, row);
}
public void add(Produto produto) {
//Adiciona na lista
listaProdutos.add(produto);
//Avisa a tabela que um novo produto foi inserido.
fireTableRowsInserted(listaProdutos.size()-1, listaProdutos.size()-1);
}
No método de remover da interface gráfica, você faria algo como:
public void actionPerformed(ActionEvent evt) {
int linhaSelecionada = seuTable.getSelectedRow();
if (linhaSelecionada == -1)
return;
Produto produtoSelecionado = seuModel.get(linhaSelecionada);
new ProdutoDao().remove(produtoSelecionado); //Manda remover do BD
seuModel.remove(linhaSelecionada); //Chama o remove do model para remover da tabela
}
As chamadas a "fire" dentro do model avisam a tabela que ela foi modificada. Quando o model faz um "fire" a Table fica sabendo que deve se redesenhar.
Caramba! Funcionou eu estava quase acertando rsrs.
a parte do tablemodel eu ja tinha feito, porem nao tinha feito a parte grafica.
a parte excluir ja esta funfando vou terminar agora. depois vou precisar de mais um dica rsrs.
eu tinha tudo isso funcionando no default… inclusive um metodo de pesquisa rapida q era show de bola agora com o tablemodel nao consegui mais fazer funfar.
bem vou terminar aqui. depois conversamos mais sobre a pesquisa.
abraço e boa noite
Oi vini boa tarde. ontem eu consegui mais uns avanços, a parte de exclusão ficou perfeita porém adicionar ele adiciona com erros. Top:
ele aparece na tabela durante a insersão, porem fica picado os dados, só aparece o nome do produto e o valor o resto fica em branco.
- e a parte de atualização tbm nao consegui. segue o codigo;
este trecho esta no tablemodel
public void setAdd(Produto produto) {
//Adiciona na lista
listaProdutos.add(produto);
//Avisa a tabela que um novo produto foi inserido.
fireTableRowsInserted(listaProdutos.size()+1, listaProdutos.size()+1);
}
public void setAtualiza(Produto produto){
fireTableDataChanged();
}
na classe grafica esta assim;
public void setGravarProduto() {
produto.setProduto(tfProduto.getText());
produto.setValorProduto(Double.parseDouble(tfValorProduto.getText().replaceAll(",", ".")));
TipoProduto obj = (TipoProduto) listaTipoProdutos.get(jcTipoProduto.getSelectedIndex());
produto.setIdTipoProduto(obj.getIdTipoproduto());
new ProdutoDAO().setAdiciona(produto); //Manda adicionar no BD
tableModelProduto.setAdd(produto); //Chama o add do model para adicionar na tabela
limparCampos();
btGravar.setEnabled(false);
}
public void setAlterarProduto() {
produto.setIdProduto(Integer.parseInt(tfIdProduto.getText()));
produto.setProduto(tfProduto.getText());
produto.setValorProduto(Double.parseDouble(tfValorProduto.getText().replaceAll(",", ".")));
TipoProduto obj = (TipoProduto) listaTipoProdutos.get(jcTipoProduto.getSelectedIndex());
produto.setIdTipoProduto(obj.getIdTipoproduto());
if (jCheckBox.isSelected()) {
produto.setProdutoContinuado(false);
} else {
produto.setProdutoContinuado(true);
}
new ProdutoDAO().setAltera(produto);
tableModelProduto.fireTableDataChanged();
limparCampos();
btGravar.setEnabled(false);
}
Abraço
O certo é size()-1 não size()+1 como você fez.
Você deve disparar no evento o índice que foi adicionado. Como ele já está na lista, ele será = size()-1.
Entao não é isso rs. eu tinha mudado para +1 para ver se mudava algo, mas nao era, e eu tinha esquecido de mudar para -1 novamente.
com isso nao consigo inserir corretamente e nem atualizar um campo.
Os codigos que passei estao corretos?
abs
Aparentemente sim.
Bom dia!.
olha como fica quando insere um produto novo.
e quando eu clico em cima tbm e mudo algo como o valor por exemplo ele tbm nao muda.

Já usou o depurador? Tem certeza de que esses campos estão preenchidos na classe no produto que está sendo inserido na tabela?
E nego está dificil rsrs
e olha que essa é fichinha pra outra que eu quero fazer. ne debug nao aparece erro nenhum.
deve estar falhando no update da jtable. pq esta inserindo normal.
veja como esta o jFrame:
public class FormProduto extends javax.swing.JFrame {
Produto produto = new Produto(WIDTH, null, Double.NaN, rootPaneCheckingEnabled, PROPERTIES, null, null);
ProdutoDAO produtoDAO = new ProdutoDAO();
TipoProduto tipoProdutos = new TipoProduto();
TipoProdutoDAO tipoProdutoDAO = new TipoProdutoDAO();
JLabel tfIdProduto = new JLabel();
// JcomboBox
List<TipoProduto> listaTipoProdutos = tipoProdutoDAO.getUpdateJtableTipo();
// Jtable
List<Produto> listProdutos = new ProdutoDAO().getUpdateJtable();
ProdutoTableModel tableModelProduto = new ProdutoTableModel(listProdutos);
public FormProduto() {
// AQUI TROCA O TAB PELO ENTER NA TRANSIÇÃO DE JTEXTFIELD
HashSet conj = new HashSet(this.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
conj.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_ENTER, 0));
this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, conj);
initComponents();
jTable1.setModel(tableModelProduto);
setUpdateJtable();
}
private void btFecharActionPerformed(java.awt.event.ActionEvent evt) {
this.dispose();
}
private void btLimparActionPerformed(java.awt.event.ActionEvent evt) {
limparCampos();
}
private void formWindowOpened(java.awt.event.WindowEvent evt) {
setPreencheList();
limparCampos();
}
private void btGravarActionPerformed(java.awt.event.ActionEvent evt) {
setHabilitaBtGravar();
if (tfIdProduto.getText().equals("")) {
setGravarProduto();
} else {
setAlterarProduto();
}
}
private void tfProdutoFocusLost(java.awt.event.FocusEvent evt) {
produto.setProduto(tfProduto.getText().toString());
if (produtoDAO.setProdutoExistente(produto) == false || tfProduto.getText().toUpperCase().equals("")) {
tfValorProduto.setEnabled(false);
btGravar.setEnabled(false);
limparCampos();
} else {
tfValorProduto.setEnabled(true);
tfValorProduto.requestFocus();
}
}
private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {
int i = jTable1.getSelectedRow();
tfIdProduto.setText(jTable1.getModel().getValueAt(i, 0).toString());
tfProduto.setText(jTable1.getModel().getValueAt(i, 1).toString());
tfValorProduto.setText(jTable1.getModel().getValueAt(i, 2).toString().replaceAll(",", "."));
jcTipoProduto.setSelectedItem(jTable1.getModel().getValueAt(i, 4));
produto.setIdProduto(Integer.parseInt(tfIdProduto.getText()));
if (produtoDAO.getPesquisaProdutoContinuado(produto) == true) {
jCheckBox.setSelected(false);
tfProduto.setEnabled(true);
tfValorProduto.setEnabled(true);
} else {
jCheckBox.setSelected(true);
tfProduto.setEnabled(false);
tfValorProduto.setEnabled(false);
}
btExcluir.setEnabled(true);
}
private void btExcluirActionPerformed(java.awt.event.ActionEvent evt) {
setRemoveLinhaTable();
limparCampos();
}
private void tfValorProdutoFocusLost(java.awt.event.FocusEvent evt) {
jcTipoProduto.requestFocus();
}
private void jcTipoProdutoItemStateChanged(java.awt.event.ItemEvent evt) {
btGravar.setEnabled(true);
btGravar.requestFocus();
}
private void btPesquisaActionPerformed(java.awt.event.ActionEvent evt) {
produto.setPesquisaRapida(tfPesquisaRapida.getText());
}
//
// Variables declaration - do not modify
private javax.swing.JButton btExcluir;
private javax.swing.JButton btFechar;
private javax.swing.JButton btGravar;
private javax.swing.JButton btLimpar;
private javax.swing.JButton btPesquisa;
private javax.swing.JCheckBox jCheckBox;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JPanel jPanel5;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
private javax.swing.JComboBox jcTipoProduto;
private javax.swing.JTextField tfPesquisaRapida;
private javax.swing.JTextField tfProduto;
private javax.swing.JFormattedTextField tfValorProduto;
// End of variables declaration
public void limparCampos() {
tfIdProduto.setText("");
tfProduto.setText("");
tfValorProduto.setText("");
tfPesquisaRapida.setText("");
jCheckBox.setSelected(false);
btGravar.setEnabled(false);
btExcluir.setEnabled(false);
jcTipoProduto.setSelectedItem(null);
}
private void setUpdateJtable() {
DefaultTableCellRenderer rendererCentro = new DefaultTableCellRenderer();
rendererCentro.setHorizontalAlignment(SwingConstants.CENTER);
DefaultTableCellRenderer rendererEsquerda = new DefaultTableCellRenderer();
rendererEsquerda.setHorizontalAlignment(SwingConstants.LEFT);
TableColumnModel modeloDaColuna = jTable1.getColumnModel();
modeloDaColuna.getColumn(0).setCellRenderer(rendererCentro);
modeloDaColuna.getColumn(1).setCellRenderer(rendererEsquerda);
modeloDaColuna.getColumn(2).setCellRenderer(rendererCentro);
modeloDaColuna.getColumn(3).setCellRenderer(rendererCentro);
modeloDaColuna.getColumn(4).setCellRenderer(rendererCentro);
modeloDaColuna.getColumn(0).setMaxWidth(60);
modeloDaColuna.getColumn(1).setMaxWidth(300);
modeloDaColuna.getColumn(2).setMaxWidth(70);
modeloDaColuna.getColumn(3).setMaxWidth(130);
modeloDaColuna.getColumn(4).setMaxWidth(150);
}
private void setPreencheList() {
for (TipoProduto tipoProduto : listaTipoProdutos) {
jcTipoProduto.addItem(tipoProduto.getTipoProduto());
}
}
public void setRemoveLinhaTable() {
int linhaSelecionada = jTable1.getSelectedRow();
if (tfIdProduto.getText().equals("")) {
JOptionPane.showMessageDialog(null, "Não há item selecionado para excluir");
} else {
produto = tableModelProduto.get(linhaSelecionada);
new ProdutoDAO().setExcluir(produto); //Manda remover do BD
tableModelProduto.setRemove(linhaSelecionada); //Chama o remove do model para remover da tabela
}
}
public void setHabilitaBtGravar() {
if (tfProduto.getText().equals("")) {
JOptionPane.showMessageDialog(null, "O Campo produto não pode estar em branco!");
btGravar.setEnabled(false);
} else if (tfValorProduto.getText().equals("")) {
JOptionPane.showMessageDialog(null, "O Campo valor do produto não pode estar em branco!");
btGravar.setEnabled(false);
} else if (jcTipoProduto.getSelectedItem() == null) {
JOptionPane.showMessageDialog(null, "O Campo tipo de produto não pode estar em branco!");
btGravar.setEnabled(false);
}
}
public void setGravarProduto() {
produto.setProduto(tfProduto.getText());
produto.setValorProduto(Double.parseDouble(tfValorProduto.getText().replaceAll(",", ".")));
TipoProduto obj = (TipoProduto) listaTipoProdutos.get(jcTipoProduto.getSelectedIndex());
produto.setIdTipoProduto(obj.getIdTipoproduto());
new ProdutoDAO().setAdiciona(produto); //Manda adicionar no BD
tableModelProduto.setAdd(produto); //Chama o add do model para adicionar na tabela
limparCampos();
btGravar.setEnabled(false);
}
public void setAlterarProduto() {
produto.setIdProduto(Integer.parseInt(tfIdProduto.getText()));
produto.setProduto(tfProduto.getText());
produto.setValorProduto(Double.parseDouble(tfValorProduto.getText().replaceAll(",", ".")));
TipoProduto obj = (TipoProduto) listaTipoProdutos.get(jcTipoProduto.getSelectedIndex());
produto.setIdTipoProduto(obj.getIdTipoproduto());
if (jCheckBox.isSelected()) {
produto.setProdutoContinuado(false);
} else {
produto.setProdutoContinuado(true);
}
new ProdutoDAO().setAltera(produto);
tableModelProduto.fireTableDataChanged();
limparCampos();
btGravar.setEnabled(false);
}
}
Esse objeto produto que está sendo alterado no método altera, onde você define o valor dele?
O ideal seria obter o produto pelo model, altera-lo, e depois dar um fireTableRowsUpdated.
Mais ou menos assim:
int linhaSelecionada = jTable1.getSelectedRow();
if (linhaSelecionada == -1)
return;
//Obtemos o produto que está dentro do JTable
produto = tableModelProduto.get(linhaSelecionada);
produto.setProduto(tfProduto.getText());
produto.setValorProduto(Double.parseDouble(tfValorProduto.getText().replaceAll(",", ".")));
TipoProduto obj = (TipoProduto) listaTipoProdutos.get(jcTipoProduto.getSelectedIndex());
produto.setIdTipoProduto(obj.getIdTipoproduto());
//Salvamos a alteração no banco
new ProdutoDAO().setAdiciona(produto); //Manda adicionar no BD
//Avisamos a tabela que o produto mudou
tableModelProduto.fireTableRowsUpdated(linhaSelecionada, linhaSelecionada);
Bom dia. vini
Demorei para retornar por causa das provas.
continuo com problemas, na hora de inserir um item novo, sai falhado, somente o nome fica lá perfeito porem o resto dos dados não saem, e qdo clico em cima dele aparece uma mensagem de nullpointer.
o codigo estão acima ele deleta e altera com perfeição. o problema é somente na hora de inserir.

Vini, descobri que nesse metodo esta voltando o codigo como null.
é por isso que esta falhando na tela, porém ainda nao tenho ideia de como resolver.
public void setAdd(TipoProduto tipoProduto) {
//Adiciona na lista
this.listaProdutos.add(tipoProduto);
//Avisa a tabela que um novo produto foi inserido.
fireTableRowsInserted(this.listaProdutos.size() - 1, this.listaProdutos.size() - 1);
}
kra por favor me ajudem… alguem ai sabe dizer como q eu faço pra ficar passando o nome completo ,por exemplo, na linha selecionada em uma tabela pequena …
pq qando eu faço sempre fica com os 3 pontos …