Question

I'm presently refactoring a JTable which displays a multitude of different types of data. The primary reason for this refactoring is that there a few ClassCastExceptions (the author/friend who wrote the code is off on hiatus), and I can't seem to find where these are originating from. Due to the large codebase, I'm at a loss as to where to start. Does anyone have any suggestions? I realize and apologize for the ambiguity of this question!

I've included the stack trace below. Thanks!!

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean
    at javax.swing.JTable$BooleanRenderer.getTableCellRendererComponent(Unknown Source)
    at javax.swing.JTable.prepareRenderer(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
    at javax.swing.plaf.ComponentUI.update(Unknown Source)
    at javax.swing.JComponent.paintComponent(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JComponent.paintToOffscreen(Unknown Source)
    at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
    at javax.swing.RepaintManager.paint(Unknown Source)
    at javax.swing.JComponent._paintImmediately(Unknown Source)
    at javax.swing.JComponent.paintImmediately(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
    at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
Was it helpful?

Solution

This error which is occurring in BooleanRenderer is because it is expecting that the value that is from the table's model is of type Boolean and tries to cast to it (akf's answer has the exact line of code where it occurs).

My guess is that initially it was expected that the model would return Boolean values for the given column but at one point it is returning strings instead. Therefore, I would concentrate on what model is being used for this given table (is it a custom model? Is it the default model where it is adding values to it?) and see where it may be getting a String instead of a Boolean.

OTHER TIPS

Probably the table contains a checkbox (when the column model states that the column contains type Boolean) and the renderer tries to convert the contents into a boolean. But probably the contents are just strings. The solution is to change the data in the table or to create your own renderer.

I think the problem comes from your TableModel (jtable.getModel()) It said somewhere

(..)
public Class<?> getColumnClass(int column)
   {
   switch(column)
     {
   (...)
      case XX: return Boolean.class;
      }
   }

but the value in your model in this column is a String

public Object getValueAt(int row,int column)
  {
  (..)
   switch(column)
     {
   (...)
      case XX: return (a String);
      }
  }

To debug this problem, you may want to consider biting the bullet and putting a breakpoint in the JTable$BooleanRenderer.getTableCellRendererComponent() on the line that makes the cast

setSelected((value != null && ((Boolean)value).booleanValue()));

(from JTable.java 1.288 06/11/15)

and check the class type of value. when you find a String, you can identify the offending column and row from your model. That will at least give you a start on identifying the problem.

Sorry to dig up an old question, but I ran into this issue myself & this post came up in a search and this is what I ran into.

I had JUnits tests fail (and actually throwing runtime exceptions) but I continued to run add/removes on my JTable (in the JUnit test) which put the GUI application in a bad state, and I would see the ClassCastException come up exactly as Chris had described.

So the "fix" for me was to make sure that all unit tests catch their exceptions and return failure instead of proceeding to run more unit tests.

I had the same problem, and the cause was exactly as Avrom specified. In my case, I had the getValueAt implemented as:

@Override
synchronized public Object getValueAt(int row, int col) {
  if (row < m_rows.size()) {
    return m_rows.get(row).getValueAt(col);
  } 
  else 
  {
    return "";  // THIS IS THE BUG
  }
}

The problem here is that, is a row does not exist, a String is returned, for every column. However some of my columns has the class type, Boolean, and hence the exception:

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean
  at javax.swing.JTable$BooleanRenderer.getTableCellRendererComponent(JTable.java:5409)
  at javax.swing.JTable.prepareRenderer(JTable.java:5736)

The solution was simply to change the return value to:

return null;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top