有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

带有按钮的java JavaFX自定义列表单元格:未调用处理程序

我有一个列表视图来显示一些信息,我创建了一个定制的CellFactory:每个单元格都有一个标签、一个图像和一个小按钮。我希望用户能够通过单击该小按钮删除列表行

列表显示正确,但从未调用与按钮关联的处理程序

public class ListViewCell extends ListCell<SessionExercise> {
    @Override
    public void updateItem(SessionExercise exercise, boolean empty) {

    ...

    FXMLLoader listItemLoader = new FXMLLoader();
    listItemLoader.setLocation(getClass().
        getResource("/view/SimpleExerciseListItem.fxml"));

    try {
        listItemLoader.load();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

    SimpleExerciseListItemController listItemController
            = (SimpleExerciseListItemController) listItemLoader.getController();

    ...

    this.setGraphic(listItemController.getAnchorPane());
}

在我的SimpleExerciseListItemController类中:

public class SimpleExerciseListItemController implements Initializable {
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        btnRemove.
            setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                System.out.println("You clicked the remove button!");

                ...
            }
        });
    }
}

我还尝试了setOnMouseClicked(neweventhandler())而不是setOnAction(neweventhandler()),但控制台上没有打印任何内容


共 (1) 个答案

  1. # 1 楼答案

    这是一个known bug,在最新版本中已修复

    您实施ListCell的方式不是推荐的方法;使用推荐的方法也可以解决这个bug

    问题在于性能。对于给定的ListView,创建的单元格相对较少,但是updateItem(...)方法可能会被多次调用。(可以说,在某些情况下,需要更多的次数,但基本的、有意的设计是updateItem(...)可以非常频繁地调用。)

    因此,您应该只在构造函数中加载fxml文件;操作它并在updateItem(...)方法中设置图形:

    public class ListViewCell extends ListCell<SessionExercise> {
    
        private final SimpleExerciseListItemController listItemController ;
    
        public ListViewCell() {
            FXMLLoader listItemLoader = new FXMLLoader();
            listItemLoader.setLocation(getClass().
                getResource("/view/SimpleExerciseListItem.fxml"));
    
            try {
                listItemLoader.load();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
    
            SimpleExerciseListItemController listItemController
                    = (SimpleExerciseListItemController) listItemLoader.getController();
    
            }
            @Override
            public void updateItem(SessionExercise exercise, boolean empty) {
                // don't omit this!!!
                super.updateItem(exercise, empty);
    
                if (empty) {
                    setGraphic(null);
                } else {
                    // update controller and ui as necessary
    
                    this.setGraphic(listItemController.getAnchorPane());
                }
            }
    }