Неизвестный источник ClassCastException (в JTables)
-
13-09-2019 - |
Вопрос
В настоящее время я занимаюсь рефакторингом 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)
Решение
Эта ошибка, возникающая в BooleanRenderer
потому что он ожидает, что значение из модели таблицы имеет тип Boolean
и пытается выполнить приведение к нему (ответ akf содержит точную строку кода, где он встречается).
Я предполагаю, что изначально ожидалось, что модель вернется Boolean
значения для данного столбца, но в какой-то момент вместо этого возвращаются строки.Поэтому я бы сосредоточился на том, какая модель используется для этой таблицы (это пользовательская модель?Это модель по умолчанию, в которой она добавляет к ней значения?) и посмотрите, где она может получить строку вместо Boolean
.
Другие советы
Вероятно, таблица содержит флажок (когда модель столбца указывает, что столбец имеет тип Boolean), и средство визуализации пытается преобразовать содержимое в логическое значение.Но, вероятно, содержимое — это просто строки.Решение — изменить данные в таблице или создать свой рендерер.
Я думаю, проблема исходит из вашей TableModel (jtable.getModel()) Где-то там было сказано
(..)
public Class<?> getColumnClass(int column)
{
switch(column)
{
(...)
case XX: return Boolean.class;
}
}
но значение в вашей модели в этом столбце является строкой
public Object getValueAt(int row,int column)
{
(..)
switch(column)
{
(...)
case XX: return (a String);
}
}
Чтобы отладить эту проблему, вы можете подумать о том, чтобы стиснуть зубы и поставить точку останова в JTable$BooleanRenderer.getTableCellRendererComponent()
на линии, которая делает приброс
setSelected((value != null && ((Boolean)value).booleanValue()));
(от JTable.java 1.288 06/11/15
)
и проверьте тип класса value
.когда ты найдешь String
, вы можете определить столбец и строку, вызывающие нарушение, в вашей модели.Это, по крайней мере, даст вам возможность определить проблему.
Извините, что откопал старый вопрос, но я сам столкнулся с этой проблемой, и этот пост появился в поиске, и вот с чем я столкнулся.
У меня были сбои тестов JUnits (и фактически выбрасывались исключения во время выполнения), но я продолжал запускать добавление/удаление в моем JTable (в тесте JUnit), что приводило приложение с графическим интерфейсом в плохое состояние, и я видел, что ClassCastException возникало точно так же, как Крис описал.
Поэтому «исправление» для меня заключалось в том, чтобы убедиться, что все модульные тесты улавливают свои исключения и возвращают ошибку. вместо приступить к запуску большего количества модульных тестов.
У меня была такая же проблема, и причина была именно такой, как указал Авром.В моем случае у меня было 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
}
}
Проблема здесь в том, что если строка не существует, для каждого столбца возвращается строка.Однако некоторые из моих столбцов имеют тип класса 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;