File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
The moose likes Swing / AWT / SWT and the fly likes JTable ClassCastException... Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "JTable ClassCastException..." Watch "JTable ClassCastException..." New topic

JTable ClassCastException...

Shannon Sims
Ranch Hand

Joined: Jul 03, 2003
Posts: 197
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) ) );
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:

at javax.swing.table.DefaultTableModel.justifyRows(
at javax.swing.table.DefaultTableModel.setDataVector(
at javax.swing.table.DefaultTableModel.<init>(
at javax.swing.JTable.<init>(
at suncertify.client.SearchContractorWindow.buildContractorResultTable(
at suncertify.server.Controller$SearchButtonListener.actionPerformed(
at javax.swing.AbstractButton.fireActionPerformed(
at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(
at javax.swing.DefaultButtonModel.fireActionPerformed(
at javax.swing.DefaultButtonModel.setPressed(
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(
at java.awt.AWTEventMulticaster.mouseReleased(
at java.awt.Component.processMouseEvent(
at java.awt.Component.processEvent(
at java.awt.Container.processEvent(
at java.awt.Component.dispatchEventImpl(
at java.awt.Container.dispatchEventImpl(
at java.awt.Component.dispatchEvent(
at java.awt.LightweightDispatcher.retargetMouseEvent(
at java.awt.LightweightDispatcher.processMouseEvent(
at java.awt.LightweightDispatcher.dispatchEvent(
at java.awt.Container.dispatchEventImpl(
at java.awt.Window.dispatchEventImpl(
at java.awt.Component.dispatchEvent(
at java.awt.EventQueue.dispatchEvent(
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(
at java.awt.EventDispatchThread.pumpEventsForHierarchy(
at java.awt.EventDispatchThread.pumpEvents(
at java.awt.EventDispatchThread.pumpEvents(

Any help is greatly appreciated! Thank you all!
Jason Kingsley

Joined: Feb 21, 2004
Posts: 18
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:


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:


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));


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.

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

You can see the line that fails.
Shannon Sims
Ranch Hand

Joined: Jul 03, 2003
Posts: 197
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

Joined: Feb 21, 2004
Posts: 18
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.
I agree. Here's the link:
subject: JTable ClassCastException...
It's not a secret anymore!