ArrayIndexOutOfBoundsException: -1 on JTable creation/tablechanged - java

I have read through all the threads out there that looked as if they could solve my problem and I've also read all the answers on here, but I'm still at my wit's end. I'm not sure why the exception is thrown, although I have a feeling this might be to do with threading. If it does, please let me know where to include the new Runnable()and whether to invokeLater() or invokeAndWait(), as I have tried it to no avail.
Please bear with me while I give you the code that leads to the exception + the stacktrace (below).
EDIT: I had included a number of sysos in the AnnoTable section just before tableChanged is called and they don't show up in the console, hence I think the problem must occur even before the application gets to that point, i.e. either when it's called from AAView or when data and table model are instantiated...
EDIT II: The problem was the overwritten tableChanged method. That would obviously fire an Exception. I've removed the tableChanged() call (which wouldn't make a difference) as well. Now I've got another problem: understanding how a change in the underlying data (AnnoData) can automatically update the table. Although this is perhaps for another query (after an extended Google search), please feel free to post helpful comments in this thread, as I'll continue reading it... THANKS A LOT for all the helpful comments and tips!
EDIT III:* I've solved the problem. I needed to instantiate another object from AnnoData, pass that to a new instance of AnnoTableModel, set this instance to my table and THEN fireTableDataChanged().
EDIT IV: Okay, so fireTableDataChanged() (as used in EDIT III) is unnecessary after all. I still would want to use it rather than creating new objects all the time. I guess I should ask a new question... Thanks!
This method in AAView should create an object extending a JTable, put it into a JScrollPane, etc. (the latter does work).
private JPanel createAnnoTablePanel() {
annoTablePanel = new JPanel();
annoTable = new AnnoTable(aameth);
setAnnoTable(annoTable);
JScrollPane scrollPane = new JScrollPane(getAnnoTable());
annoTablePanel.add(scrollPane);
return annoTablePanel;
}
Here is the class AnnoTable (aameth is an instance object containing business logic to access a data model, works fine).
public class AnnoTable extends JTable implements TableModelListener
{
public AnnoTable(AAMethods aameth)
{
int tokenCount = aameth.getTokenCount();
AnnoData annoData = new AnnoData(aameth); // cf. below, AnnoData is a Vector(Vector<Object>,String[])
TableModel tableModel = new AnnoTableModel(annoData.getAnnoData(),
// AnnoTableModel extends AbstractTableModel(Vector, String[])
annoData.getColTitles());
setModel(tableModel);
getModel().addTableModelListener(this);
TableModelEvent tme = new TableModelEvent(tableModel);
this.tableChanged(tme);
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
setCellSelectionEnabled(true);
getColumnModel().getSelectionModel().addListSelectionListener(new AnnoTableSelectionListener(this));
setPreferredScrollableViewportSize(this.getPreferredSize());
}
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int column = e.getColumn();
AbstractTableModel model = (AbstractTableModel)e.getSource();
String columnName = model.getColumnName(column);
Object data = model.getValueAt(row, column); // This is where the exception is thrown!
}
}
If you need the source code for AnnoTableModel() (which is a fairly generic extension of AbstractTableModel) or AnnoData (which constructs a Vector containing three Vector<Object> and a String[] for column titles), please let me know.
Here's the stacktrace.
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.table.DefaultTableModel.getValueAt(Unknown Source)
at package.AnnoTable.tableChanged(AnnoTable.java:52)
at javax.swing.JTable.setModel(Unknown Source)
at javax.swing.JTable.<init>(Unknown Source)
at javax.swing.JTable.<init>(Unknown Source)
at package.AnnoTable.<init>(AnnoTable.java:25)
at package.AAView.createAnnoTablePanel(AAView.java:464)
at package.AAView.createNorthPanel(AAView.java:455)
at package.AAView.displayAndAnnotate(AAView.java:444)
at package.AAView.loadProject(AAView.java:333)
at package.AAView.actionPerformed(AAView.java:286)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Actions.actionPerformed(Unknown Source)
at javax.swing.SwingUtilities.notifyAction(Unknown Source)
at javax.swing.JComponent.processKeyBinding(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processKeyBinding(Unknown Source)
at javax.swing.KeyboardManager.fireBinding(Unknown Source)
at javax.swing.KeyboardManager.fireKeyboardAction(Unknown Source)
at javax.swing.JComponent.processKeyBindingsForAllComponents(Unknown Source)
at javax.swing.JComponent.processKeyBindings(Unknown Source)
at javax.swing.JComponent.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(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)
I can see the EDT in there so from what I've learned this might really be a problem of threading. However, I don't know how to find out where I should start a new Thread (or invoke a new Runnable().
On a side note, the Exception only started appearing when I changed AnnoTable to extend JTable rather than JPanel. Originally I had AnnoTable not only construct the table but also wrap it in a scroll pane and add this to a new JPanel. But because I wanted to fireTableDataChanged from a Class that only knew of AAView (which also features a setAnnoTable() method) I wanted to do it the correct way, whereas before it worked just fine. Murphy's law?

A rowIndex of -1 (==TableModelEvent.HEADER_ROW) indicates that the model's structure has changed completely. Such an event is fired internally by the JTable on setModel. Read the api doc of TableModelEvent to fully understand which types/values to expect in the listener's tableChanged.
BTW, #AKJ is right - no need to fire any TableModelEvents in your table code. Make the model fire the events as appropriate

This means that you are passing -1 as row or column. This is not permitted - make sure you pass a correct value.

I have a feeling that your problem is here:
TableModelEvent tme = new TableModelEvent(tableModel);
this.tableChanged(tme);
->
int column = e.getColumn();
AbstractTableModel model = (AbstractTableModel)e.getSource();
String columnName = model.getColumnName(column);
Because you haven't specified a row or column value, the getColumn() and getRow() calls will return -1, which you are then passing to getValueAt().
Try looking at the constructor for TableModelEvent. It has options for specifying those row/column values.

TableModelEvent tme = new TableModelEvent(tableModel);
this.tableChanged(tme);
I don't see any need of this call. As pointed by other posters this is the cause of your problem.
If you are implementing the table model correctly, whenever you update the table model the jtable will automatically get notifications and you don't need to write the tableChanged() method as well. So I am lost why you need to call tableChanged() explicitly.
Whenever you want to update the table just update the model. Also at first glance there does not seem to be any threading issue involved.

Your AnnoTable constructor is leaking references to the incompletely constructed "this" object. Also, registering Listeners from the constructor is not safe. enter link description here
Build your objects doing the least amount of work possible in the constructor and then operate on the fully built objects. Add listeners, adjust the models, fireEvents etc...

Related

How count agents from utilities collection with specific characteristic?

There are two types of agents in my Model:
AgentA - it's a parcel which must be delivered to the DeliveryPoint. This AgentA has a corresponding parameter "DeliveryPoint".
AgentB - it's a package (an agent-container) containing parcels (AgentA). This AgentB has a parameter "DeliveryPoint" too that depends on the "DeliveryPoint" of the parcel (AgentA) delivering at the moment.
I need to count agents AgentA in the agent-container AgentB which meet the given condition:
AgentA.DeliveryPoint == AgentB.DeliveryPoint
I tried this expression:
count(agentB.contents(), p -> ((AgentA)agentB.contents()).DeliveryPoint == agentB.DeliveryPoint))
Code example:
private void _movingToDeliveryPoint_onExit_xjal( final com.anylogic.libraries.processmodeling.Delay<AgentB> self, AgentB agent ) {
traceln(count(agent.contents(), p -> ((AgentA)agent.contents()).DeliveryPoint == agent.DeliveryPoint));
}
but when I run my Model, I recieve this error in the block "Delay" ("movingToDeliveryPoint") that executes this code:
java.base/java.util.Collections$UnmodifiableList cannot be cast to smm_chain.AgentA
java.lang.ClassCastException: java.base/java.util.Collections$UnmodifiableList cannot be cast to smm_chain.AgentA
at smm_chain.sc.lambda$0(sc.java:5168)
at com.anylogic.engine.UtilitiesCollection.count(Unknown Source)
at smm_chain.sc._movingToDeliveryPoint_onExit_xjal(sc.java:5168)
at smm_chain.sc.access$25(sc.java:5163)
at smm_chain.sc$17.onExit(sc.java:2319)
at smm_chain.sc$17.onExit(sc.java:1)
at com.anylogic.libraries.processmodeling.Delay.b(Unknown Source)
at com.anylogic.libraries.processmodeling.Delay.b(Unknown Source)
at com.anylogic.libraries.processmodeling.Delay$6.onExit(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBuffer.c(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBuffer.c(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBuffer$1.onExit(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock.c(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock$1.b(Unknown Source)
at com.anylogic.libraries.processmodeling.OutPort.a(Unknown Source)
at com.anylogic.libraries.processmodeling.InPort.receiveImmediately(Unknown Source)
at com.anylogic.libraries.processmodeling.InputBlock$1.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutPort.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutPort.b(Unknown Source)
at com.anylogic.libraries.processmodeling.OutPort.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock$2.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock$2.action(Unknown Source)
at com.anylogic.libraries.processmodeling.AsynchronousExecutor_xjal.executeActionOf(Unknown Source)
at com.anylogic.engine.EventTimeout.execute(Unknown Source)
at com.anylogic.engine.Engine.b(Unknown Source)
at com.anylogic.engine.Engine.nb(Unknown Source)
at com.anylogic.engine.Engine.k(Unknown Source)
at com.anylogic.engine.Engine$a.run(Unknown Source)
Could you help me?
Thanks a lot!
You cannot use agentB.contents(). Although it looks like a good method, it is not supposed to be used by modellers.
Also, do not compare objects using ==. Use the equals() method instead.
Do this, assuming you have a population or list named myAgentsA of AgentA within AgentB:
count(myAgentsA, a->a.DeliveryPoint.equals(DeliveryPoint))
This assumes you call the code from within AgentB

readObject() is not working and breaks from method

I'd like to read different kinds of objects from file to an ArrayList, all of them are instances of class which extend the class Advertisement. I'm trying with this code:
ArrayList <Advertisement> ads = new ArrayList<Advertisement>();
ObjectInput input2 = new ObjectInputStream(
new BufferedInputStream(new FileInputStream("ads.ser")));
//break from this method at this point
ads = (ArrayList<Advertisement>) input2.readObject();
The problem is at the 3rd line/last line. It doesn't read the objects in variable ads of type ArrayList<Advertisement>, furthermore, it breaks from this method, without any messages.
Edit: Removed the try-catch block, I should have done it earlier, but I still don't know the solution. Stacktrace:
java.io.InvalidClassException: Kiado; local class incompatible: stream classdesc serialVersionUID = -1393576200767336208, local class serialVersionUID = -841663850423605586
at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at java.util.ArrayList.readObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at Main.beolvasas(Main.java:30)
at Main.startup(Main.java:57)
at Main.main(Main.java:633)
Now that you have a stack trace, the problem is clear: since the moment you serialized the objects to the file, you have made changes to the class Kiado. So the class you have now is not compatible anymore with the class as it was when serializing the objects to the file.
If you didn't change the number and the names of the fields of the class (and of all its superclasses), you can make it compatible again by just adding the following variable declaration in the class:
private static final long serialVersionUID = -1393576200767336208;
If you added, removed or renamed at least one (non-transient) field, then you might make the new class still compatible with the old one, but with more pain. And we would have to know the nature of the changes to help you.
I would personally avoid using native serialization for long-term storage because, as you just noticed, it's fragile and makes it hard to change the model. I would use a more easily readable and migratable file format: XML or JSON for example.
Do you have any code like:
catch(<WheteverException> e)
{
// nothing here
}
If so do the following:
change the // nothing here to e.printStackTrace();
remove the try/catch and only add it back if the compiler tells you to, and then only add back what exception that the compiler tells you to add (for instance don't do catch(Exception e).

How do I find an item in a JList and set that as the selected value?

When I update the JList, I want to keep the selection of what it was before updating the JList. When updating a JList, it can either remove an object or add an object.
This is what I have right now:
Object obj = list.getSelectedValue(); // This is line 47
list.clearSelection();
list.setListData(peerList);
if(obj != null)
{
int selectedIndex = list.getNextMatch(obj.toString(), 0, Position.Bias.Forward);
if(selectedIndex != -1)
list.setSelectedIndex(selectedIndex);
else
list.clearSelection();
}
But then sometimes, when an object is added or removed, it would throw an exception:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 3 >= 3
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.JList$5.getElementAt(Unknown Source)
at javax.swing.JList.getSelectedValue(Unknown Source)
at MyThread$1.run(MyThread.java:47) // I marked up top where line 47 is
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(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)
That seems to me like a concurrency issue. Are you updating the selection index and removing/adding elements all on the Event Dispatch Thread (EDT), or are you running concurrent threads that do this? You should only change the selection or modify the list on the EDT.
I figured out what my problem was. peerList is a Vector, so before this I do the adding and deleting of elements from the Vector, not the JList, though I don't know if this is possible. So if I deleted an object from the Vector and I asked to get the selected value from a JList before updating it, it wouldn't be able to find it. But the JList would still show the deleted element until you use setListData and update the JList.

Java - JTabbedPane - ArrayIndexOutOfBoundsException when adding a new panel

I have a weird problem using a JTabbedPane and adding a new tab to it.
public void addTab(String title, AbstractTab tab) {
int i = tabPanel.getTabCount();
System.out.println("Tab count:" + i);
tab.validate();
tabPanel.insertTab(title, null, tab, title, i);
tabPanel.validate();
tabPanel.setSelectedIndex(i);
}
Running this code causes the following exception:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.JTabbedPane.getTitleAt(Unknown Source)
at javax.swing.plaf.basic.BasicTabbedPaneUI$Handler.updateHtmlViews(Unknown Source)
at javax.swing.plaf.basic.BasicTabbedPaneUI$Handler.componentAdded(Unknown Source)
at java.awt.Container.processContainerEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.Container.addImpl(Unknown Source)
at javax.swing.JTabbedPane.insertTab(Unknown Source)
at View.Swing.Global.**EditorPanel.addTab(EditorPanel.java:383)**
at View.Swing.Developer.DeveloperContentPanel.showNote(DeveloperContentPanel.java:176)
at View.Swing.Developer.DeveloperTreeViewer.clickedTreeElement(DeveloperTreeViewer.java:62)
at View.Swing.Global.TreeNavigation.mouseClicked(TreeNavigation.java:556)
at java.awt.AWTEventMulticaster.mouseClicked(Unknown Source)
...
The System.out.println(..); prints
Tab count 1
The weird thing is, that this method works once, and another time it throws this exception. The added tabs are instances of the class AbstractTab, containing JTextFields, a MetaphaseEditor, scrollbars, JLabels and JTextAreas and some pictures (ImageIcon).
Does anyone know a solution for this problem?
from Bugtracker, maybe you use a component more than once?
Clarify in documentation that no 2 tabs in a JTabbedPane can have the
same component assigned to them.. causes
java.lang.ArrayIndexOutOfBoundsException: 1 > 0

Unknown source of ClassCastException (in JTables)

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

Categories

Resources