如何将复选框添加到 table 以读取和写入它在 JavaFX 中表示的对象 属性

How can I add a checkbox to a table that reads and writes the object property that it represents in JavaFX

我有一个 table,它列出了 Bot 类型的对象,这些对象具有我想要列出的名称和 isOn 属性:

private SimpleStringProperty name;
private boolean isOn;

布尔值已打开,我想从复选框中读取并从该复选框中读取 table

到目前为止,我已经能够为每一行在 table 的列中添加一个复选框,但它纯粹是可视的(即它与 BotisOn 会员).

如何让复选框从 Bot 的这个成员读取和写入?

这是我处理 Table 的代码:

ObservableList<Bot> bots = FXCollections.observableArrayList();
@FXML
private TableView<Bot> botTable;
@FXML
private TableColumn<Bot, String> nameColumn;
@FXML
private TableColumn<Bot, Boolean> statusColumn;

public void initialize(URL location, ResourceBundle resources){
    nameColumn.setCellValueFactory(new PropertyValueFactory<Bot, String>("name"));
    statusColumn.setCellValueFactory(new PropertyValueFactory<Bot, Boolean>("on"));
    statusColumn.setSortable(false);

    statusColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Bot, Boolean>, ObservableValue<Boolean>>(){
        @Override public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Bot, Boolean> features) {
            return new SimpleBooleanProperty(features.getValue() != null);
        }
    });

    // create a cell value factory with an add button for each row in the table.
    statusColumn.setCellFactory(new Callback<TableColumn<Bot, Boolean>, TableCell<Bot, Boolean>>() {
        @Override public TableCell<Bot, Boolean> call(TableColumn<Bot, Boolean> personBooleanTableColumn) {
            return new AddBotCell(/*stage, botTable*/);
        }
    });

    botTable.setItems(bots);
}

/** A table cell containing a button for adding a new person. */
private class AddBotCell extends TableCell<Bot, Boolean> {
    // a checkbox for adding a new bot.
    final CheckBox checkbox = new CheckBox();
    // pads and centers the add button in the cell.
    final StackPane paddedCheckBox = new StackPane();

    AddBotCell(/*final Stage stage, final TableView table*/) {
        paddedCheckBox.setPadding(new Insets(3));
        paddedCheckBox.getChildren().add(checkbox);
        checkbox.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
            }
        });
    }
    /** places an add checkbox in the row only if the row is not empty. */
    @Override protected void updateItem(Boolean item, boolean empty) {
        super.updateItem(item, empty);
        if (!empty) {
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            setGraphic(checkbox);
        }
    }
}

如果单元格变空,您需要删除复选框。此外,您需要在用户与 CheckBox 交互时更新该值。最好由 selected 属性:

的侦听器完成
private class AddBotCell extends TableCell<Bot, Boolean> {
    // a button for adding a new person.
    final CheckBox checkbox = new CheckBox();
    // pads and centers the add button in the cell.
    final StackPane paddedCheckBox = new StackPane();
    // records the y pos of the last button press so that the add person dialog can be shown next to the cell.
    final DoubleProperty buttonY = new SimpleDoubleProperty();
    private boolean updating = false;

    AddBotCell(/*final Stage stage, final TableView table*/) {
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        paddedCheckBox.setPadding(new Insets(3));
        paddedCheckBox.getChildren().add(checkbox);
        checkbox.selectedProperty().addListener((o, oldValue, newValue) -> {
            if (!updating) {
                updating = true;
                ((Bot)getTableRow().getItem()).setIsOn(newValue);
                updating = false;
            }
        });
    }

    /** places an add button in the row only if the row is not empty. */
    @Override protected void updateItem(Boolean item, boolean empty) {
        super.updateItem(item, empty);

        if (empty || item == null) {
            setGraphic(null);
        } else {
            setGraphic(paddedCheckBox);
            updating = true;
            checkbox.setSelected(item);
            updating = false;
        }
    }
}

您的 cellValueFactory 也应该使用 属性 的值。

statusColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Bot, Boolean>, ObservableValue<Boolean>>(){
    @Override public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Bot, Boolean> features) {
        return new SimpleBooleanProperty(features.getValue().isIsOn());
    }
});