JavaFX 中的 ClassCastException
ClassCastException in JavaFX
我的代码出现以下错误。
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: javafx.scene.Group cannot be cast to javafx.scene.control.TreeCell
源代码
private TreeItem getClickedTreeItem(EventTarget eventTarget){
TreeItem clickedTreeItem = null;
if(eventTarget instanceof TreeCellSkin){
clickedTreeItem = (TreeItem) ((TreeCell) ((TreeCellSkin)eventTarget).getParent()).getTreeItem();
}else if(eventTarget instanceof LabeledText){
clickedTreeItem = (TreeItem) ((TreeCell) ((LabeledText)eventTarget).getParent().getParent()).getTreeItem();
}else if(eventTarget instanceof ImageView){
clickedTreeItem = (TreeItem) ((TreeCell) ((ImageView)eventTarget).getParent().getParent()).getTreeItem();
}
return clickedTreeItem;
}
控制台显示这一行:
clickedTreeItem = (TreeItem) ((TreeCell) ((ImageView)eventTarget).getParent().getParent()).getTreeItem();
这是与 Java 6 一起使用的遗留代码,但使用 Java8 给出了上述异常?
现在 ClassCastException
可能是什么原因造成的,如何解决 Java8 的问题?
当前代码很脆弱,因为它依赖于 TreeCell
的内部结构。此外,TreeCellSkin
1 和 LabeledText
都是内部 类。内部代码如有更改,恕不另行通知,也不考虑第三方对它的依赖。由于这适用于 Java 6 而不是 Java 8 我只能假设 ImageView
的祖父母从 TreeCell
变为 Group
两个版本。
要解决此问题,您 可以 查看实施并了解您需要做什么才能再次达到 TreeCell
,但这不会 真的解决了问题。 EventTarget
的使用告诉我这段代码是在不完全理解事件处理在 JavaFX 中是如何工作的情况下实现的。从这段代码的明显目标来看,您应该使用事件的 source,而不是 target。在 JavaFX 中,事件源始终是 object 当前处理的 EventHandler
说 Event
添加到 2.换句话说,如果您将 EventHandler
添加到 TreeCell
,则源将是 TreeCell
。使用源,并假设 EventHandler
添加到 TreeCell
,你可以简单地做:
TreeItem<?> item = ((TreeCell<?>) event.getSource()).getTreeItem();
当然,如果您要将 EventHandler
添加到 TreeCell
,您可能不需要为源代码操心,因为您可以直接访问 TreeCell
。例如:
TreeView<String> treeView = new TreeView<>();
treeView.setCellFactory(tv -> {
TreeCell<String> cell = new TreeCell<>(); // or some custom implementation
cell.setOnMouseClicked(event -> {
TreeItem<String> item = cell.getTreeItem();
// do something with item...
});
return cell;
});
1. TreeCellSkin
在 JavaFX 9 中变成了 public API 以及许多(全部?)皮肤实现。它们是 javafx.scene.control.skin
包的一部分。
2。还有更多,但这超出了这个答案的范围。
我的代码出现以下错误。
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: javafx.scene.Group cannot be cast to javafx.scene.control.TreeCell
源代码
private TreeItem getClickedTreeItem(EventTarget eventTarget){
TreeItem clickedTreeItem = null;
if(eventTarget instanceof TreeCellSkin){
clickedTreeItem = (TreeItem) ((TreeCell) ((TreeCellSkin)eventTarget).getParent()).getTreeItem();
}else if(eventTarget instanceof LabeledText){
clickedTreeItem = (TreeItem) ((TreeCell) ((LabeledText)eventTarget).getParent().getParent()).getTreeItem();
}else if(eventTarget instanceof ImageView){
clickedTreeItem = (TreeItem) ((TreeCell) ((ImageView)eventTarget).getParent().getParent()).getTreeItem();
}
return clickedTreeItem;
}
控制台显示这一行:
clickedTreeItem = (TreeItem) ((TreeCell) ((ImageView)eventTarget).getParent().getParent()).getTreeItem();
这是与 Java 6 一起使用的遗留代码,但使用 Java8 给出了上述异常?
现在 ClassCastException
可能是什么原因造成的,如何解决 Java8 的问题?
当前代码很脆弱,因为它依赖于 TreeCell
的内部结构。此外,TreeCellSkin
1 和 LabeledText
都是内部 类。内部代码如有更改,恕不另行通知,也不考虑第三方对它的依赖。由于这适用于 Java 6 而不是 Java 8 我只能假设 ImageView
的祖父母从 TreeCell
变为 Group
两个版本。
要解决此问题,您 可以 查看实施并了解您需要做什么才能再次达到 TreeCell
,但这不会 真的解决了问题。 EventTarget
的使用告诉我这段代码是在不完全理解事件处理在 JavaFX 中是如何工作的情况下实现的。从这段代码的明显目标来看,您应该使用事件的 source,而不是 target。在 JavaFX 中,事件源始终是 object 当前处理的 EventHandler
说 Event
添加到 2.换句话说,如果您将 EventHandler
添加到 TreeCell
,则源将是 TreeCell
。使用源,并假设 EventHandler
添加到 TreeCell
,你可以简单地做:
TreeItem<?> item = ((TreeCell<?>) event.getSource()).getTreeItem();
当然,如果您要将 EventHandler
添加到 TreeCell
,您可能不需要为源代码操心,因为您可以直接访问 TreeCell
。例如:
TreeView<String> treeView = new TreeView<>();
treeView.setCellFactory(tv -> {
TreeCell<String> cell = new TreeCell<>(); // or some custom implementation
cell.setOnMouseClicked(event -> {
TreeItem<String> item = cell.getTreeItem();
// do something with item...
});
return cell;
});
1. TreeCellSkin
在 JavaFX 9 中变成了 public API 以及许多(全部?)皮肤实现。它们是 javafx.scene.control.skin
包的一部分。
2。还有更多,但这超出了这个答案的范围。