我正在重构JTable
,它显示了大量不同类型的数据。这种重构的主要原因是有一些ClassCastExceptions
(编写代码的作者/朋友中断了),我似乎无法找到它们的起源。由于代码库很大,我不知道从哪里开始。有没有人有什么建议?我为这个问题的模棱两可而道歉并道歉!
我在下面列出了堆栈跟踪。谢谢!
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)
答案 0 :(得分:3)
BooleanRenderer
中发生的这个错误是因为它期望来自表模型的值是Boolean
类型并试图转换为它(akf的答案具有确切的行代码发生的地方)。
我的猜测是,最初预计模型会返回给定列的Boolean
值,但在某一点上它会返回字符串。
因此,我将专注于为这个给定的表使用什么模型(它是一个自定义模型吗?它是默认模型,它为它添加值吗?)并查看它可能获取字符串而不是{{ 1}}。
答案 1 :(得分:2)
该表可能包含一个复选框(当列模型声明该列包含类型Boolean时),并且渲染器尝试将内容转换为布尔值。但可能内容只是字符串。解决方案是更改表中的数据或创建自己的渲染器。
答案 2 :(得分:1)
我认为问题来自你的TableModel(jtable.getModel()) 它在某处说了
(..)
public Class<?> getColumnClass(int column)
{
switch(column)
{
(...)
case XX: return Boolean.class;
}
}
但此列中模型中的值是String
public Object getValueAt(int row,int column)
{
(..)
switch(column)
{
(...)
case XX: return (a String);
}
}
答案 3 :(得分:0)
要调试此问题,您可能需要考虑咬住子弹,并在JTable$BooleanRenderer.getTableCellRendererComponent()
上放置一个断点来进行转换
setSelected((value != null && ((Boolean)value).booleanValue()));
(来自JTable.java 1.288 06/11/15
)
并检查value
的班级类型。当您找到String
时,您可以从模型中识别出有问题的列和行。这至少可以帮助您找到问题所在。
答案 4 :(得分:0)
很抱歉找到一个老问题,但我自己也遇到了这个问题。这篇文章出现在搜索中,这就是我遇到的。
我让JUnits测试失败(并且实际上抛出了运行时异常)但我继续在我的JTable上运行添加/删除(在JUnit测试中),这使得GUI应用程序处于错误状态,我会看到ClassCastException出现正如克里斯所描述的那样。
所以对我来说,“修复”是为了确保所有单元测试都能捕获异常并返回失败而不是继续运行更多的单元测试。
答案 5 :(得分:0)
我遇到了同样的问题,其原因与Avrom指定的完全相同。就我而言,我将getValueAt
实现为:
@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
}
}
这里的问题是,对于每一列,不存在行,返回String。但是我的一些列具有类类型Boolean,因此是例外:
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)
解决方案只是将返回值更改为:
return null;