简体   繁体   English

选中/取消选中TableView上的JavaFx CheckBox不会更新模型

[英]JavaFx CheckBox on TableView does not update model when checked/unchecked

i have a TableView with the first column with a check box. 我有一个TableView的第一列带有一个复选框。

I managed to show the checkbox correctly and make it editable, but when i click on the checkbox to check or uncheck, the checkBox changes but it does not update my model. 我设法正确显示了复选框并使其可编辑,但是当我单击复选框以选中或取消选中时,复选框会发生变化,但不会更新我的模型。

This is how i did it: 这是我的方法:

TableColumn<ContasReceber, Boolean> myCheckBoxColumn = (TableColumn<ContasReceber, Boolean>) tabelaContas.getColumns().get(0);
myCheckBoxColumn.setCellFactory(p -> new CheckBoxTableCell<>());
myCheckBoxColumn.setOnEditCommit(evt -> evt.getRowValue().setChecked(evt.getNewValue()));//It never executes the method setChecked when i click on the checkBox to change it's values.

CheckBoxTableCell is really designed to map to a BooleanProperty in the table model (and in general tables work best with such models). CheckBoxTableCell实际上是为映射到表模型中的BooleanProperty而设计的(一般而言,表在此类模型中效果最好)。 The JavaDocs for CheckBoxTableCell explicitly state that CheckBoxTableCellJavaDocs明确指出

the usual editing callbacks (such as on edit commit) will not be called 通常的编辑回调(例如在编辑提交时)将不会被调用

If you want to use a CheckBox in a table cell where the model does not use a BooleanProperty , the best bet is probably to create your own table cell: 如果你想使用一个CheckBox表格单元格在模型不使用BooleanProperty ,最好的办法可能是创建自己的表格单元格:

myCheckBoxColumn.setCellFactory(p -> {
    CheckBox checkBox = new CheckBox();
    TableCell<ContasReceber, Boolean> cell = new TableCell<ContasReceber, Boolean>() {
        @Override
        public void updateItem(Boolean item, boolean empty) {
            if (empty) {
                setGraphic(null);
            } else {
                checkBox.setSelected(item);
                setGraphic(checkBox);
            }
        }
    };
    checkBox.selectedProperty().addListener((obs, wasSelected, isSelected) -> 
        ((ContasReceber)cell.getTableRow().getItem()).setChecked(isSelected));
    cell.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    cell.setAlignment(Pos.CENTER);
    return cell ;
});

I found i way of doing it myself, it's quite simple as i answered in this other question : There is a very simple way of doing this, you don't need to modify your model class with SimpleBooleanProperty or whatever, just follow these steps: 我发现自己可以这样做,这很简单,就像我在另一个问题中回答的那样:有一种非常简单的方法,您不需要使用SimpleBooleanProperty或其他方法修改模型类,只需执行以下步骤:

1 - Suppose you have a "Person" object with a isUnemployed method: 1-假设您有一个带isUnemployed方法的“ Person”对象:


public class Person {
    private String name;
    private Boolean unemployed;

    public String getName(){return this.name;}
    public void setName(String name){this.name = name;}
    public Boolean isUnemployed(){return this.unemployed;}
    public void setUnemployed(Boolean unemployed){this.unemployed = unemployed;}
}

2 - Create the callback class 2-创建回调类


import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableColumn;
import javafx.util.Callback;

public class PersonUnemployedValueFactory implements Callback, ObservableValue> {
    @Override
    public ObservableValue call(TableColumn.CellDataFeatures param) {
        Person person = param.getValue();
        CheckBox checkBox = new CheckBox();
        checkBox.selectedProperty().setValue(person.isUnemployed());
        checkBox.selectedProperty().addListener((ov, old_val, new_val) -> {
            person.setUnemployed(new_val);
        });
        return new SimpleObjectProperty(checkBox);
    }
}

3 - Bind the callback to the table column 3-将回调绑定到表列

If you use FXML, put the callback class inside your column: 如果使用FXML,请将回调类放在您的列中:

<TableView fx:id="personList" prefHeight="200.0" prefWidth="200.0">
    <columns>
        <TableColumn prefWidth="196.0" text="Unemployed">
            <cellValueFactory>
                <PersonUnemployedValueFactory/> <!--This is how the magic happens-->
            </cellValueFactory>
        </TableColumn>

        ...
    </columns>
</TableView>

Don't forget to import the class in your FXML: 不要忘记在您的FXML中导入该类:

<?import org.yourcompany.yourapp.util.PersonUnemployedValueFactory?>

Without FXML, do it like this: 如果没有FXML,请按照以下步骤操作:

TableColumn<Person, CheckBox> column = (TableColumn<Person, CheckBox>) personTable.getColumns().get(0);
column.setCellValueFactory(new PersonUnemployedValueFactory());

4 - That's it 4-就这样

Everything should work as expected, with the value being set to the backing bean when you click on the checkbox, and the checkbox value correctly being set when you load the items list in your table. 一切都会按预期进行,单击复选框时将其值设置为backing bean,并且在表中加载项目列表时将正确设置复选框的值。

Try to create the Column using the following code: 尝试使用以下代码创建列:

 checkBoxesCol = new TableColumn<ContasReceber, Boolean>("CheckBox Col");
 checkBoxesCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ContasReceber, Boolean>, ObservableValue<Boolean>>() {

                @Override
                public ObservableValue<Boolean> call(CellDataFeatures<ContasReceber, Boolean> param) {
                    return param.getValue().checkedProperty();
                }
            });
 checkBoxesCol.setCellFactory(CheckBoxTableCell.forTableColumn(checkBoxesCol));

The update of the value is automatic(No need for setOnEditCommit ) 值的更新是自动的(无需setOnEditCommit)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM