[Resolvido] Erro no Formatter do Object Table Model

Bom dia!

Estou utilizando o ObjectTableModel do Markyameba: http://markyameba.wordpress.com/2009/05/29/objecttablemodel/. Creio que muitos aqui devem conhecer essa classe.

No entanto, estou tendo problemas com o Formatter.

No banco de dados SQLITE tenho 5 campos DATETIME.
Quero exibir esses dados em uma JTable onde 4 (das 5 colunas correspondentes aos campos) devem ser exibidas como horas (formato HH:mm).
Mas está ocorrendo erro na formatação (mesmo sem existir campos de tipos diferentes do que DATETIME):

Código dos atributos da classe com as anotações:

    @Resolvable(colName = "Dia")
    private Date dia;

    @Resolvable(formatter = HorarioFormatter.class, colName = "entrada")
    private Date entrada;

Código do formatter:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import mark.utils.bean.Formatter;
import java.util.Date;

/**
 *
 * @author diego.queres
 */
public class HorarioFormatter implements Formatter {

    private final static SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");

    @Override
    public String format(Object obj) {

        if (obj == null || !(obj instanceof java.util.Date)) {
            return "";
        } else {
            return formatter.format(obj);
        }

    }

    @Override
    public String getName() {
        return "horário";
    }

    @Override
    public Object parse(Object s) {
        Date horario = null;
        try {
            horario = formatter.parse(s.toString());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return horario;
    }
}

Pilha de erro:

Exception occurred during event dispatching:
java.lang.IllegalArgumentException: Cannot format given Object as a Date
        at java.text.DateFormat.format(DateFormat.java:281)
        at java.text.Format.format(Format.java:140)
        at javax.swing.JTable$DateRenderer.setValue(JTable.java:5364)
        at javax.swing.table.DefaultTableCellRenderer.getTableCellRendererComponent(DefaultTableCellRenderer.java:237)
        at javax.swing.JTable.prepareRenderer(JTable.java:5720)
        at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2072)
        at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:1974)
        at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1770)
        at javax.swing.plaf.ComponentUI.update(ComponentUI.java:143)
        at javax.swing.JComponent.paintComponent(JComponent.java:752)
        at javax.swing.JComponent.paint(JComponent.java:1029)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
        at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
        at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
        at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
        at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
        at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
        at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:178)
        at java.awt.Dialog$1.run(Dialog.java:1046)
        at java.awt.Dialog$3.run(Dialog.java:1098)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.awt.Dialog.show(Dialog.java:1096)
        at java.awt.Component.show(Component.java:1563)
        at java.awt.Component.setVisible(Component.java:1515)
        at java.awt.Window.setVisible(Window.java:842)
        at java.awt.Dialog.setVisible(Dialog.java:986)
        at ponto.JFramePrincipal$3.run(JFramePrincipal.java:147)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
CONSTRUÍDO COM SUCESSO (tempo total: 5 segundos)

Voce esta usando qual versão? 2.7?

Eu reparei que deixei um erro na parte do formatter que preciso corrigir urgente, e farei o mais breve possivel.

Do modo que deixei, voce teria que fazer isso através do CellRenderer e nesse caso voce nem precisaria do Formatter.

Mas fiquei curioso, o que é exibido no campo? O valor correto? E veja qual é o conteudo do objeto que recebe no método parse, acredito que já seja um Date.

Bom dia,

Isso, é a versão 2.7.

Eu acredito que esteja ocorrendo um segundo SimpleDateFormat.format em cima do primeiro. Parece que está tentando “reformatar” a String (que já foi renderizada para o campo antes). Fiz um debug, e a exceção é disparada neste trecho da classe DateFormat:

    public final StringBuffer format(Object obj, StringBuffer toAppendTo,
                                     FieldPosition fieldPosition)
    {
        //Quando rodei o debug, verifiquei a varíavel obj. Ela já estava previamente formatada para horário e salva como String.
        //Ou seja, parece que este método esta sendo chamado de novo em cima de um valor já formatado.

        if (obj instanceof Date)
            return format( (Date)obj, toAppendTo, fieldPosition );
        else if (obj instanceof Number)
            return format( new Date(((Number)obj).longValue()),
                          toAppendTo, fieldPosition );
        else 
            throw new IllegalArgumentException("Cannot format given Object as a Date");    //Exceção que é disparada
    }

Nas linhas da tabela não é exibido nada. Depois que dispara o erro, a JTable fica sem nenhuma linha.

No método parse, eu recebo um Date normalmente.

Verifique se não houve uma confusão de java.util.Date e java.sql.Date

São classes diferentes e, dependendo do seu import, pode estar ferrando aquele instanceof ali.

Eu tentei também converter explicitamente todos os obj que entram para um novo objeto java.util.Date e acontece o mesmo problema.
Este trecho aparentemente não influiu no problema.


     @Override  
     public String format(Object obj) {  
 
         java.util.Date novaData = new java.util.Date( ((Date) obj).getTime() );
         return formatter.format(novaData);  
   
     }

Outra tentativa que fiz, para me certificar que o problema não viria daqui mesmo:


     @Override  
     public String format(Object obj) {  
 
         //Tentei esse trecho, afim de testar se o problema vinha desse trecho e nada - ocorreu a exceção da mesma forma
         java.util.Date novaData = new java.util.Date();
         return formatter.format(novaData);  
   
     }

[quote=Marky.Vasconcelos]Voce esta usando qual versão? 2.7?

Eu reparei que deixei um erro na parte do formatter que preciso corrigir urgente, e farei o mais breve possivel.

Do modo que deixei, voce teria que fazer isso através do CellRenderer e nesse caso voce nem precisaria do Formatter.

Mas fiquei curioso, o que é exibido no campo? O valor correto? E veja qual é o conteudo do objeto que recebe no método parse, acredito que já seja um Date.[/quote]

Eu consegui com o TableCellRenderer - conforme você indicou. Espero que os detalhes que passei ajudem a solucionar o problema. :smiley:

Grato!

Ajudou sim, eu descobri onde está o problema, e é relativamente facil de arrumar. O problema é que preciso de tempo.

Se eu nao conseguir durante semana nesse final de semana tenho certeza que farei.

Só pra avisar, já está corrigido.

Pode fazer o formatter do modo simples novamente.

Blz valeu (só vi agora…kkk).
Mas nas próximas vezes, vou utilizar o Formatter normalmente.