Formatar uma jTable

[quote=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)){ [/quote]

tente isso:

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

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]

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.

tá estranho hein…

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

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.

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:

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.

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

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.

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

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:

[quote=petter]Valeu mesmo, o problema de selecionar a coluna pelo boolean fico funcionando redondo.
[/quote]

Ótimo!

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

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

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!

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

Maravilha!!!
Que bom que tudo deu certo!

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

[]'s

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?

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

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?

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

Valeu cara, agora tá funcionanado legal.