Vincular JTable com List

8 respostas
J

Gostaria de saber se vocês poderiam me ajudar em uma dúvida:

Nos seus exemplo de vinculação de uma JTable com uma list, normalmente se usa o conjunto, entidade -> query ->list. Tem como eu vincular uma JTable com uma list sem usar esta hierarquia, ou seja, eu tendo um list já pré-preenchido, sem o uso de query…? Se sim, tem como alguém postar um exemplo básico?

8 Respostas

R

vc pode usar um TableModel.
instancia seu tablemodel com seu list e seta esse model na sua tabela.

exemplo:

public abstract class GenericTableModel<T> extends AbstractTableModel {

    public abstract void setData(List<T> list);

    public abstract T getValueAt(int row);

    public abstract int indexOf(T entity);

    public abstract void clear();

    public abstract void remove(T entity);

    public abstract void add(T entity);

    public abstract boolean contains(T entity);
    
    public abstract List<T> list();
    
    public abstract void updateItem( int idx, T entity);
    
}

vc pode usar essa classe pra extender os seus tablemodels.

ex.:

public class LogTableModel extends GenericTableModel<Log> {
    
    private String[] columnNames = { "Docto", "Número", "Data Envio", "Tipo", "Status", "ProtocoloID" };
    private List<Log> logList;
    
    public LogTableModel() {
        logList = new ArrayList<Log>();
    }
    
    public LogTableModel( List<Log> logList ) {
        this();
        setData( logList );
    }

    @Override
    public String getColumnName(int col) {
        return columnNames[col];
    }
    
    public String[] getColumnNames() {
        return columnNames;
    }
    
    @Override
    public void setData(List<Log> list) {
        this.logList.clear();
        this.logList.addAll( list );
        super.fireTableDataChanged();
    }

    @Override
    public Log getValueAt(int row) {
        return logList.get( row );
    }

    @Override
    public int indexOf(Log entity) {
        return logList.indexOf( entity );
    }

    @Override
    public void clear() {
        this.logList.clear();
        fireTableDataChanged();
    }

    @Override
    public void remove(Log entity) {
        logList.remove( entity );
        super.fireTableDataChanged();
    }

    @Override
    public void add(Log entity) {
        logList.add( 0, entity );
        super.fireTableDataChanged();
    }

    @Override
    public boolean contains(Log entity) {
        return logList.contains( entity );
    }

    public int getRowCount() {
        return logList.size();
    }

    public int getColumnCount() {
        return columnNames.length;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        Log log = logList.get( rowIndex );
        switch( columnIndex ) {
            case 0: return log.getDocto();
            case 1: return log.getNumeroNota();
            case 2: return log.getData();
            case 3: return log.getTipo();
            case 4: return log.getRespostaConsulta();
            case 5: return log.getProtocoloId();
        }
        return null;
    }

    @Override
    public List<Log> list() {
        return logList;
    }

    @Override
    public void updateItem(int idx, Log entity) {
        logList.set( idx, entity );
        super.fireTableDataChanged();
    }
    
}

pra relacionar com sua tabela:

LogTableModel logTModel = new LogTableModel( suaListaComOsObjetos );
suaTabela.setModel( model );

A

Olá Rodrigo, tentei fazer o exemplo que você passou para minha Jtable.

Fiz da seguinte forma:
public class AlunoTableModel extends AbstractTableModel {

    private String[] nomeColunas = {"Código", "Nome", "E-mail"};
    private List<Aluno> alunos;

    // construtor padrão criando um arraylist de alunos
    public AlunoTableModel(){
        alunos = new ArrayList<Aluno>();
    }

    // construtor que adiciona a lista passada pelo método ao alunos
    public AlunoTableModel(List<Aluno> lista){
        this();
        this.alunos.clear();
        this.alunos.addAll(lista);
        super.fireTableDataChanged();
    }

    public int getRowCount() {
        return alunos.size();
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public int getColumnCount() {
        return nomeColunas.length;
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
                 Aluno aluno = alunos.get( rowIndex );
         switch( columnIndex ) {
             case 0: return aluno.getId();
             case 1: return aluno.getNome();
             case 2: return aluno.getEmail();
         }
         return null;
        //throw new UnsupportedOperationException("Not supported yet.");
    }
}

Agora não estou sabendo como chamar o método a partir do meu frame.
No netbeans 6.5, clico com o botão direito no jFrame e vou em Conteúdo Da Tabela, escolho personalizar código e em jTableAlunos.setModel( );
eu chamo um método que criei, getTableModelAlunos()
Eu havia feito um teste e funcionava desta maneira populando colunas e linhas a mão, agora quero saber como fazer neste método para continuar usando ele?

Ele está da seguinte forma agora:
private void getTableModelAlunos(){


        AlunoDao ad = new AlunoDao();
        AlunoTableModel atm = new AlunoTableModel(ad.listarAlunos());
        jTableAlunos.setModel(atm);

    }

Eu mudei o retorno para voi pois não estava conseguindo, o que eu devo retornar? como fazer esse método?

Se alguém puder ajudar.
Obrigado.
Alexander

R

vc pode fazer o seguinte…

cria o método retornando seu tablemodel:

private AlunoTableModel atm;

public TableModel getTableModelAlunos() {

AlunoDao ad = new AlunoDao();

atm = new AlunoTableModel(ad.listarAlunos());

return atm;

}

dpois, visualizando sua frame no netbeans, clica no componente jtable que vc adicionou na frame, vai no canto direito em propriedades do componente, acha a opção model, clica no botãozinho para abrir a edição , e coloca o seu método no campo setModel(), .

cria um método na sua classe AlunoTableModel que atualiza a tabela “setando” seu list.
assiml, sempre que vc fizer uma pesquisa na tela, é só vc passar sua consulta para o objeto atm, não precisando instanciá-la novamente.

ex.:

public class AlunoTableModel extends AbstractTableModel {







public void setData(List<Aluno> _list) {

this.list.clear();

this.list.addAll( _list );

super.fireTableDataChanged();

}





}
A

Rodrigo, muito obrigado pela explicação…

Rodou direitinho aqui, agora só mais uma dúvida, tinha alguns métodos que eu ainda não havia colocado, mas já completei eles conforme seu modelo.
Agora, como faço para fixar o tamanho da coluna? em qual lugar coloco isso?
Queria que a coluna Código tivesse um tamanho, nome outro…

Onde que seto aquelas propriedades para deixar selecionar somente a linha toda, e não uma célula?
E no caso, se o indivíduo der um duploclick, para ele chamar outra tela com aqueles dados…
Se não for abusar… hehe

Onde fazer?
Obrigado novamente.

Alexander

R

setar largura coluna:

suaTabela.getColumnModel().getColumn( 0 ).setWidth( 50 ); // largura
//suaTabela.getColumnModel().getColumn( 0 ).setMinWidth( 10 ); // largura mínima
//suaTabela.getColumnModel().getColumn( 0 ).setMaxWidth( 80 ); // largura máxima

suaTabela.getColumnModel().getColumn( 1 ).setWidth( 200 ); // largura
suaTabela.getColumnModel().getColumn( 2 ).setWidth( 100 ); // largura

selecionar a linha toda:

imagino que vc quis dizer pra não selecionar a célula? se for, cria uma classe que extende a JTable e sobrescreva o método isCellEditable, retornando false.

ex.:

<a class="mention" href="/u/override">@Override</a>

public boolean isCellEditable(int row, int column) {

return false;

}

agora é só usar essa sua classe no lugar da jtable. vc pode arrastar direto do package pra tela q o netbeans reconhece como sendo um componente.

para o duplo-clique, é só adicionar o evento MouseClicked e, no evento, pegar o índice da linha selecionada.

int row = tabela.getSelectedRow();

if ( row >= 0) {

// a linha foi selecionada

}
A

Rodrigo, tem como colocar o tamanho das colunas no AlunoTableModel?

Pelo que eu estava vendo aqui, acho que não né?
Teria que popular a tabela antes e depois alterar o tamanho, isso?

No método getTableModelAlunos também não consigui colocar…
Onde seria o melhor lugar?

mais uma vez obrigado.

R

eu faço como indiquei pra vc.

criei uma classe que extende a jtable e joguei um método que altera a largura das colunas nesta classe, junto com o isCellEditable.

public Table extends JTable {







public void defineColumnSize( int[] minSize, int[] maxSize ) {

TableColumnModel tc = this.getColumnModel();

for ( int i = 0; i < minSize.length; i++ ) {

tc.getColumn( i ).setMinWidth( minSize[i] );

}

for ( int i = 0; i < maxSize.length; i++ ) {

tc.getColumn( i ).setMaxWidth( maxSize[i] );

}

}
@Override
public boolean isCellEditable(int row, int column) {
    for ( int i = 0; i &lt; columns.length; i++ ) {
        if ( column == columns[i] )
            return true;
    }

    return false;
}




}

G
public TableModel getTableModelAlunos() {

AlunoDao ad = new AlunoDao();

atm = new AlunoTableModel(ad.listarAlunos());

return atm;

nao entendi, essa parte …o método listarAlunos retorna o q?

Criado 23 de outubro de 2008
Ultima resposta 14 de jun. de 2010
Respostas 8
Participantes 4