• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

JTable ClassCastException...

 
Ranch Hand
Posts: 201
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello. I'm constructing the JTable with two Vectors to build a table. It seems as though the rowData is causing the ClassCastException. The rowData contains only Strings. The second Vector works fine, if I set rowData as just an empty Vector.

//Vector rowData = new Vector(); this works fine
Vector rowData = aModel.getMatchingCriteria();
Iterator anIter = matches.iterator();
while( anIter.hasNext() )
{
System.out.println( ( (String) anIter.next() ) );
}
JTable table = new JTable( rowData, aModel.getColumnNames() );
System.out.println( "table is constructed" );
table.setPreferredScrollableViewportSize( new Dimension( 500, 100 ) );
TableColumn widestColumn = table.getColumnModel().getColumn(2);
widestColumn.setPreferredWidth( 150 );

I can iterate and print the contents of the Vector, however I never get to the "table is constructed" print statement. This is the exception I get if I use the rowData to construct the table:

java.lang.ClassCastException
at javax.swing.table.DefaultTableModel.justifyRows(DefaultTableModel.java:238)
at javax.swing.table.DefaultTableModel.setDataVector(DefaultTableModel.java:194)
at javax.swing.table.DefaultTableModel.<init>(DefaultTableModel.java:131)
at javax.swing.JTable.<init>(JTable.java:403)
at suncertify.client.SearchContractorWindow.buildContractorResultTable(SearchContractorWindow.java:153)
at suncertify.server.Controller$SearchButtonListener.actionPerformed(Controller.java:56)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1786)
at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(AbstractButton.java:1839)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:245)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:231)
at java.awt.Component.processMouseEvent(Component.java:5100)
at java.awt.Component.processEvent(Component.java:4897)
at java.awt.Container.processEvent(Container.java:1569)
at java.awt.Component.dispatchEventImpl(Component.java:3615)
at java.awt.Container.dispatchEventImpl(Container.java:1627)
at java.awt.Component.dispatchEvent(Component.java:3477)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3483)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3198)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3128)
at java.awt.Container.dispatchEventImpl(Container.java:1613)
at java.awt.Window.dispatchEventImpl(Window.java:1606)
at java.awt.Component.dispatchEvent(Component.java:3477)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:456)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)

Any help is greatly appreciated! Thank you all!
 
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
JTables expect to see a data structure of rows and columns. When you use a vector in the JTable constructor, this is expected to be 2-dimensional. Specifically, a Vector of Vectors (as that is what the DefaultTableModel uses/expects as its underlying storage structure - but becareful with DefaultTableModel's, because of the Vector of Vectors, you pay a penalty of synchronized access).

The requirements are shown in the API help for JTable:


JTable

public JTable(Vector rowData,
Vector columnNames)

Constructs a JTable to display the values in the Vector of Vectors, rowData, with column names, columnNames. The Vectors contained in rowData should contain the values for that row. In other words, the value of the cell at row 1, column 5 can be obtained with the following code:

((Vector)rowData.elementAt(1)).elementAt(5);

Parameters:
rowData - the data for the new table
columnNames - names of each column



With your vector only containing strings the cast illustrated above will fail. If you only have one column, you need to have a Vector (rows) of Vectors(columns) where each row Vector is of length 1 containing your string.

You can trace it through by looking at the source for JTable and DefaultTableModel:


/**
* Constructs a <code>JTable</code> to display the values in the
* <code>Vector</code> of <code>Vectors</code>, <code>rowData</code>,
* with column names, <code>columnNames</code>. The
* <code>Vectors</code> contained in <code>rowData</code>
* should contain the values for that row. In other words,
* the value of the cell at row 1, column 5 can be obtained
* with the following code:
* <p>
* <pre>((Vector)rowData.elementAt(1)).elementAt(5);</pre>
* <p>
* @param rowData the data for the new table
* @param columnNames names of each column
*/
public JTable(Vector rowData, Vector columnNames) {
this(new DefaultTableModel(rowData, columnNames));
}



and


private void justifyRows(int from, int to) {
// Sometimes the DefaultTableModel is subclassed
// instead of the AbstractTableModel by mistake.
// Set the number of rows for the case when getRowCount
// is overridden.
dataVector.setSize(getRowCount());

for (int i = from; i < to; i++) {
if (dataVector.elementAt(i) == null) {
dataVector.setElementAt(new Vector(), i);
}
((Vector)dataVector.elementAt(i)).setSize(getColumnCount());
}
}



You can see the line that fails.
 
Shannon Sims
Ranch Hand
Posts: 201
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Jason for the help and quick response. I thought I would be stuck on this problem for a while. So basically, the first Vector is a container of rows (each row is a Vector within the first Vector), correct?
 
Jason Kingsley
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yes, that is what the particular constructor for JTable is expecting. It will take the Vector and construct a DefaultTableModel with it (as can be seen:



and if you follow the codepath in DefaultTableModel (the source is included usually with your JDK installation) you'll see that it uses a Vector of Vectors and will replace its internal vector with the one passed in.

You will need to construct a Vector of columns for each row, and add that to a Vector of rows and pass that to the constructor.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic