Capturar linha selecionada de uma JTable!

[quote=?Bruno?]Seria dentro do metodo, isCellEditable?
Como poderia ser feita essa verificaçao?[/quote]

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?

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

Bom, entao seria necessario dizer que tipo e para todas as minhas colunas?
Como seria feito?

[quote=?Bruno?]Bom, entao seria necessario dizer que tipo e para todas as minhas colunas?
Como seria feito?[/quote]

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?

Sim, é similar sim. Cria no seu dao o método

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:

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

}[/code]

Para o seu TableModel ser modificável, você precisaria ainda adicionar os método adicionar e remover nele:

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

Isso vai dentro do DAO?
Seria similar ao adicionar ou atualizar?

[quote=ViniGodoy]

public void remover(Aluno aluno)

Este codigo abaixo vai no DAO também?

[quote=ViniGodoy]

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

}[/code] [/quote]

Nessa linha deu o seguinte erro:

Seria necessario conveter ou codigo esta incorreto?
Meio perdido aqui…

[quote=?Bruno?]Isso vai dentro do DAO?
Seria similar ao adicionar ou atualizar?[/quote]

Sim, aquilo vai dentro do DAO.

[quote=?Bruno?]
Este codigo abaixo vai no DAO também?

[quote=ViniGodoy]

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

}[/code] [/quote][/quote]

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.

[quote=?Bruno?]
Seria necessario conveter ou codigo esta incorreto?
Meio perdido aqui…[/quote]

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.

[quote=ViniGodoy]
Procure entender certinho tudo o que foi feito aqui e você naturalmente responderá sua pergunta de como incluir um campo boolean na tabela. [/quote]

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); } }