Sconosciuto fonte di ClassCastException (in JTables)
-
13-09-2019 - |
Domanda
Sono attualmente refactoring un JTable
che mostra una moltitudine di diversi tipi di dati. La ragione principale di questo refactoring è che c'è qualche ClassCastExceptions
(l'autore / amico che ha scritto il codice è spento in pausa), e io non riesco a trovare dove questi siano originari da. A causa della grande base di codice, sono ad una perdita quanto a dove cominciare. Qualcuno ha qualche suggerimento? Mi rendo conto e ci scusiamo per l'ambiguità di questa domanda!
Ho incluso l'analisi dello stack di seguito. Grazie !!
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)
Soluzione
Questo errore, che si sta verificando in BooleanRenderer
è perché si aspetta che il valore che è dal modello del tavolo è di tipo Boolean
e cerca di lanciare ad essa (la risposta di akf ha la linea esatta di codice in cui si verifica).
La mia ipotesi è che inizialmente ci si aspettava che il modello sarebbe tornato valori Boolean
per la colonna data, ma a un certo punto è restituire le stringhe, invece.
Pertanto, vorrei concentrarmi su quale modello viene utilizzato per questa data tabella (si tratta di un modello personalizzato? E 'il modello di default in cui si sta aggiungendo valori ad esso?) E vedere dove si può essere sempre una stringa invece di un Boolean
.
Altri suggerimenti
Probabilmente la tabella contiene una casella di controllo (quando il modello di colonna afferma che la colonna contiene tipo booleano) e il renderer prova a convertire il contenuto in un valore booleano. Ma probabilmente i contenuti sono solo stringhe. La soluzione è quella di modificare i dati nella tabella o per creare il proprio renderer.
Credo che il problema viene dal vostro TableModel (jtable.getModel ()) Ha detto che da qualche parte
(..)
public Class<?> getColumnClass(int column)
{
switch(column)
{
(...)
case XX: return Boolean.class;
}
}
, ma il valore nel modello in questa colonna è una stringa
public Object getValueAt(int row,int column)
{
(..)
switch(column)
{
(...)
case XX: return (a String);
}
}
Per eseguire il debug di questo problema, si può prendere in considerazione mordere la pallottola e mettere un punto di interruzione nella JTable$BooleanRenderer.getTableCellRendererComponent()
sulla linea che fa il cast
setSelected((value != null && ((Boolean)value).booleanValue()));
(da JTable.java 1.288 06/11/15
)
e verificare il tipo di classe di value
. quando si trova una String
, è possibile identificare la colonna incriminato e la fila dal modello. Che almeno dare un inizio su come identificare il problema.
Siamo spiacenti per scavare una vecchia questione, ma mi sono imbattuto in questo problema me stesso e questo post è venuto in una ricerca e questo è ciò che mi sono imbattuto in.
Ho avuto le prove JUnits falliscono (e in realtà gettando le eccezioni di runtime), ma ho continuato a correre aggiungere / rimuove sul mio JTable (nel test JUnit), che ha messo l'applicazione GUI in cattivo stato, e vorrei vedere il ClassCastException venire esattamente come Chris aveva descritto.
Così il "fix" per me è stato quello di fare in modo che tutti i test di unità catturano le loro eccezioni e il fallimento anziché di procedere per eseguire ulteriori test di unità tornare.
Ho avuto lo stesso problema, e la causa era esattamente come specificato Avrom. Nel mio caso, ho avuto la getValueAt
implementata come:
@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
}
}
Il problema è che, una riga non esiste, una stringa viene restituito, per ogni colonna. Tuttavia alcune delle mie colonne ha il tipo di classe, booleano, e quindi l'eccezione:
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)
La soluzione era semplicemente quello di cambiare il valore di ritorno a:
return null;