ClassCastException в JavaFX - PullRequest
       26

ClassCastException в JavaFX

0 голосов
/ 11 декабря 2018

Мой код получает следующую ошибку.

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?

1 Ответ

0 голосов
/ 11 декабря 2018

Текущий код хрупок, так как опирается на внутреннюю структуру TreeCell.Кроме того, TreeCellSkin 1 и LabeledText являются внутренними классами.Внутренний код может быть изменен без уведомления и безотносительно к сторонней зависимости от него.Поскольку это работало в Java 6, но не в Java 8, я могу только предположить, что прародитель ImageView изменился с TreeCell на Group между двумя версиями.

Чтобы это исправить, может заглянуть в реализацию и посмотреть, что вам нужно сделать, чтобы вы снова достигли TreeCell, но это не могло бы действительно решить проблему.Использование EventTarget говорит мне, что этот код был реализован, при этом не полностью понимая, как работает обработка событий в JavaFX.Исходя из очевидной цели этого кода, вы должны использовать источник события, а не цель .В JavaFX источником события всегда является объект, для которого 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 стал публичным API в JavaFX 9 вместе со многими (всеми?) Реализациями скинов.Они являются частью пакета javafx.scene.control.skin.
2.Это еще не все, но это выходит за рамки этого ответа.

...