当用户单击复选框时,我不会在CheckBoxTableCell中使用TableView
需要在选中CheckBox之前以及更改关联属性之前执行此代码。

由于CheckBoxTableCell不会触发startEdit()commitEdit()等,因此我还需要放置代码。
updateItem()为时已晚,因为此处的值已更改。

有人知道我可以在其他地方插入我的代码吗?还是我最好只编写自己的CheckBoxTableCell?

对于那些想进一步思考的人:当用户选中复选框时,我想运行一个代码,该代码检查他的决定是否会在以后导致他的问题。当属性更改时,我有一个changeListener,它将新值上传到数据库。如果可能有任何问题(我的代码返回true),则应该出现强制性错误消息:“您真的要执行此操作吗……blabla”,并且只有当他确认应该实际选中复选框时,该值才会更改并上传到数据库。

这就是我设置CheckBoxTableCell的方法:

    //init cell factories
    Callback<TableColumn<PublicMovie, Boolean>, TableCell<PublicMovie, Boolean>> checkBoxCellFactory
            = (TableColumn<PublicMovie, Boolean> p) -> new CheckBoxTableCell<>();
    //Assign Column
    allMoviesCheckBoxColumn = (TableColumn<PublicMovie, Boolean>) allMoviesTableView.getColumns().get(0);
    //Set CellValueFactory
    allMoviesCheckBoxColumn.setCellValueFactory(cellData -> cellData.getValue().getSomeBooleanProperty();
someBooleanProperty有一个侦听器。更改为true时,statusProperty更改为1

此代码段位于TableView的基础类的构造函数中。每当用户单击CheckBox时,都会执行该复选框。
    this.status.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
        DataHandler.fireOnChangedEvent(PublicMovieChangeListener.STATUS_CHANGED, getMovie(), newValue, oldValue);
    });
DataHandler包含Listeners的列表(到目前为止只有一个)。当onChange调用DataHandler事件时,将执行以下代码:
@Override
public void onChange(int changeID, PublicMovie changedPublicMovie, Object newValue, Object oldValue) {
    switch (changeID) {
        case STATUS_CHANGED:
            boolean mayUpdate = check();
            //check is a placeholder for the code that checks for problems.
            //It will return false if there might be a problem.

            if(!mayUpdate){
                    mayUpdate = ErrorDialogs.getConfirmationDialog("Überfüllung!", header, content);
            }
            if (mayUpdate) {
                updateMovie(changedPublicMovie);
            } else {
                changedPublicMovie.getStatusProperty().set((int) oldValue);
                refreshAllMoviesTable();
            }
            break;
        case THREE_DIM_CHANGED:
            updateMovie(changedPublicMovie);
            break;
        case CHILDREN_CHANGED:
            updateMovie(changedPublicMovie);
            break;
    }

您在这里看到的是我试图撤消更改后的属性...,但该复选框仍处于选中状态。因此,我正在寻找一种在更改属性之前执行检查的方法。

最佳答案

根据 CheckBoxTableCell 的文档:

如果您想收到更改通知,建议直接
观察由CheckBox操作的布尔属性。

我并不是说CheckBoxTableCell是不可能的,但很可能不是那么简单。

在大多数情况下,可以使用EventFilter来管理这种“预选”事件。

因此,您可以尝试将普通的TableColumn与使用这些cellFactory的适当EventFilter一起使用。

我的示例

使用的cellFactory:

tableCol.setCellFactory(p -> {
    CheckBox checkBox = new CheckBox();
    TableCell<Person, Boolean> tableCell = new TableCell<Person, Boolean>() {

        @Override
        protected void updateItem(Boolean item, boolean empty) {

            super.updateItem(item, empty);
            if (empty || item == null)
                setGraphic(null);
            else {
                setGraphic(checkBox);
                checkBox.setSelected(item);
            }
        }
    };

    checkBox.addEventFilter(MouseEvent.MOUSE_PRESSED, event ->
        validate(checkBox, (Person) cell.getTableRow().getItem(), event));

    checkBox.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
        if(event.getCode() == KeyCode.SPACE)
            validate(checkBox, (Person) cell.getTableRow().getItem(), event);
    });

    tableCell.setAlignment(Pos.CENTER);
    tableCell.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);

    return tableCell;
});

和使用的validate方法:
private void validate(CheckBox checkBox, Person item, Event event){
    // Validate here
    event.consume();

    Alert alert = new Alert(AlertType.CONFIRMATION);
    alert.setTitle("Confirmation Dialog");
    alert.setHeaderText("Look, a Confirmation Dialog");
    alert.setContentText("Are you ok with this?");

    // Set the checkbox if the user want to continue
    Optional<ButtonType> result = alert.showAndWait();
    if (result.get() == ButtonType.OK)
        checkBox.setSelected(!checkBox.isSelected());
}

是做什么的:

它呈现一个简单的CheckBox,并向此EventFilter添加两个CheckBox。第一个在鼠标按下时执行,第二个在按键上执行(此处使用KeyCode.SPACE)。他们两个都调用validate方法。 validate方法使用事件(确保未修改CheckBox的选择状态),“验证”输入(我这边没有验证),然后显示确认对话框。如果用户同意,则设置selectedPropertyCheckBox

08-26 02:35