RSS

Tutorial sobre JTable do Swing – parte I

23 nov

 

            Com esse tutorial voce aprenderá a criar desde uma JTable simples, até uma complexa, utilizando as princpais classes ( editor, renderer, model, etc ). Este tutorial estará subdividindo em diversos capitlos, aumentando sua complexidade a medida que entrarmos em um novo capítulo. CAPITULO 1 – Construindo uma JTable Simples Introdução: A classe JTable é utilizada para vizualizar dados em grid no Swing e é um dos componentes mais complexos desse pacote. Alias o JTable possui até um pacote especial, que contém diversas classes para sua utilização: javax.swing.table. A JTable é um componente MVC: o seu trabalho é dividido em 3 partes: Model: É a parte que cuida dos dados, quem controla e distribui os dados na jtable. É implementado pela interface TableModel ( AbstractTableModel e DefaultTableModel ). Ela é responsavel por fornecedor os dados para a tabela, a qual requisitará os dados atraves do método getValueAt, informando a linha e a coluna. Este método retorna um Object, ou seja, um objeto qualquer, que pode ser um Integer, uma String ou uma outra classe que você tenha implementado. View: É a parte que cuida da apresentação. É implementado pela interface CellRenderer. É como a apresentação é dada celula a celula na tabela, o renderer deve ser fornecedido para uma celula especifica. Na Jtable é possivel fornecer tanto um renderer para a tabela inteira como para uma coluna especifica. Assim como na tablemodel requisitará o valor na linha e coluna especifica, aqui ele requisitara o objeto que ira apresentar o dados, passando como parametro a linha, a coluna o valor (object), a tabela (jtable), se esta celula esta selecionada e se ela celula possui o foco. Este método é o getCellRendererComponent, que irá retornar um JComponent. O DefaultCellRenderer implementa o JLabel para apresentar os dados, que é a forma de apresentação mais comum para um valor. Controller: É a parte que controla a apresentação dos dados na view. É a própria JTable. Como a JTable ja vem implementada para usar os tipos defaults existentes e implementados, para criar uma jtable simples não é tão complicado. O unico problema é que voce acaba se engessando quando precisar de algum recurso mais "completo".

Criando uma JTable

Vamos agora conhecer uma forma de contruir uma JTable, simplesmente fornecedor os dados que quero exibir nela.

 

  1. String[] colunas = new String []{"Estado","Cidade"}; 
  2. String[][] dados = new String [][] { 
  3.        {"SP","Sao Paulo"}, 
  4.        {"RJ","Rio de Janeiro"}, 
  5.        {"RN","Rio Grande do Norte"}, 
  6.        {"PR","Parana"} 
  7. }; 
  8.  
  9. JTable jtable = new JTable(dados, colunas);   

String[] colunas = new String []{"Estado","Cidade"}; String[][] dados = new String [][] { {"SP","Sao Paulo"}, {"RJ","Rio de Janeiro"}, {"RN","Rio Grande do Norte"}, {"PR","Parana"} }; JTable jtable = new JTable(dados, colunas);
O exemplo acima cria uma instância da classe JTable passando como argumentos as variáveis dados e colunas. Existem diversos contrutores para a JTable, e um deles é a passagem de arrays (linhas e colunas) como argumentos. Este é o modo mais simples de fornecer à JTable os dados que deseja exibir. Ela utliza toda a estrutura default para exibição deste codigo.  Trabalhando com a JTable: DefaultTableModel()Tendo nossa JTable criada, podemos trabalhar em cima do modelo (TableModel) que ela criou. Para obtermos o modelo dessa JTable criada, basta chamarmos o método getModel() que retorna uma instância de classe que implementa o TableModel. Como o argumento para criação de nossa JTable foi uma coleção, o modelo utilizado internamente foi o DefaultTableModel. O DefaultTableModel é uma classe de javax.swing.table e implementa a interface TableModel, fornecedo-nos todo o controle dos dados da JTable. Claro que é uma classe com métodos básicos para trabalhar com os dados da JTable. – getValueAt(): obtem o valor de uma determinada linha e coluna na JTable. – setValueAt(): seta o valor em uma determinada linha e coluna na JTable. – addRow(): adiciona uma nova linha na JTable. Recebe um array simples. – addColumn(): adiciona uma nova coluna no modelo. Com base no exemplo anterior, digamos que seria necessario adicionar outras linhas apos a criação da nossa JTable. Vamos alterar nosso codigo para tirarmos o peso de controlar os dados da própria JTable e jogar esse trabalho pro DefaultTableModel:

 

  1. String[][] dados = new String [][]{ 
  2.               {"SP","Sao Paulo"}, 
  3.               {"RJ","Rio de Janeiro"}, 
  4.               {"RN","Rio Grande do Norte"}, 
  5.               {"PR","Parana"} 
  6. }; 
  7. String[] colunas = new String []{"Estado","Cidade"}; 
  8. // Ao inves de passar direto, colocamos os dados em um modelo
  9. DefaultTableModel modelo = new DefaultTableModel(dados, colunas); 
  10. // e passamos o modelo para criar a jtable
  11. JTable jtable = new JTable( modelo ); 

String[][] dados = new String [][]{ {"SP","Sao Paulo"}, {"RJ","Rio de Janeiro"}, {"RN","Rio Grande do Norte"}, {"PR","Parana"} }; String[] colunas = new String []{"Estado","Cidade"}; // Ao inves de passar direto, colocamos os dados em um modelo DefaultTableModel modelo = new DefaultTableModel(dados, colunas); // e passamos o modelo para criar a jtable JTable jtable = new JTable( modelo );
O que fizemos foi pegar as colunas e os dados, e jogá-los em alguém para cuidar deles: no caso um TableModel, que é o responsavel por controlar os dados de uma JTable. Agora que criamos uma JTable passando um TableModel que controla os dados, podemos trabalhar em cima desse modelo. Uma coisa que devemos ter em mente é sempre saber que modelo tal JTable está usando, pois assim podemos pega-lo de volta e trabalhar em cima dele. – addRow() Digamos que, na nossa tela, colocamos um novo botão para incluir novas linhas nessa minha JTable. E para tal, criamos o método adicionaLinha(), chamado pelo ActionPerformed deste botão. Este método irá obter o nosso modelo, quem controla os dados, e incluirá uma nova linha em branco.

 

  1. /**
  2. * Método para adicionar uma nova linha na JTable
  3. */
  4. public void adicionaLinha() { 
  5. // Obtem o modelo da JTable
  6. DefaultTableModel modelo = (DefaultTableModel)getTabela().getModel(); 
  7. // Adiciona uma nova linha em branco no modelo
  8. modelo.addRow( new String [] {"", ""} ); 

/** * Método para adicionar uma nova linha na JTable */ public void adicionaLinha() { // Obtem o modelo da JTable DefaultTableModel modelo = (DefaultTableModel)getTabela().getModel(); // Adiciona uma nova linha em branco no modelo modelo.addRow( new String [] {"", ""} ); }
– removeRow() A mesmo coisa poderia ser feito se quisermos deletar uma determinada linha. Digamos que vamos excluir a linha atualmente selecionada. Para saber qual linha está selecionada, devemos perguntar a JTable, que é o controlador. O método utilizado é o getSelectedRow() e retorna um int, a linha selecionada. Se nao houver linhas selecionadas, o retorno é -1.

 

  1. /**
  2. * Remove a linha do modelo.
  3. * @param linha
  4. */
  5. public void removeLinha(int linha){ 
  6.  
  7. // Obtem o modelo da JTable
  8.     DefaultTableModel modelo = (DefaultTableModel)getTabela().getModel(); 
  9.  
  10. // Remove a linha
  11.     modelo.removeRow(linha); 
  12.  
  13.  
  14. /**
  15. * Obtem a linha selecionada e chama o método para remover
  16. * do modelo
  17. */
  18. public void removeLinha(){ 
  19.  
  20. // Obtem a linha selecionada na tabela e chama o método
  21. // para excluir a linha
  22. int linhaSelecionada = getTabela().getSelectedRow(); 
  23.  
  24. // Verificamos se existe realmente alguma linha selecionada
  25. if( linhaSelecionada < 0 ){ 
  26. return; 
  27.     }else{ 
  28. // Remove a linha do modelo
  29.         removeLinha(linhaSelecionada); 
  30.     } 
  31.  
  32.  

/** * Remove a linha do modelo. * @param linha */ public void removeLinha(int linha){ // Obtem o modelo da JTable DefaultTableModel modelo = (DefaultTableModel)getTabela().getModel(); // Remove a linha modelo.removeRow(linha); } /** * Obtem a linha selecionada e chama o método para remover * do modelo */ public void removeLinha(){ // Obtem a linha selecionada na tabela e chama o método // para excluir a linha int linhaSelecionada = getTabela().getSelectedRow(); // Verificamos se existe realmente alguma linha selecionada if( linhaSelecionada < 0 ){ return; }else{ // Remove a linha do modelo removeLinha(linhaSelecionada); } }
– ListSeleciont Trabalhar com seleção de linhas e colunas na JTable tambem é um trabalho a parte. Existem métodos para obter nao só a linha, mas o numero de linhas selecionadas, as linhas selecionadas ( que retorna um array de int[] ). Assim como as linhas, os mesmos métodos se encontram para obter as colunas seleciondas. Vale a pena dar uma olhada na API da JTable para conferir estes métodos. Para setar o modo de seleção no qual sua JTable irá trabalahar, vamos permitir somente a seleção de linhas ( unicas ) e nao multiplas.

 

  1. .setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 

.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
– getValueAt e setValueAt Em algum ponto de sua aplicação, voce pode querer substituir o conteúdo de uma celula, ou de várias linhas em uma determinada coluna. Com os métoso getValueAt e setValueAt podemos obter e setar o valor em uma determinada coluna e linha. Vamos criar um método para subtituir um determinado valor por outro, em uma coluna especifica.

 

  1. /**
  2. * Método para subtituir um valor por outro em uma determinada
  3. * coluna.
  4. * @param oldValue
  5. * @param newValue
  6. * @param column
  7. * @return Numero de substituições
  8. */
  9. public int substituirValor(String oldValue, String newValue, int column){ 
  10. // Flag para saber se algum valor foi
  11. int total = 0; 
  12. // Obtem o modelo da JTable
  13.     DefaultTableModel modelo = (DefaultTableModel)getTabela().getModel(); 
  14. // Faz um looping em cima das linhas do modelo
  15. for( int linha=0; linha<modelo.getRowCount(); linha++){ 
  16. // Obtem o valor atual na coluna
  17.         String valorAtual = (String)modelo.getValueAt(linha, column); 
  18. if( valorAtual.equals(oldValue) ){ 
  19. // Substitui pelo novo valor na linha e coluna
  20.             modelo.setValueAt(newValue, linha, column); 
  21. // Adiciona mais um no numero de linhas atualizadas        
  22.             total++; 
  23.         } 
  24.     } 
  25. return total; 

/** * Método para subtituir um valor por outro em uma determinada * coluna. * @param oldValue * @param newValue * @param column * @return Numero de substituições */ public int substituirValor(String oldValue, String newValue, int column){ // Flag para saber se algum valor foi int total = 0; // Obtem o modelo da JTable DefaultTableModel modelo = (DefaultTableModel)getTabela().getModel(); // Faz um looping em cima das linhas do modelo for( int linha=0; linha<modelo.getRowCount(); linha++){ // Obtem o valor atual na coluna String valorAtual = (String)modelo.getValueAt(linha, column); if( valorAtual.equals(oldValue) ){ // Substitui pelo novo valor na linha e coluna modelo.setValueAt(newValue, linha, column); // Adiciona mais um no numero de linhas atualizadas total++; } } return total; }
Poderiamos ter utilizado o Iterator para trabalhar em cima dos dados, basta obter o iterator do vetor de linhas dos dados retornado pelo modelo e obter os valor por meio de array de strings.

 

  1. Iterator i = modelo.getDataVector().iterator(); 
  2. String [] row = i.next(); 

Iterator i = modelo.getDataVector().iterator(); String [] row = i.next();

Implementando meu próprio TableModel

Para implementar o TableModel, existem diversos pontos que devemos cobrir – devemos tratar o controle dos dados ( colunas e linhas ). Uma opção simples para começarmos, será a de estender a classe AbstractTableModel que fornece diversos métodos já sobrescritos exceto aqueles que retornam dados: – public Object getValueAt( int row, int col ) – public int getRowCount() – public int getColumnCount() Esta classe também já implementa 7 métodos de atualização da JTable ( TableModelEvents ). Estes métodos são utilizados para informar as alterações ocorridas dentro de um modelo. Exemplo seria a inclusão de uma nova linha, que dispara o método fireTableRowsInserted. Durante a criação dos métodos para trabalhar com os dados, iremos ver estes eventos. Mas este assunto vamos tratar na próxima parte do artigo. Até lá!

Anúncios
 
Deixe um comentário

Publicado por em 23/11/2009 em Estudos Java

 

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

 
%d blogueiros gostam disto: