[Dúvida] Pegar objeto da JTable [RESOLVIDO]

Olá, pessoal do GUJ!

Venho eu, novamente, com outra dúvida para vocês!

Bom, tenho uma JTable.
Estou usando (por enquanto) um DefaultTableModel nela:

private DefaultTableModel tableModel(List<Usuario> usuarios) {
        
        DefaultTableModel tableModel = null;
		
        try {
            
           Vector<String> colunas = new Vector<String>();
		   colunas.add("ID");
		   colunas.add("Nome");
		   colunas.add("Senha");
		
		   Vector<Object> dados = new Vector<Object>();
		   if(usuarios != null) {
              
              for (Usuario usuario : usuarios) {
                  
                  Usuario u = new Usuario();
                  
                  Vector<String> linha = new Vector<String>();
                  linha.add(u.getId());
                  linha.add(u.getUsuario());
                  linha.add(u.getSenha());
                  
                  dados.add(linha);
              }
              
              tableModel = new DefaultTableModel(data,columns);
		   }
        }
        
	    return tableModel;
    }

Beleza… Assim, monto o modelo da JTable bonitinho.

Agora, como faria para pegar, por exemplo, um objeto referente ao primeiro usuário listado?
Agradeço a atenção de todos, e fico no aguardo!

Forte abraço!

Não intendi…
a tabela já está com as colunas “id, nome e senha”?
ela ta preenchida?
explica melhor o que você quer…

Se sua intenção for pegar o valor de determinada linha quando esta for selecionada, seria mais ou menos assim:
Adicione no seu frame 2 jTextFields…
No evento Mouse>MouseCliqued da tabela, coloque o seguinte código:

  int k = jTable1.getSelectedRow();
    String ID = (String) jTable1.getValueAt(k, 0);
    String SEILA = (String) jTable1.getValueAt(k, 1);
    jTextField1.setText(ID);
    jTextField2.setText(SEILA); 

Se não for isso, seja mais claro quanto a sua dúvida…
Se foi resolvido, adicione ao final do título (assunto) : [RESOLVIDO]

1 curtida

Bom, você está vendo 3 problemas do DefaultTableModel:

  1. Ele não trabalha com objetos. Nele, vc tem strings, com cópias de valores do seu objeto, e isso ocupa muito mais espaço do que fazer um model que trabalhe diretamente com sua classe de negócio;
  2. Ele usa Vector, que não é recomendado desde o Java 1.2. O código do Vector é inteiro synchronized e tem vários métodos fora da Collections Framework.
  3. Ele torna o código mais difícil. Para vc pegar um objeto agora, vc terá que ler o valor do seu JTable, e procurar o equivalente num List. Tudo isso passando por casts e código sujeito a erro de execução.

Por isso, não use o DefaultTableModel. Faça seu próprio model, que será mais rápido, mais fácil, mais prático, mais seguro, mais orientado a objetos e ainda irá respeitar o modelo MVC.

Abaixo, segue um model de exemplo, para livros. Você poderá adapta-lo facilmente a um model de usuários:
http://www.guj.com.br/posts/list/132698.java#714736

Olá, pessoal!

Antes de tudo, muito obrigado pela ajuda!

@Vini

Então, Vini… Você me recomendou fazer meu próprio Model…
O problema é que tenho um projeto para apresentar quinta-feira, e não estou com tempo para sentar e projetar meu próprio Model, visto que tem MUITA coisa pra fazer que é prioridade!

Mas obrigado, novamente!

Abraço a todos!

Ok, mas já vou avisando. Você vai perder mais tempo fazendo com o DefaultTableModel.
Pelo menos dê uma lida no tópico, e você vai ver que não é nenhum bicho de sete cabeças…

1 curtida

Por exemplo, seu model para tabela de usuários ficaria mais ou menos assim:

[code]public class UsuariosTableModel extends AbstractTableModel {
private static final int COL_ID = 0;
private static final int COL_NOME = 1;
private static final int COL_SENHA = 1;

private List<Usuario> valores;       

//Esse é um construtor, que recebe a nossa lista de usuários
public TitulosTableModel(List<Usuario> valores) {
      this.valores = new ArrayList<Usuario>(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ó 3.
    return 3;
}

public String getColumnName(int columnIndex) {
    //Qual é o nome das nossas colunas?
    String colunas[] = {"Autor", "Título", "Senha"};
    return colunas[columnIndex];
}

public Object getValueAt(int row, int column) {
    //Precisamos retornar o valor da coluna column e da linha row.
    Usuario u = valores.get(row);
    if (column == COL_ID) return u.getId();
    else if (column == COL_NOME) return u.getNome();
    else if (column == COL_SENHA) return u.getSenha();
}

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ó.
    Usuario u = valores.get(row);
    if (column == COL_ID) u.setId((Integer)aValue);
    else if (column == COL_NOME) u.setNome(aValue.toString());
    else if (column == COL_SENHA) u.setNome(aValue.toString());
}

public  Class getColumnClass(int columnIndex) {
    //Qual a classe das nossas colunas? A coluna 1 é inteira, as outras string.
    if (columnIndex == COL_ID) return Integer.class;
    return String.class;
}

boolean isCellEditable(int rowIndex, int columnIndex) {
    //Indicamos se a célula da rowIndex e da columnIndex é editável. Nossa tabela toda é.
    return true;
}

public List<Usuario> getUsuarios() {
   return Collections.unmodifiableList<Usuario>(usuarios);
}

//Usuaremos esse método para adicionar um novo usuário da tabela
public void Adicionar(Usuario usuario) {
   usuarios.add(usuario);   //Adicionamos na lista
   fireTableRowsInserted(usuarios.size(), usuarios.size()); //Avisamos a tabela para repintar a linha
}

//Aqui faremos a remoção do usuário
public void Remover(Usuario usuario) {
   int index = usuario.indexOf(usuario);
   if (index == -1)  //Se o usuário não estiver na tabela
      return;           //Saimos sem fazer nada
   usuarios.remove(index);   //Caso contrário, removemos da lista
   fireTableRowsDeleted(index, index); //Repintamos a linha
}

}
[/code]

Como você usaria isso?

private UsuarioTableModel tableModel(List<Usuario> usuarios) { return new UsuarioTableModel(usuarios); }

Como obter o usuário da linha selecionada?

private Usuario getUsuarioDaLinhaSelecionada() { if (table.getSelectedRow() == -1) { return null; } Usuario u = model.getUsuarios().get(table.getSelectedRow()); }

E adicionar um novo usuario na tabela:

model.adicionar(usuario);

Note que, apesar do código do model ficar um pouco longo, ele é bem lógico, claro e fácil de fazer. E, note que o código da interface gráfica (que usa o model) fica extremamente simples, já que só trabalha com usuários. Não há necessidade de criar vectors, fazer casts, sincronizar listas. Nada disso.

Se seu trabalho é para quinta, sugiro fortemente que você use essa técnica. Vai te poupar boas horas. Depois do primeiro model pronto, basta copiar e colar para os outros. :wink:

1 curtida

Vini, boa tarde,
velho estou utilizando esta classe model para tabela, só que estou precisando definir cores nas linhas mas conforme um atributo. Como conseguiria definir esta cor utilizando esta classe de modelo.

Obrigado…

[quote=jcgmarlboro]Vini, boa tarde,
velho estou utilizando esta classe model para tabela, só que estou precisando definir cores nas linhas mas conforme um atributo. Como conseguiria definir esta cor utilizando esta classe de modelo.

Obrigado…[/quote]

Meu Deeeeus, ressucitaram o tópico! haha
Cara, você pode sobrescrever o método prepareRenderer de sua JTable e fazer essa coloração!

JTable table = new JTable( meuModelo ) {

    @Override
    public void prepareRenderer(...) {
    
        //...
    }
}

Cores é um atributo da View, não do model.

Ao invés de sobrescrever prepareRender, o ideal é criar um TableCellRenderer, e então implementar nele a mudança da cor.
A tabela escolhe o renderer através da classe retornada no getColumnClass().

Certo Vini, mas eu queria setar as cores nas linhas e não nas colunas… achei vários post teu no GUJ, estou tentanto implementar para minha necessidade.

Esse é realmente um problema sério do JTable. Ele trata por coluna. O máximo que vc pode fazer é um decorator para o cell renderer padrão, e seta-lo em todas as colunas.

Estou sem saber o q fazer =/ :shock:

vamos caçar o q possa ser feito então… o sistema tem um atributo que se for true a linha teria q ser verde, e se fosse false a linha seria vermelha… agora vem a zica =) hehehe…

ViniGodoy.
Tenho visto varios post aqui no GUJ fazendo referencia ao maleficios do DefaultTableModel, sinceramente estou tentando me livrar dele, mas existe um problema a ser considerado em tudo isto.
quem esta começando com o java, ou mesmo quem não quer perder tempo cirando no braço telas em swing, usa o editor da IDE (particularmente uso o Netbeans) e neste editor de ide, quando se arrasta a table o que vem é o nefasto DefaultTableModel.

Por exemplo eu estou tentando fazer um sort em minha table, eu populei ela com uma list que foi buscada no banco pelo hibernate. Mostrar os dados esta ok, mas a ordenação é feita como se todos os dados fossem string.

Estou trabalhando para poder fazer uma table que aceite qualquer tipo de objeto de valor (itens, pedidos, compras etc), porque não acho legal ficar criando uma tabela para cada janela que for criar. Eu realmente ja fiz isto com o componente do netbeans, mas parei no problema da ordenação.

Minha pergunta é, se eu setar um modelo próprio no componente JTable do netbeans, vou precisar implementar cada comportamento da table na mão ?

Fico no aguardo e grato pelo auxilio a todos.

valeu pedroroxd me ajudou muito…

Se sua intenção for pegar o valor de determinada linha quando esta for selecionada, seria mais ou menos assim:
Adicione no seu frame 2 jTextFields…
No evento Mouse>MouseCliqued da tabela, coloque o seguinte código:

view plaincopy to clipboardprint?
int k = jTable1.getSelectedRow();
String ID = (String) jTable1.getValueAt(k, 0);
String SEILA = (String) jTable1.getValueAt(k, 1);
jTextField1.setText(ID);
jTextField2.setText(SEILA);

Se não for isso, seja mais claro quanto a sua dúvida…
Se foi resolvido, adicione ao final do título (assunto) : [RESOLVIDO]

é isso ai muito obrigado

Pessoal, estou procurando uma solução para um erro que tenho encontrado e pode estar relacionado com este post. Pode ser coisa simples, mas não estou encontrando o motivo do problema.
Tomando como base o seguinte código:

for (Usuario usuario : usuarios) {  
                    
                  Usuario u = new Usuario();  
                    
                  Vector linha = new Vector();  
                  linha.add(u.getId());  
                  linha.add(u.getUsuario());  
                  linha.add(u.getTipo().getNomeTipo());  //Há um erro nesta linha. o Tipo é um objeto inserido pelo Hibernate no objeto Usuario.
                    
                  dados.add(linha);  
              }  

Alguem pode me clarear a mente?? Grata!!!