Capturar linha selecionada de uma JTable!

Preciso saber como e feita a captura de uma linha selecionada pelo usuario, dei uma pesquisada mas não resolveu. Alguem pode ajudar?

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

2 curtidas

Boa, tava precisando disso também…
Valeu :stuck_out_tongue:

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.

  1. Minha persistência é com JPA/Hibernate;
  2. 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 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.

[quote=?Bruno?]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.[/quote]

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:

[code]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

}[/code]

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:

[code]
public class AmigoDAO {
public List carregar() {
try {
List amigos = new ArrayList();
//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);

}
}[/code]

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?