TreeTableView:设置一行不可编辑 [英] TreeTableView : setting a row not editable

查看:184
本文介绍了TreeTableView:设置一行不可编辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够根据树中的级别控制TreeTableView的某些行的样式。我使用 setRowFactory 并应用样式,如果此行是表的根的第一级子项的一部分。样式工作正常,但我也想禁用单击这些行的复选框。我能够 setDisable(true)但是这也禁用了TreeItem的扩展和 SetEditable(false)没有似乎有任何影响。

I want to have control over the styling of some rows of a TreeTableView based on the level in the tree. I used setRowFactory and apply a styling if this row is part of the first level children of the root of the Table. The styling works fine, but I also want to disable clicking on the checkbox for those rows. I am able to setDisable(true) but that also disables the expanding of the TreeItem and SetEditable(false) does not seem to have any effect.

编辑:据我所知,表必须设置为可编辑,然后列默认可编辑。但是,如果我设置 TreeTableRow.setEditable(true); TreeTableRow.setEditable(false); 我从未看到任何效果。似乎setEditable的描述似乎正是我想要的但我无法以这种方式使用它。

EDIT : What I understand is that the Table must be set editable, then the columns are by default editable. But if I set TreeTableRow.setEditable(true); or TreeTableRow.setEditable(false); I never see any effect. The description seems of setEditable seems exactly what I want but I am unable to use it that way.


void javafx.scene.control.Cell .setEditable(boolean arg0)

void javafx.scene.control.Cell.setEditable(boolean arg0)

setEditable
public final void setEditable(boolean value)

setEditable public final void setEditable(boolean value)

允许某些单元格无法编辑。这很有用>例如,List有'标题行' - 标题行>没有意义可编辑,因此它们应该具有可编辑的设置tofalse。
参数:value - 表示单元格是否可编辑的布尔值。如果> true,则单元格是可编辑的,如果为false,则无法编辑单元格。

Allows for certain cells to not be able to be edited. This is useful incases >where, say, a List has 'header rows' - it does not make sense forthe header rows >to be editable, so they should have editable set tofalse. Parameters:value - A boolean representing whether the cell is editable or not.If >true, the cell is editable, and if it is false, the cell can notbe edited.

Main:

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));
    colSelected.setCellValueFactory(new TreeItemPropertyValueFactory<>("selected"));


    ttv.setRowFactory(table-> {
        return new TreeTableRow<Person>(){
            @Override
            public void updateItem(Person pers, boolean empty) {
                super.updateItem(pers, empty);
                boolean isTopLevel = table.getRoot().getChildren().contains(treeItemProperty().get());
                if (!isEmpty()) {
                    if(isTopLevel){
                        setStyle("-fx-background-color:lightgrey;");
                        setEditable(false); //THIS DOES NOT SEEM TO WORK AS I WANT
                        //setDisable(true); //this would disable the checkbox but also the expanding of the tree
                    }else{

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


    // creating treeItems to populate the treetableview
    TreeItem<Person> rootTreeItem = new TreeItem<Person>();
    TreeItem<Person> parent1 = new TreeItem<Person>(new Person("Parent 1"));
    TreeItem<Person> parent2 = new TreeItem<Person>(new Person("Parent 1"));
    parent1.getChildren().add(new TreeItem<Person>(new Person("Child 1")));
    parent2.getChildren().add(new TreeItem<Person>(new Person("Child 2")));
    rootTreeItem.getChildren().addAll(parent1,parent2);


    ttv.setRoot(rootTreeItem);

    // build and show the window
    Group root = new Group();
    root.getChildren().add(ttv);
    stage.setScene(new Scene(root, 300, 300));
    stage.show();
}
}

模特人:

public class Person {
private StringProperty name;
private BooleanProperty selected;

public Person(String name) {
    this.name = new SimpleStringProperty(name);
    selected = new SimpleBooleanProperty(false);
}

public StringProperty nameProperty() {
    return name;
}

public BooleanProperty selectedProperty() {
    return selected;
}

public void setName(String name){
    this.name.set(name);
}

public void setSelected(boolean selected){
    this.selected.set(selected);
}
}


推荐答案

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

The base problem is that none of the editable (nor the pseudo-editable like CheckBoxXX) Tree/Table cells respect the editability of the row they are contained in. Which I consider a bug.

要克服,您必须扩展(伪)可编辑单元格并使它们尊重行的可编辑性。伪对称实际编辑单元的确切实现是不同的。下面是内联示例,对于频繁使用,您可以使它们成为顶层并重新使用。

To overcome, you have to extend the (pseudo) editable cells and make them respect the row's editable. The exact implementation is different for pseudo- vs. real editing cells. Below are in-line examples, for frequent usage you would make them top-level and re-use.

CheckBoxTreeTableCell:子类并覆盖updateItem以重新绑定其禁用的属性喜欢

CheckBoxTreeTableCell: subclass and override updateItem to re-bind its disabled property like

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

对于真正的编辑单元格,f.i。 TextFieldTreeTableCell:覆盖startEdit,如果行不可编辑则返回而不调用super

For a real editing cell, f.i. TextFieldTreeTableCell: override startEdit and return without calling super if the row isn't editable

colName.setCellFactory(c -> {
    TreeTableCell cell = new TextFieldTreeTableCell() {

        @Override
        public void startEdit() {
            if (getTreeTableRow() != null && !getTreeTableRow().isEditable()) return;
            super.startEdit();
        }

    };
    return cell;
});

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

Now you can toggle the row's editability as you do, changed the logic a bit to guarantee full cleanup in all cases:

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

            }
        }
    };
});

这篇关于TreeTableView:设置一行不可编辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆