为了账号安全,请及时绑定邮箱和手机立即绑定

TreeTableView:设置一行不可编辑

TreeTableView:设置一行不可编辑

郎朗坤 2021-10-13 16:12:28
我想根据树中的级别控制 TreeTableView 某些行的样式。setRowFactory如果此行是表根的第一级子级的一部分,我使用并应用了样式。样式工作正常,但我也想禁用单击这些行的复选框。我能够,setDisable(true)但这也禁用了 TreeItem 的扩展,并且SetEditable(false)似乎没有任何效果。编辑:我的理解是必须将表设置为可编辑,然后列在默认情况下是可编辑的。但是如果我设置了,TreeTableRow.setEditable(true);或者TreeTableRow.setEditable(false);我从来没有看到任何效果。setEditable 的描述似乎正是我想要的,但我无法那样使用它。void javafx.scene.control.Cell.setEditable(boolean arg0)setEditable public final void setEditable(boolean value)允许某些单元格无法编辑。这在以下情况下很有用,例如,列表具有“标题行”-标题行 > 可编辑没有意义,因此它们应该将可编辑设置为 false。参数:value - 表示单元格是否可编辑的布尔值。如果 >true,单元格可编辑,如果为 false,单元格不可编辑。主要的:public class TreeTableViewRowStyle extends Application {    public static void main(String[] args) {        launch(args);    }    @Override    public void start(Stage stage) throws Exception {        // create the treeTableView and colums        TreeTableView<Person> ttv = new TreeTableView<Person>();        TreeTableColumn<Person, String> colName = new TreeTableColumn<>("Name");        TreeTableColumn<Person, Boolean> colSelected = new TreeTableColumn<>("Selected");        colName.setPrefWidth(100);        ttv.getColumns().add(colName);        ttv.getColumns().add(colSelected);        ttv.setShowRoot(false);        ttv.setEditable(true);        // set the columns        colName.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));        colSelected.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(colSelected));
查看完整描述

3 回答

?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

基本问题是,没有任何可编辑(也不是像 CheckBoxXX 这样的伪可编辑)树/表单元格尊重它们所在行的可编辑性。我认为这是一个错误。


要克服这一问题,您必须扩展(伪)可编辑单元格并使它们尊重行的可编辑性。伪编辑单元格和真实编辑单元格的确切实现是不同的。以下是内嵌示例,对于频繁使用,您可以将它们设为顶级并重复使用。


CheckBoxTreeTableCell:子类化并覆盖 updateItem 以重新绑定其禁用的属性,例如


colSelected.setCellFactory(c -> {

    TreeTableCell cell = new CheckBoxTreeTableCell() {


        @Override

        public void updateItem(Object item, boolean empty) {

            super.updateItem(item, empty);

            if (getGraphic() != null) {

                getGraphic().disableProperty().bind(Bindings

                        .not(

                              getTreeTableView().editableProperty()

                             .and(getTableColumn().editableProperty())

                             .and(editableProperty())

                             .and(getTreeTableRow().editableProperty())

                    ));

            }

        }


    };

    return cell;

});

对于真正的编辑单元格,fi TextFieldTreeTableCell: 覆盖 startEdit 并返回,如果该行不可编辑,则不调用 super


colName.setCellFactory(c -> {

    TreeTableCell cell = new TextFieldTreeTableCell() {


        @Override

        public void startEdit() {

            if (getTreeTableRow() != null && !getTreeTableRow().isEditable()) return;

            super.startEdit();

        }


    };

    return cell;

});

现在你可以像你一样切换行的可编辑性,稍微改变逻辑以保证在所有情况下完全清理:


ttv.setRowFactory(table-> {

    return new TreeTableRow<Person>(){

        @Override

        public void updateItem(Person pers, boolean empty) {

            super.updateItem(pers, empty);

            // tbd: check for nulls!

            boolean isTopLevel = table.getRoot().getChildren().contains(treeItemProperty().get());

            if (!isEmpty() && isTopLevel) {

                //                        if(isTopLevel){

                setStyle("-fx-background-color:lightgrey;");

                setEditable(false); 

            }else{

                setEditable(true);

                setStyle("-fx-background-color:white;");


            }

        }

    };

});


查看完整回答
反对 回复 2021-10-13
?
largeQ

TA贡献2039条经验 获得超7个赞

如果您想禁用特定的 Cell,则在 CellFactory 而不是 RowFactory 中处理禁用逻辑。TreeTableColumn(..)的静态方法是一种方便快速使用的方法。但这不是唯一的方法。您仍然可以为 CheckBoxTreeTableCell 创建自己的工厂。


所以代替


colSelected.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(colSelected));

设置 cellfactory 如下,这应该适合你。


colSelected.setCellFactory(new Callback<TreeTableColumn<Person, Boolean>, TreeTableCell<Person, Boolean>>() {


    @Override

    public TreeTableCell<Person, Boolean> call(TreeTableColumn<Person, Boolean> column) {

        return new CheckBoxTreeTableCell<Person, Boolean>() {


            @Override

            public void updateItem(Boolean item, boolean empty) {

                super.updateItem(item, empty);

                boolean isTopLevel = column.getTreeTableView().getRoot().getChildren().contains(getTreeTableRow().getTreeItem());

                setEditable(!isTopLevel);

            }

        };

    }

});


查看完整回答
反对 回复 2021-10-13
  • 3 回答
  • 0 关注
  • 372 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信