JavaFX 8 TreeTableColumn setText ClassCastException
-
02-01-2020 - |
Question
Ma situation est la suivante :j'ai un TreeTableView
qui a un TreeTableColumn
.Le texte de l’en-tête des colonnes sera modifié lors de l’exécution.
Quand je change le texte setText
ou textProperty().bind(...)
avant de monter sur scène, tout fonctionne comme prévu.
Mais si je change le texte après avoir montré la scène, je reçois un énorme java.lang.ClassCastException
.
J'ai essayé cela avec Java SE 1.8.0 b132 et avec Java 1.8.0_20 b17 EA.
Existe-t-il une solution de contournement pour cela, à part recréer le TreeTableColumn
?
Mon exemple de code :
TreeTableView<String> ttv = new TreeTableView<>();
TreeTableColumn<String, String> ttc = new TreeTableColumn<>();
ttc.setText("Hello");
ttv.getColumns().add(ttc);
ttv.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
ttc.setText("World");
}
});
Scene scene = new Scene(ttv);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
L'Exception(après avoir cliqué sur TreeTableView
):
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:367)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:305)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:894)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:56)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:158)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.ClassCastException: javafx.scene.control.TreeTableColumn cannot be cast to javafx.scene.control.TableColumn
at com.sun.javafx.scene.control.skin.TableHeaderRow$10.invalidated(TableHeaderRow.java:277)
at javafx.beans.WeakInvalidationListener.invalidated(WeakInvalidationListener.java:83)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:339)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:143)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
at javafx.scene.control.TableColumnBase.setText(TableColumnBase.java:189)
at com.kalasch.test.TreeTableTest.start(TreeTableTest.java:39)
at com.sun.javafx.application.LauncherImpl$8.run(LauncherImpl.java:837)
at com.sun.javafx.application.PlatformImpl$7.run(PlatformImpl.java:335)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:301)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:298)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:298)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
... 1 more
Exception running application com.kalasch.test.TreeTableTest
MISE À JOUR 08/04/2014 :
Rapport de bug soumis à javafx-jira :
https://bugs.openjdk.java.net/browse/JDK-8095931
MISE À JOUR 08/05/2014 :
La version du correctif sera : 8u40
Le correctif @ thatjavaguy09 fonctionne.
Salutations, Kalsch
La solution
En parcourant la trace de la pile, il semble que le problème soit que votre TreeTableColumn tente d'être convertie en TableColumn, ce qui lève l'exception ClassCastException (puisqu'il s'agit en fait d'une conversion non valide).
Il semble que l'appel provienne de TableHeaderRow.invalidated.En regardant cette méthode, je vois d’où vient le casting.
private final InvalidationListener columnTextListener = new InvalidationListener() {
@Override public void invalidated(Observable observable) {
**TableColumn<?,?> column = (TableColumn<?,?>) ((StringProperty)observable).getBean();**
CheckMenuItem menuItem = columnMenuItems.get(column);
if (menuItem != null) {
menuItem.setText(getText(column.getText(), column));
}
}
};
Il s'agit peut-être d'un bug du JDK.Je pense que la distribution correcte devrait être vers une TableColumnBase.Je soumettrais ceci à leur bug tracker :