【问题标题】:JavaFx CheckBox on TableView does not update model when checked/unchecked选中/取消选中时,TableView 上的 JavaFx CheckBox 不会更新模型
【发布时间】:2015-02-08 13:02:22
【问题描述】:

我有一个 TableView,第一列有一个复选框。

我设法正确显示复选框并使其可编辑,但是当我单击复选框以选中或取消选中时,复选框会更改但它不会更新我的模型。

这就是我的做法:

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.

【问题讨论】:

    标签: java javafx javafx-2 javafx-8


    【解决方案1】:

    CheckBoxTableCell 真正设计为映射到表模型中的BooleanProperty(通常表最适合此类模型)。 JavaDocs for CheckBoxTableCell 明确声明

    不会调用通常的编辑回调(例如在编辑提交时)

    如果您想在模型不使用BooleanProperty 的表格单元格中使用CheckBox,最好的办法可能是创建自己的表格单元格:

    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 ;
    });
    

    【讨论】:

      【解决方案2】:

      我发现我自己做这件事的方法很简单,正如我在this other question 中回答的那样: 有一种非常简单的方法可以做到这一点,您不需要使用 SimpleBooleanProperty 或其他方式修改模型类,只需按照以下步骤操作即可:

      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 - 创建回调类

      
      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 - 将回调绑定到表格列

      如果您使用 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>
      

      别忘了在你的 FXML 中导入类:

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

      如果没有 FXML,请这样做:

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

      4 - 就是这样

      一切都应该按预期工作,当您单击复选框时将值设置为支持 bean,并且当您在表中加载项目列表时正确设置复选框值。

      【讨论】:

      • 我尝试了这种方法,但是当我点击复选框时,值没有更新回模型类。
      【解决方案3】:

      尝试使用以下代码创建列:

       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));
      

      值的更新是自动的(不需要 setOnEditCommit )

      【讨论】:

      • 但是这样我必须将我的模型与 JavaFX 代码联系起来?我不能只使用简单的布尔变量而不是 SimpleBooleanProperty 吗?
      • 尝试用 ReadOnlyBooleanWrapper 在上面的代码中的 cellValueFactory 回调中包装布尔变量。
      • 以上对我有用,但如果我点击表格视图中的复选框,它不会更新值。我究竟做错了什么?我在我的模型中将其定义为 SimpleBooleanProperty
      猜你喜欢
      • 2016-08-19
      • 2011-03-28
      • 2016-05-19
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-03
      相关资源
      最近更新 更多