更改项目类型时,在JavaFX中使用listview的ClassCastException

时间:2018-01-13 20:19:25

标签: java listview javafx classcastexception

我正在处理应用程序的表示层,并且遇到了JavaFX的“listview”的一些问题。

在应用程序的GUI中,我打算使用一个listview元素来交替(从不同时)显示两个不同对象的列表:“Group”类型的对象和“Expenditure”类型的对象。

当用户想要查看所有组的列表时,会调用以下函数(此处简化):

 private void loadGroups(){

     List<Group> groups = getGroups();
     ObservableList<Group> ol = FXCollections.observableList( (List<Group>)groups );
     myListView.setCellFactory( new Callback<ListView<Group>, ListCell<Group>>() {
        @Override
        public ListCell<Group> call(ListView<Group> listView) {
            return new GroupCell();
        }
     });
     myListView.setItems(ol);
     myListView.setOnMouseClicked(...);

 }

双击组时,将执行以下代码,目的是在同一ListView上显示与该组相关的所有支出对象:

 private void loadGroups(){

     List<Expenditure> expenditures = getExpenditures();
     ObservableList<Expenditure> ol = FXCollections.observableList( (List<Expenditure>)expenditures );
     myListView.setCellFactory( new Callback<ListView<Expenditure>, ListCell<Expenditure>>() {
        @Override
        public ListCell<Expenditure> call(ListView<Expenditure> listView) {
            System.out.println("updateView() called for expenditures.................");
            return new ExpenditureCell();
        }
     });
     myListView.setItems(ol);
     myListView.setOnMouseClicked(...);

 }

GroupCell和ExpenditureCell对象根据以下模式覆盖updateItem方法(我将只显示GroupCell对象的overriden方法):

@Override
protected void updateItem(Group group, boolean empty) {

    super.updateItem(group, empty);

    if (empty){
        setGraphic(null);
    }else{
        GroupCellController groupCellController = new GroupCellController();
        groupCellController.setGroupInfo(group);
        setGraphic(groupCellController.getAnchorPane());
        //addEventFilter(MouseEvent.MOUSE_PRESSED, eve);
    }

}

如果用户首先查看组列表,然后决定查看支出列表,则会发生以下错误:

  Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: DATA.Model.Expenditure cannot be cast to DATA.Model.Group
我在这里不知所措。 CellFactories正在被正确替换,可观察列表也是如此。

1 个答案:

答案 0 :(得分:3)

你是如何宣布myListView的?

我认为问题在于,当您更换单元工厂时,它会立即尝试显示当前项目,这当然是错误的类型。如果你真的想这样做,试试

myListView.getItems().clear(); 

在更换单元工厂之前。

所有这些看起来都像是一个大黑客。输入ListView,你应该这样使用它。你真的无法在运行时改变它的类型。是否有任何理由不简单地切换到其他ListView(即在ListView<Group>ListView<Expenditure>之间切换,而不是仅重新配置单个ListView<???>)?