Formatar uma jTable

47 respostas
P

Pessoal consigo alimentar a minha jTable com um select, até aí tudo blz. Agora pintou 3 dúvidas:
1ª) O nome das duas colunas saem com o nome do campo no banco, como eu faço para alterar esse nome?
2ª) O retorno do meu select é duas colunas agora como eu faço para a minha jTable ter 3 colunas onde as duas primeiras são alimentas pela select (o usuário não pode alterar) e a outra é um jCheckBox que pode ser editavel (selecionar) pelo usuário?
3ª)Como fazer as colunas geradas a partir do select sairem com largura já definida?
A minha jTable eu gerei no NetBeans 5 (usando matisse) e invoco ao click de um botão alguns métodos gerados por mim para alimentar essa jTable.
Olha os trechos do meu código:

//Método para carregar a jTable de dados da select    
   public void JTabela(ResultSet pStr){
      Grade.removeAll();
      try{     
           ResultSet rs = pStr;
           if (rs == null) return;
           ResultSetMetaData rsmd = rs.getMetaData();
           
           String[] col = new String[rsmd.getColumnCount()];
           for (int it = 0; it < rsmd.getColumnCount(); ++it)
                  col[it] = rsmd.getColumnLabel(it + 1);

           Vector vt = new Vector();
           while (rs.next())
           {
             Object[] row = new Object[rsmd.getColumnCount()];
             for (int it = 0; it < rsmd.getColumnCount(); it++)
               row[it] = this.getValue(rs, rsmd, it);
             vt.add(row);
           }
           Object[][] lin = (Object[][])vt.toArray(new Object[0][0]);
           Grade.setModel(new DefaultTableModel(lin,col));
           Grade.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);;
           for (int i=0;i < Grade.getColumnModel().getColumnCount();i++)
           {
             // Configurar o alinhamento das colunas
             //DefaultTableCellRenderer r = new DefaultTableCellRenderer();
             //r.setHorizontalAlignment(JLabel.RIGHT);
             //Grade.getColumnModel().getColumn(i).setCellRenderer(r);
               
             // Configurar o Tamanhos das Colunhas
             //Grade.getColumnModel().getColumn(i).setPreferredWidth(100*(i+1));
           }
           /*JCheckBox renderer = new JCheckBox();
           Grade.getColumnModel().getColumn(2).setCellRenderer(DefaultRenderer(renderer));*/
         }catch (SQLException sqle){
           JOptionPane.showMessageDialog(null,
                    "Impossível conectar com o Banco de Dados! Código do erro: " + sqle.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
         }
    }
   
   public Object getValue(ResultSet rs, ResultSetMetaData rsmd, int col) throws SQLException{
      if ((rsmd.getColumnType(col + 1) == Types.TIMESTAMP) ||
          (rsmd.getColumnType(col + 1) == Types.DATE)){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try{
                Date dt = sdf.parse(rs.getString(col+1));
                sdf = new SimpleDateFormat("dd/MM/yyyy");
                return sdf.format(dt);
              }catch (ParseException pe){
                  return new String();
              }
          }
        return rs.getObject(col +1);
    }

Código do botão para invocar a carregar a jTable:

Conexao conexao2 = new Conexao();
        try {
            conexao2.conexao();
        } catch (FileNotFoundException fnfe) {
                JOptionPane.showMessageDialog(null,
                    "Arquivo do Banco de Dados não encontrado! Código do erro: " + fnfe.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        } catch (SQLException sqle) {
                JOptionPane.showMessageDialog(null,
                    "Impossível conectar com o Banco de Dados! Código do erro: " + sqle.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        } catch (IOException ioe) {
                JOptionPane.showMessageDialog(null,
                    "Exceção do tipo IOException gerada! Código do erro: " + ioe.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        } catch (ClassNotFoundException cnfe) {
                JOptionPane.showMessageDialog(null,
                    "Exceção do tipo ClassNotFoundException gerada! Código do erro: " + cnfe.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        }
        
        if (jCheckBoxTodos.isSelected() == true || jTextFieldConsulta.getText() != null){
            JOptionPane.showMessageDialog(null,
                    "Você não pode consultar TODOS com um parâmetro NOME digitado",
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        }
        
        if (jCheckBoxTodos.isSelected() == false || jTextFieldConsulta.getText() == null){
            JOptionPane.showMessageDialog(null,
                    "Você não pode executar a consulta sem um parâmetro!",
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        }
       
        if (jCheckBoxTodos.isSelected() == true){
            conexao2.setSelect("select e.cod_cli, e.razao_soc from bebwilson.clientes e"
                               + " where e.cod_cli = " + Main.jTextFieldConsulta.getText());
            conexao2.abrirbanco();
        
        try{
            ResultSet rs = conexao2.stm.executeQuery();
            JTabela(rs);
            
        }catch(SQLException sqle){
            JOptionPane.showMessageDialog(null,
                    "Impossível conectar com o Banco de Dados! Código do erro: " + sqle.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        }

        }else{
           conexao2.setSelect("select e.cod_cli, e.razao_soc from bebwilson.clientes e");     
           conexao2.abrirbanco();

           try{
               ResultSet rs = conexao2.stm.executeQuery();
               JTabela(rs);
               
           }catch (SQLException sqle){
               JOptionPane.showMessageDialog(null,
                    "Impossível conectar com o Banco de Dados! Código do erro: " + sqle.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
           }
           
        }

47 Respostas

L

Não que eu queira ser referência absoluta para as dúvidas, mas já vi que não adiantou nada postar pra você os exemplos no outro post…
Com as classes que eu te apresentei lá dá pra fazer a maior parte disso que você precisa velho…

Pelo jeito você não gastou para ler a metade do tempo que eu gastei para escrever… e para quê

tem certas horas que me pergunto pq ainda importo tanto…

P

Olha sem querer fazer flame ou qualquer coisa do genero.

Não sei quanto tempo vc demorou para escrever o outro post mas eu gastei mais de 1 dia tentando implementar muita das coisas que vc passou, algumas funcionaram bem outras nem tanto, o resulto foi o código que postei nesse post.

Antes eu nem conseguia alimentar a jTable, agora já consigo. O fato é que não tenho tanta familiariade com Java em especial com o Swing, estou aprendendo ainda. Mas já fiz progressos.

L

petter:
Olha sem querer fazer flame ou qualquer coisa do genero.

Não sei quanto tempo vc demorou para escrever o outro post mas eu gastei mais de 1 dia tentando implementar muita das coisas que vc passou, algumas funcionaram bem outras nem tanto, o resulto foi o código que postei nesse post.

Antes eu nem conseguia alimentar a jTable, agora já consigo. O fato é que não tenho tanta familiariade com Java em especial com o Swing, estou aprendendo ainda. Mas já fiz progressos.

então tá valendo :smiley:

vou ver o q consigo por fazer pra te ajudar por aqui…

[]'s

L

Nesse trecho:

String[] col = new String[rsmd.getColumnCount()];
            for (int it = 0; it < rsmd.getColumnCount(); ++it)
                   col[it] = rsmd.getColumnLabel(it + 1);

você está montando um array com as sugestões de nome para as colunas.

se você sabe a quantidade certa de colunas (rsmd.getColumnCount() te dá a quantidade de colunas), e a ordem em que elas serão apresentadas, você pode montar um array manualmente e passar para o model de sua tabela:

supondo que rsmd.getColumnCount() = 2:

String[] col = {"Nome da Primeira Coluna", "Nome da Segunda Coluna"};

isso te resolve a primeira dúvida… :smiley:

L

Não entendi bem a 3ª dúvida? Sair já configurada de que maneira?

nesse trecho é onde você define a largura das colunas.

//Grade.getColumnModel().getColumn(i).setPreferredWidth(100*(i+1));

Você pode tirar esse trecho do laço for e definir para cada coluna individualmente:

Grade.getColumnModel().getColumn(0).setPreferredWidth(100);
Grade.getColumnModel().getColumn(1).setPreferredWidth(50);

isso pode te resolver a 3ª dúvida …

L

Ahhh… antes que me esqueça… me desculpe pela maneira como respondi lá no início velho…
É que como vi que algumas coisas que você perguntou poderiam ter sido resolvidas com aqueles exemplos, achei que você nem tivesse se dado ao trabalho de ler e tentar implementar.

:thumbup:

P

Sussu.

Valeu pelas dicas vou fazer uns testes mas pelo que vi tá funcionando legal.

P

Eu devo tá muito errado mesmo.

Agora a minha select tá dando erro. Se eu passo algum parametro ele funciona legal (alimenta a jTable) contudo se eu faço um select do tipo select * from tabela retorna fim inesperado do comando SQL. Contudo se eu faço o select direto no meu banco (Oracle) ele funciona legal (retorna todos os 80.000 registros).
Olha o código do meu botão que dispara o select:

private void jButtonConsultarActionPerformed(java.awt.event.ActionEvent evt) {                                                 
        Conexao conexao2 = new Conexao();
        try {
            conexao2.conexao();
        } catch (FileNotFoundException fnfe) {
                JOptionPane.showMessageDialog(null,
                    "Arquivo do Banco de Dados não encontrado! Código do erro: " + fnfe.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        } catch (SQLException sqle) {
                JOptionPane.showMessageDialog(null,
                    "Impossível conectar com o Banco de Dados! Código do erro: " + sqle.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        } catch (IOException ioe) {
                JOptionPane.showMessageDialog(null,
                    "Exceção do tipo IOException gerada! Código do erro: " + ioe.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        } catch (ClassNotFoundException cnfe) {
                JOptionPane.showMessageDialog(null,
                    "Exceção do tipo ClassNotFoundException gerada! Código do erro: " + cnfe.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        }
           
        if (jTextFieldConsulta.getText() != null){
            conexao2.setSelect("select e.cod_cli, e.razao_soc from bebwilson.clientes e"
                               + " where e.cod_cli = " + jTextFieldConsulta.getText());
            conexao2.abrirbanco();
        
        try{
            ResultSet rs = conexao2.stm.executeQuery();
            JTabela(rs);
            
        }catch(SQLException sqle){
            JOptionPane.showMessageDialog(null,
                    "Impossível conectar com o Banco de Dados! Código do erro: " + sqle.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
        }

        }
        if(jTextFieldConsulta.getText() == null){
           conexao2.setSelect("select e.cod_cli, e.razao_soc from bebwilson.clientes e");     
           conexao2.abrirbanco();

           try{
               ResultSet rs = conexao2.stm.executeQuery();
               JTabela(rs);
               
           }catch (SQLException sqle){
               JOptionPane.showMessageDialog(null,
                    "Impossível conectar com o Banco de Dados! Código do erro: " + sqle.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
           }
           
        }
        
//        conexao2.fecharbanco();
    }
L

é aqui q está dando erro?

if(jTextFieldConsulta.getText() == null){
            conexao2.setSelect("select e.cod_cli, e.razao_soc from bebwilson.clientes e");     
            conexao2.abrirbanco();
 
            try{
                ResultSet rs = conexao2.stm.executeQuery();
                JTabela(rs);
                
            }catch (SQLException sqle){
                JOptionPane.showMessageDialog(null,
                     "Impossível conectar com o Banco de Dados! Código do erro: " + sqle.toString(),
                     "Erro!",
                     JOptionPane.ERROR_MESSAGE);
            }
            
         }

onde você faz os testes, nos if’s…

if(jTextFieldConsulta.getText() == null)

tente substituir por isso:

if(jTextFieldConsulta.getText().equals(""))

e 

if(!jTextFieldConsulta.getText().equals(""))
P

Cara sua dica foi certeira. Eu era acostumado fazer um == null em outras linguagens e como equals() funcionou legal.

P

Só mais uma coisa, nessa minha jTable preciso imprimir as linhas que selecionei no meu jCheckBox, por exemplo, se eu selecionar 3 linhas pelo jCheckBox ele deve imprimir as 3 linhas ao pressionar o meu botão (nesse caso tem como eu pegar o número da linha?).

Já tenho a rotina para o meu impressor de códigos de barras funcionando blz. Minha dúvida é como capturar quais as linhas estão com o jCheckBox selecionado.

Consegui pegar o index da linha editada da seguinte forma:

for (int linhas = 0; linhas < Grade.getEditingRow(); linhas++){
            
        }

Se não estiver errado esse laço for vai percorrer todos as linhas editadas (selecionadas) a minha dúvida é como pegar o conteudo desses células editadas, onde cada campo (coluna) da linha eu possa atribuir a uma variável. Tem como?

L

Opa…

Não respondi ontem pois uma enxaqueca me tirou do jogo :smiley:

Vamos lá…

Tente o seguinte:

Digamos que você queira somente a segunda coluna da JTable, para as linhas selecionadas, e que o valor nesta segunda coluna é uma String.

// pega uma referência ao TableModel da sua JTable, que é onde estão os dados...
DefaultTableModel m = Grade.getModel();

// irá quardar os valores das colunas...
List<String> valores = new ArrayList<String>();

// passa por cada linha da JTable...
for(int index = 0; index < m.getRowCount(); index++){

   // digamos que a coluna que tem o JCheckBox seja a primeira...
   // o valor de um JCheckBox é representado (até onde eu sei) por um valor
   // booleano (true=selecionado)
   // vamos ver se o valor da primeira coluna é true, e se for guardamos o valor
   // que está na segunda coluna


   if((Boolean)m.getValueAt(index, 0)){
      
      // guarda o valor da segunda coluna...
      valores.add(m.getValueAt(index, 1));
   }
 
}

ao sair daqui, se tudo der certo :smiley: “values” terá todos os valores as segundas células das linhas selecionadas.

para percorrer “values” e imprimir os valores - suponha que exista um método imprimir(String s) - faça o seguinte:

for(String s : valores){

   imprimir(s);
}

qualquer coisa estamos aí…

[]'s

P

Fala…

Só voltei pro Java hoje pela manhã. Tava fazendo um ponta de Webdesigner.

O seguinte estava tentando implementar o seu código e ainda dá um erro (fiz algumas alterações conforme a minha necessidade).

private void jButtonImprimirActionPerformed(java.awt.event.ActionEvent evt) {                                                
 // pega uma referência ao TableModel da sua JTable, que é onde estão os dados...
//Aqui retirei o Default pois dava erro
 TableModel model = Grade.getModel();
 
 // irá quardar os valores das colunas...
//Preciso guardar o valor de duas colunas, por isso inclui mais 1
 List<String> valores1 = new ArrayList<String>();
 List<String> valores2 = new ArrayList<String>();
 
 // passa por cada linha da JTable...
 for(int index = 0; index < model.getRowCount(); index++){
    if((Boolean)model.getValueAt(index, 0)){
       //guarda o valor da primeira coluna...

/*Dá um erro de canot find symbol
   Symbol: method add(java.lang.Object)
   Location: interface java.util.list<java.lang.String>
  O erro ocorre nas duas linhas abaixo.*/

       valores1.add(model.getValueAt(index, 0));
       // guarda o valor da segunda coluna...
       valores2.add(model.getValueAt(index, 1));
    }
 }
 
 //Aqui virá a minha rotina de impressão.
imprimir(String, String);
    }

Outro erro, a minha rotina de imprimir recebe duas Strings e está com conflito pois está recebendo List, tentei mudar usando toString mas o erro persiste. Olha o código:

for(String s : valores1){
    valores1.toString();
    valores2.toString();
    imprimir.main(valores1, valores2);
 }

Cara eu também tenho enxaqueca, quando ataca é brabo, não dá nem animo para sair da cama. Melhoras !!!

L

Opa… valeu

Já tô melhor… deu até pra jogar um bilhar e tomar umas esse final de semana :smiley:

mas vamos lá…

tente fazer o seguinte onde dá erro:

valores1.add((String)model.getValueAt(index, 0));
valores2.add((String)model.getValueAt(index, 1));

Aqui, se você fosse imprimir apenas uma String funcionaria assim:

for(String s : valores1){

     imprimir.main(s);
}

mas como são duas, faça o seguinte:

// já que a quantidade de itens em valores1 e valores2 é a mesma, obtenho a quantidade a partir de um só

for(int index = 0; index < valores1.size(); index++){

     imprimir.main(valores1.get(index), valores2.get(index));
}

qualquer coisa poste aí…

[]'s

P

Cara o código agora compila, mas quando eu aciono o botão de imprimir dá a seguinte exceção:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.math.BigDecimal

E não imprime nada. Achei estranho pois acusa java.math.BigDecimal e estou usando somente Strings.

L

:shock:

L

Tava reparando o seguinte (não que seja a solução apra esse erro).

Se a sua primeira coluna tem um boolean (checkbox), então você não pode pegar o valor dela, tem que ser os valores da segunda e terceira colunas:

valores1.add((String)model.getValueAt(index, 1));
valores2.add((String)model.getValueAt(index, 2));

dá uma olhada nisso… se possível indique em que local o código dispara a Exception…

[]s

P

Bem a minha coluna com o boolean é a terceira.

Pelo que vi aqui a exception é disparada nesse trecho do código:

if((Boolean)model.getValueAt(index, 0)){
P

Achei esse erro, troquei o 0 por 2. Agora dá a mesma exception na linha:

valores1.add((String)model.getValueAt(index, 0));

Esse negócio tá sinistro. :lol:

L

petter:
Bem a minha coluna com o boolean é a terceira.

Pelo que vi aqui a exception é disparada nesse trecho do código:

if((Boolean)model.getValueAt(index, 0)){

tente isso:

L

Os valores retornados pelo ResultSet são todos String mesmo?
Ao montar a linha você os obtém como Object a partir do ResultSet.

Verifique isso também.

[]'s

P
Cara tem algo estranho que não consigo decifrar. Se eu deixo o código assim:
for(int index = 0; index < model.getRowCount(); index++){
    if(((Boolean)model.getValueAt(index, 2)).booleanValue()){
       //guarda o valor das colunas...
        valores1.add((String)model.getValueAt(index, 0));
        valores2.add((String)model.getValueAt(index, 1));
    }
 }
Dá o seguinte erro:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.math.BigDecimal
Na linha:
valores1.add((String)model.getValueAt(index, 0));
Agora se eu altero o código dessa maneira:
for(int index = 0; index < model.getRowCount(); index++){
    if(((Boolean)model.getValueAt(index, 2)).booleanValue()){
       //guarda o valor das colunas...
        valores1.add(model.getValueAt(index, 0).toString());
        valores2.add(model.getValueAt(index, 1).toString());
    }
 }
Dá o seguinte erro:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
Na linha: [code] if(((Boolean)model.getValueAt(index, 2)).booleanValue()){

Esse negócio empacou agora, e só falta isso para eu liberar o app.[code]

P

Verifiquei e pelo que me consta tudo está como string. Em todo caso o código do ResultSet é o seguinte:

ResultSet rs = pStr;
           if (rs == null) return;
           ResultSetMetaData rsmd = rs.getMetaData();
           
           Vector vt = new Vector();
           while (rs.next()){
             Object[] row = new Object[rsmd.getColumnCount()];
             for (int it = 0; it < rsmd.getColumnCount(); it++)
               row[it] = this.getValue(rs, rsmd, it);
             vt.add(row);
           }
           Object[][] lin = (Object[][])vt.toArray(new Object[0][0]);

//A partir daqui eu alimento a minha jTable.
L

tá estranho hein…

em que parte do programa você está atribuindo um valor booleano para a terceira coluna da JTable?

P

Quando o usuário clica em consultar na minha app ele é que escolhe quais linhas imprimir ticando na 3 coluna.

Tem algum macete para o jTable aceitar esse tique como uma edição ou algo do tipo?

Só se for isso.

L

então… só de clicar e deixar selecionado é para ele reconhecer naquele test que é feito…
Mas tá aparecendo o check numa boa aí?
É estranho ele não estar reconhecendo :stuck_out_tongue:

P

Ele aparece tranquilo.

Só por desencargo de consciência olha o código que eu gero a jTable:

public void JTabela(ResultSet pStr){
      Grade.removeAll();
        try{
           ResultSet rs = pStr;
           if (rs == null){
               JOptionPane.showMessageDialog(null,
               "Sua consulta ao Banco de Dados retornou vazia. Tente novamente.",
               "Aviso!",
               JOptionPane.WARNING_MESSAGE);
           }

           ResultSetMetaData rsmd = rs.getMetaData();

           Vector vt = new Vector();
           while (rs.next()){
             Object[] row = new Object[rsmd.getColumnCount()];
             for (int it = 0; it < rsmd.getColumnCount(); it++)
               row[it] = this.getValue(rs, rsmd, it);
             vt.add(row);
           }
           Object[][] lin = (Object[][])vt.toArray(new Object[0][0]);
           
           //Retorna aviso se não retornar nenhum cliente para o código digitado
           if (lin.length == 0){
               JOptionPane.showMessageDialog(null,
                    "Não foi encontrado cliente com este código.",
                    "Aviso!",
                    JOptionPane.WARNING_MESSAGE);
           }
           
           Grade.setModel(new DefaultTableModel(
                   lin,
                   new String [] {
                "Código", "Razão Social", "Impressão"
                }
                   )
                   {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.Boolean.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, true
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
            }
           );       
           Grade.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);         
           for (int i=0;i < Grade.getColumnModel().getColumnCount();i++){
                         
             // Configurar o Tamanhos das Colunhas individualmente
             Grade.getColumnModel().getColumn(0).setPreferredWidth(20);
             Grade.getColumnModel().getColumn(1).setPreferredWidth(340);
             Grade.getColumnModel().getColumn(2).setPreferredWidth(20);
           }

         }catch (SQLException sqle){
           JOptionPane.showMessageDialog(null,
                    "Impossível conectar com o Banco de Dados! Código: " + sqle.toString(),
                    "Erro!",
                    JOptionPane.ERROR_MESSAGE);
         }
    }
   
   public Object getValue(ResultSet rs, ResultSetMetaData rsmd, int col) throws SQLException{
      if ((rsmd.getColumnType(col + 1) == Types.TIMESTAMP) ||
          (rsmd.getColumnType(col + 1) == Types.DATE)){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try{
                Date dt = sdf.parse(rs.getString(col+1));
                sdf = new SimpleDateFormat("dd/MM/yyyy");
                return sdf.format(dt);
              }catch (ParseException pe){
                  return new String();
              }
          }
        return rs.getObject(col +1);
    }

Já não sei mas para onde correr.

L

Bom, vamos tentar fazer o seguinte:

Pelo que estou olhando, você adiciona o valor às colunas das linhas nesse trecho:

while (rs.next()){
  Object[] row = new Object[rsmd.getColumnCount()];
  for (int it = 0; it < rsmd.getColumnCount(); it++)
    row[it] = this.getValue(rs, rsmd, it);
  vt.add(row);
}

Se seu ResultSet retornar somente duas colunas, você está atribuindo valores a somente duas colunas.
A terceira, que tem como valor um Boolean está ficando sem valor.
O techo abaixo:

Class[] types = new Class [] {
     java.lang.String.class, java.lang.String.class, java.lang.Boolean.class
 };

faz com que sua JTable apresente as colunas de acordo com os valores indicados pelo método:

public Class getColumnClass(int columnIndex) {
     return types [columnIndex];
 }

mas não necessariamente ele está refletindo o que existe nas colunas.

Eu não sei te dizer com certeza se ele está criando um valor default para terceira coluna, mas
por desencargo vamos tentar o seguinte neste trecho:

while (rs.next()){
  
  // o +1 é para a coluna com valor Booleano
  Object[] row = new Object[rsmd.getColumnCount()+1];
  
  for (int it = 0; it < rsmd.getColumnCount(); it++)
    row[it] = this.getValue(rs, rsmd, it);
  
  // a coluna com vlor Booleano sempre terá valor default "false"
  row[rsmd.getColumnCount()+1] = new Boolean(false);
  vt.add(row);
}

não custa tentar né…

qualquer coisa poste aí!

[]'s

P

Tentei implementar isso (provavelmente o problema deve ser esse mesmo de ficar sem valor o boleano), mas agora dá a exception:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 3

Na linha:

row[rsmd.getColumnCount()+1] = new Boolean(false);

Eita negócio complicado.

L

ops… disfarça…

faz isso:

// a coluna com vlor Booleano sempre terá valor default "false"
row[rsmd.getColumnCount()] = new Boolean(false);

rsmd.getColumnCount() já te devolve 2 (que é o índice para a terceira coluna).
Só será necessário o “+1” lá no início mesmo, para ele adicionar 3 colunas na linha.
Agora deve funcionar, tenta aí…

[]'s

P

Valeu mesmo, o problema de selecionar a coluna pelo boolean fico funcionando redondo.

Foi só controlar o fluxo da ordem de impressão usando um Thread.sleep() que tudo ficou show de bola. Valeu mesmo.

Qualquer coisa estamos aí! :smiley:

L

petter:
Valeu mesmo, o problema de selecionar a coluna pelo boolean fico funcionando redondo.

Ótimo!

petter:
O que tá matando agora é que na função imprimir imprime só a primeira linha, se eu selecionar várias não imprime as outras.

Lá vamos nós de novo. Eita coisa que tá dando trabalho.

VAmos lá!!! :smiley:

Faça um teste, antes de chamar o método imprimir, para ver quantos registros existem em seus Lists, que são passados para alimentar o método.

Poste o código do seu método imprimir (a parte relevante).

[]'s

P

Ops. Editei o meu outro post, vi que o problema de impressão era uma limitação do meu hardware (impressora) que precisa de um “tempo” antes de receber outra requisição de impressão.

Valeu!

L

petter:
Ops. Editei o meu outro post, vi que o problema de impressão era uma limitação do meu hardware (impressora) que precisa de um “tempo” antes de receber outra requisição de impressão.

Valeu!

Maravilha!!!
Que bom que tudo deu certo!

Precisando pode entrar em contato. Qqr coisa tb entro em contato.

[]'s

P

Cara o resultado foi tão bom que agora preciso usar a mesma classe em outra app só que preciso implementar um outro processo, além das 3 colunas preciso gerar um quarta coluna com campo int que é carregado todos com 0, o porém é que clicar no jcheckBox o campo int deve ter o seu valor alterado automaticamente. Tem como capturar esse click, tentei montar algo como no click de um jButton mas não vingou. O caminho é esse mesmo?

L

Antes de começarmos, deixa eu te fazer uma pergunta (que você pode até pensar que não tem nada a ver, mas enfim, é uma curiosidade):

  • Qual valor o int deve receber quando você clica no JCheckBox?

Agora outras dúvidas mais intimamente relacionadas à questão:

  • Quando o JCheckBox está selecionado o int fica com o tal valor, e quando não está o int volta a zero? (Imagine a situação da pessoa marcando e desmarcando o JCheckBox).

bom… adicione um ListSelectionListener à sua JTable. Não exatamente à JTable, mas ao ListSelectionModel dela… algo como:

suaTable.getSelectionModel().addListSelectionListener(seuListSelectionListener);

Você vai ver, consultando a API da interface ListSelectionListener, que ela tem o método valueChanged(ListSelectionEvent evt)

implemente ele mais ou menos assim:

public void valueChanged(ListSelectionEvent evt){
        
        //Obtém o Model da JTable que foi selecionada
        ListSelectionModel lsm = (ListSelectionModel)evt.getSource();
        
        if (evt.getValueIsAdjusting())             
            return;
        
        // se houver alguma coisa selecionada
        if (!(lsm.isSelectionEmpty())) {   
            
            // aqui é onde você pode identificar qual(ais) linha(s) selecionada(s) 
           // esse método, por exemplo, identifica a última linha selecionada:
           int index = lsm.getMaxSelectionIndex()));

           // com isso em mãos você consegue modificar o valor da coluna em uma determinada linha.

           // se você estiver permitindo que várias linhas sejam selecionadas, consulte os métodos da interface 
           //ListSelectionModel para ver como identificar as várias linhas selecionadas.
      }

       // limpa a seleção
       lsm.clearSelection();
}

[]'s

P

Eu estava testando as minhas alterações, e acho que tá dando o erro em uma parte. O erro é esse:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.Integer

Seguindo a sua lógica para alimentar campos que não vem do select:

while (rs.next()){
             //O +2 é para a coluna com Booleano e coluna com Integer
             Object[] row = new Object[rsmd.getColumnCount() + 2];
             for (int it = 0; it < rsmd.getColumnCount(); it++)
               row[it] = this.getValue(rs, rsmd, it);
               //A coluna com valor Booleano sempre terá valor default "false"
               row[rsmd.getColumnCount()-1] = new Boolean(false);
               //A coluna com valor Integer sempre terá valor dafault "1"
               row[rsmd.getColumnCount()] = new Integer(1);
               
               vt.add(row);
           }

É isso mesmo ou estou fazendo alguma barbaridade?

L

se ainda está como no caso anterior, em que vêm duas do banco, é assim:

while (rs.next()){

      //O +2 é para a coluna com Booleano e coluna com Integer
      Object[] row = new Object[rsmd.getColumnCount() + 2];
      for (int it = 0; it < rsmd.getColumnCount(); it++)
           row[it] = this.getValue(rs, rsmd, it);

      //A coluna com valor Booleano sempre terá valor default "false"
      row[rsmd.getColumnCount()] = new Boolean(false);
      //A coluna com valor Integer sempre terá valor dafault "1"
      row[rsmd.getColumnCount()+1] = new Integer(1);
                
      vt.add(row);
 }

[]'s

P

Valeu cara, agora tá funcionanado legal.

L

:thumbup:

P

Editado: Tá tudo funcionando 100%.

C

Grande
Tenho uma jTable que consegui imprimi-la direto na impressora, mas gostaria de ter um cabeçalho em cada pagina, e configurar 20 linhas por pagina. Pode me ajudar. Segue código quando abro a Tabela, e quando imprimo.

[code]

package Relatorio;

import java.awt.event.ActionListener;
import java.awt.print.PrinterException;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.* ;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import utilitarios.conexao;
import javax.swing.text.MaskFormatter;

public class RelaContas extends javax.swing.JFrame
{

private static class jTable {

public jTable() {
}
}

MaskFormatter formatodatacada;
private MaskFormatter formatodata;
private MaskFormatter formatocep;
private MaskFormatter formatocnpj;
private MaskFormatter formatoie;
private MaskFormatter formatoccm;
private MaskFormatter formatoddi;
private MaskFormatter formatotelefone;


//COMANDA PRIMEIRO, PROXIMO, ANTERIOR, ULTIMO
int navega = 0 ;

//ORDENA PELO CÓDIGO
String ordenacao ="codigo";

//ORDENA PELA DATA DE VENCIMENTO
String ordenacao1 ="datavencimento";
String novo = "n";

conexao contas;
private ActionListener ActionListener;

public RelaContas()
{
initComponents();
contas = new conexao();
contas.conecta();
contas.executeSQL("select * from Contas order by "+ordenacao1);
try
{
contas.executeSQL("select * from Contas order by posicaoconta");
preencher_jtable();
contas.executeSQL("select * from Contas order by codigo");
contas.resultset.last();
mostrardados();

}
catch(SQLException erro)
{
JOptionPane.showMessageDialog(null,"BANCO DE DADOS NÃO ENCONTRADO, VERIFIQUE O ERRO");
}
}
public void mostrardados()
{
//try
{
//MOSTRA DATA NO FORMULÁRIO
Date data = new Date();
String dia = "" + data.getDate();
String mes = "" + String.valueOf(data.getMonth()+1);
String ano = "" + (1900 + data.getYear());
if (Integer.parseInt(dia)<=9)
dia = "0" + dia;
if (Integer.parseInt(mes)<=9)
mes = "0" + mes;
datacada.setText(dia+"/"+mes+"/"+ano);
datacada.setEditable(false);

//MOSTRA HORA NO FORMULÁRIO
Date hora = new Date();
String thora ="" + data.getHours();
String tminuto=""+ data.getMinutes();
String tsegundo=""+ data.getSeconds();
if (Integer.parseInt(tminuto)<=9)
tminuto = "0" + tminuto;
if (Integer.parseInt(tsegundo)<=9)
tsegundo = "0" + tsegundo;
horacada.setText(thora+":"+tminuto+":"+tsegundo);
horacada.setEditable(false);

//DESABILITA O X NO FORMULÁRIO
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

}
}

public void preencher_jtable()
{
DefaultTableCellRenderer esquerda = new DefaultTableCellRenderer();
DefaultTableCellRenderer centro = new DefaultTableCellRenderer();
DefaultTableCellRenderer direita = new DefaultTableCellRenderer();

esquerda.setHorizontalAlignment(SwingConstants.LEFT);
centro.setHorizontalAlignment(SwingConstants.CENTER);
direita.setHorizontalAlignment(SwingConstants.RIGHT);

//CODIGO
jTable.getColumnModel().getColumn(0).setCellRenderer(centro);
//DATAVENCIMENTO
jTable.getColumnModel().getColumn(1).setCellRenderer(centro);
//FORNECEDOR
jTable.getColumnModel().getColumn(2).setCellRenderer(esquerda);
//VALOR
jTable.getColumnModel().getColumn(3).setCellRenderer(direita);
//PISIÇÃO CONTA
jTable.getColumnModel().getColumn(4).setCellRenderer(esquerda);
//CODIGO DE BARRAS
jTable.getColumnModel().getColumn(5).setCellRenderer(esquerda);

//CODIGO
jTable.getColumnModel().getColumn(0).setPreferredWidth(10);
//DATA VENCIMENTO
jTable.getColumnModel().getColumn(1).setPreferredWidth(15);
//FORNECEDOR
jTable.getColumnModel().getColumn(2).setPreferredWidth(200);
//VALOR
jTable.getColumnModel().getColumn(3).setPreferredWidth(30);
//POSIÇÃO CONTA
jTable.getColumnModel().getColumn(4).setPreferredWidth(20);
//CODIGO DE BARRAS
jTable.getColumnModel().getColumn(5).setPreferredWidth(220);

DefaultTableModel modelo = (DefaultTableModel)jTable.getModel();
modelo.setNumRows(0);
try
{
while(contas.resultset.next())
{
modelo.addRow(new Object[]
{
contas.resultset.getString("codigo"),
contas.resultset.getString("datavencimento"),
contas.resultset.getString("fornecedor"),
contas.resultset.getString("valor"),
contas.resultset.getString("posicaoconta"),
contas.resultset.getString("codigobarras"),
}
);
}
}
catch(SQLException erro)
{
}
}

private void btsairActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
//if(javax.swing.JOptionPane.showConfirmDialog(null,"DESEJA FECHAR ESTE FORMULÁRIO ?","SAIR",javax.swing.JOptionPane.YES_NO_OPTION )==0)
//this.dispose();
//new Cadastro.CadastroDeContas().show();
Object[] options =
{
"Sim", "Não"
};
int i = JOptionPane.showOptionDialog(null,
"DESEJA FECHAR ESTE FORMULÁRIO ?","SAIR",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (i == JOptionPane.YES_OPTION)
{
//System.exit(0);
this.dispose();
new Cadastro.CadastroDeContas().show();
}
}

private void btimprimirActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
{
try
{
jTable.print();
}
catch (PrinterException ex)
{
Logger.getLogger(RelaContas.class.getName()).log(Level.SEVERE, null, ex);
}
}
DefaultTableModel modelo = (DefaultTableModel)jTable.getModel();
modelo.setNumRows(0);
try
{
while(contas.resultset.next())
{
modelo.addRow(new Object[]
{
contas.resultset.getString("codigo"),
contas.resultset.getString("datavencimento"),
contas.resultset.getString("fornecedor"),
contas.resultset.getString("valor"),
contas.resultset.getString("posicaoconta"),
contas.resultset.getString("codigobarras"),
}
);
}
}
catch(SQLException erro)
{
}
this.dispose();
new Relatorio.RelaContas().show();
}

G

Luiz_Gustavo:
Nesse trecho:
se você sabe a quantidade certa de colunas (rsmd.getColumnCount() te dá a quantidade de colunas), e a ordem em que elas serão apresentadas, você pode montar um array manualmente e passar para o model de sua tabela:

Eu preciso saber como faço para não permitir que o usuário altere a ordem das colunas. Alguém aí faz ideia de como se faz isso?

G

Gustavo Zub:
Luiz_Gustavo:
Nesse trecho:
se você sabe a quantidade certa de colunas (rsmd.getColumnCount() te dá a quantidade de colunas), e a ordem em que elas serão apresentadas, você pode montar um array manualmente e passar para o model de sua tabela:

Eu preciso saber como faço para não permitir que o usuário altere a ordem das colunas. Alguém aí faz ideia de como se faz isso?

Opa, já descobri…

jTable.getTableHeader().setReorderingAllowed(false);
N

Boa noite a todos, nao conheco muito de java e estou trabalhando com uma jtable, estou com o seguinte problema.
Preciso alterar a largura das colunas da tabela, nao pode ser no geral para cada classe vai ser uma tabela diferente. Ex tabela cliente codigo (20), nome(50), cidade (50), telefone(50).
ja a tabela pecas codigo(20), descrição(50), quantidade(20), valor(20).
Como posso fazer isso???

desde ja agradeço pela atenção.
ja posto os codigos.

N

codigos da tabela.

package Extra;

import java.util.Vector;

import java.util.Comparator;

import java.util.Collections;
import javax.swing.table.DefaultTableModel;

import javax.swing.table.TableColumnModel;

import javax.swing.table.JTableHeader;

import javax.swing.event.TableModelEvent;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.awt.event.InputEvent;

import javax.swing.JTable;

public class TablePrincipalModel extends DefaultTableModel implements Comparator{

protected   int         currCol;
protected   Vector      ascendCol;  // this vector stores the state (ascending or descending) of each column
protected   Integer     one         = new Integer(1);
protected   Integer     minusOne    = new Integer(-1);
protected   Vector colEditable = new Vector() ;
protected   Vector cellLocked = new Vector();

public TablePrincipalModel() {
    super();
    ascendCol = new Vector();
}
public TablePrincipalModel(Object[][] data, Object[] titles) {
    super(data,titles);
    ascendCol = new Vector();
    for (int i = 0; i < titles.length; i++)
        colEditable.add(new Boolean(false));
    
    
}

 public Class getColumnClass(int c) {
    //return getValueAt(0, c).getClass();
    
    
    //Para evitar erro de null, procurando em todos as linhas
    for (int i=0; i < this.getRowCount(); i++) {
        if (getValueAt(i, c) != null)
            return getValueAt(i, c).getClass();
    }
    //Se todas estao vazias, retornar como tipo String
    String ret = "";
    return ret.getClass();
    
} 
 
 public void limpaVectorCellNotEditable(){
    cellLocked.removeAllElements();
 }
 
 public void setColEditable(int col, boolean editable) { //Anderson criou
    colEditable.set(col, new Boolean(editable));
 }
 
 public void setCellNotEditable(int col, int row) { //FT criou
     cellLocked.add(new Cell(row,col));
 }
 
/*
 * Don't need to implement this method unless your table's
 * editable.
 */
public boolean isCellEditable(int row, int col) {
    if (cellLocked.size() > 0) {
        Cell cellTest;
        for (int i=0; i < cellLocked.size(); i ++) {
            cellTest =(Cell)cellLocked.get(i);
            if (cellTest.row == row && cellTest.col == col)
                return false;
        }
    }
    return ((Boolean)colEditable.get(col)).booleanValue();
}

/*******************************************************************
 * addColumn methods are inherited from the DefaultTableModel class.
 *******************************************************************/

public void addColumn(Object columnName) {
    super.addColumn(columnName);
    ascendCol.add(one);
    colEditable.add(new Boolean(false));
}

public void addColumn(Object columnName, Object[] columnData) {
    super.addColumn(columnName, columnData);
    ascendCol.add(one);
}

public void addColumn(Object columnName, Vector columnData) {
    super.addColumn(columnName, columnData);
    ascendCol.add(one);
}

/*****************************************************************
 * This method is the implementation of the Comparator interface.
 * It is used for sorting the rows
 *****************************************************************/
public int compare(Object v1, Object v2) {

    // the comparison is between 2 vectors, each representing a row
    // the comparison is done between 2 objects from the different rows that are in the column that is being sorted

    int ascending = ((Integer) ascendCol.get(currCol)).intValue();
    if (v1 == null && v2 == null) {
        return 0;
    } else if (v2 == null) { // Define null less than everything.
        return 1 * ascending;
    } else if (v1 == null) {
        return -1 * ascending;
    }

    Object o1 = ((Vector) v1).get(currCol);
    Object o2 = ((Vector) v2).get(currCol);

    // If both values are null, return 0.
    if (o1 == null && o2 == null) {
        return 0;
    } else if (o2 == null) { // Define null less than everything.
        return 1 * ascending;
    } else if (o1 == null) {
        return -1 * ascending;
    }

    if (o1 instanceof Number && o2 instanceof Number) {
        Number n1 = (Number) o1;
        double d1 = n1.doubleValue();
        Number n2 = (Number) o2;
        double d2 = n2.doubleValue();

        if (d1 == d2) {
            return 0;
        } else if (d1 > d2) {
            return 1 * ascending;
        } else {
            return -1 * ascending;
        }

    } else if (o1 instanceof Boolean && o2 instanceof Boolean) {
        Boolean bool1 = (Boolean) o1;
        boolean b1 = bool1.booleanValue();
        Boolean bool2 = (Boolean) o2;
        boolean b2 = bool2.booleanValue();

        if (b1 == b2) {
            return 0;
        } else if (b1) {
            return 1 * ascending;
        } else {
            return -1 * ascending;
        }

    } else {
        // default case
        if (o1 instanceof Comparable && o2 instanceof Comparable) {
            Comparable c1 = (Comparable) o1;
            Comparable c2 = (Comparable) o2; // superflous cast, no need for it!

            try {
                return c1.compareTo(c2) * ascending;
            } catch (ClassCastException cce) {
                // forget it... we'll deal with them like 2 normal objects below.
            }
        }

        String s1 = o1.toString();
        String s2 = o2.toString();
        return s1.compareTo(s2) * ascending;
    }
}

/***************************************************************************
 * This method sorts the rows using Java's Collections class.
 * After sorting, it changes the state of the column -
 * if the column was ascending, its new state is descending, and vice versa.
 ***************************************************************************/
public void sort() {
    Collections.sort(dataVector, this);
    Integer val = (Integer) ascendCol.get(currCol);
    ascendCol.remove(currCol);
    if(val.equals(one)) // change the state of the column
        ascendCol.add(currCol, minusOne);
    else
        ascendCol.add(currCol, one);
}

public void sortByColumn(int column) {
    this.currCol = column;
    sort();
    fireTableChanged(new TableModelEvent(this));
}

// Add a mouse listener to the Table to trigger a table sort
// when a column heading is clicked in the JTable.
public void addMouseListenerToHeaderInTable(JTable table) {
    final TablePrincipalModel sorter = this;
    final JTable tableView = table;
    tableView.setColumnSelectionAllowed(false);
    MouseAdapter listMouseListener = new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
            TableColumnModel columnModel = tableView.getColumnModel();
            int viewColumn = columnModel.getColumnIndexAtX(e.getX());
            int column = tableView.convertColumnIndexToModel(viewColumn);
            if (e.getClickCount() == 1 && column != -1) {
                int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK;
                boolean ascending = (shiftPressed == 0);
                
                //sorter.sortByColumn(column);
                sorter.sortByColumn(column);
            }
        }
    };
    JTableHeader th = tableView.getTableHeader();
    th.addMouseListener(listMouseListener);
}
}

class Cell {

int row;

int col;

public Cell(int i_row, int i_col) {

row = i_row;

col = i_col;

}

}
N

Aqui eu chamo a tabela…

public class Cliente extends javax.swing.JFrame {

TablePrincipalModel tmCliente = new TablePrincipalModel(null, new String[]{"Código","Nome","Cidade","Telefone Residencial"});

// DefaultTableModel tmCliente = new DefaultTableModel(null, new String[]{“Código”,“Nome”,“Cidade”,“Telefone Residencial”});
ListSelectionModel lsmCliente;

List<Cliente_Bean> clientes;

List<Cidade_Bean> cidade;
String tipoCadastro;
private String tipo_consulta
Criado 28 de junho de 2006
Ultima resposta 24 de nov. de 2013
Respostas 47
Participantes 5