TreeTableView: установка строки недоступна для редактирования - PullRequest
0 голосов
/ 27 сентября 2018

Я хочу иметь контроль над стилем некоторых строк TreeTableView на основе уровня в дереве.Я использовал setRowFactory и применил стиль, если эта строка является частью дочерних элементов первого уровня корня таблицы.Стиль работает хорошо, но я также хочу отключить установку флажка для этих строк.Я могу setDisable(true), но это также отключает расширение TreeItem, и SetEditable(false), кажется, не имеет никакого эффекта.

РЕДАКТИРОВАТЬ: я понимаю, что таблица должна быть редактируемой, а затемстолбцы по умолчанию доступны для редактирования.Но если я установлю TreeTableRow.setEditable(true); или TreeTableRow.setEditable(false);, я никогда не вижу никакого эффекта.Кажется, что описание setEditable кажется именно тем, что я хочу, но я не могу использовать его таким образом.

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

setEditablepublic final void setEditable (логическое значение)

Позволяет определенным ячейкам не иметь возможности редактировать.Это полезно в случаях, когда, скажем, у List есть «строки заголовка» - не имеет смысла, чтобы строки заголовка были редактируемыми, поэтому они должны иметь редактируемый набор tofalse.Параметры: value - Логическое значение, представляющее, является ли ячейка редактируемой или нет. Если> true, ячейка является редактируемой, и если она ложна, ячейка не может быть отредактирована.

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

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Основная проблема в том, что ни одна из редактируемых (или псевдоредактируемых, как 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;");

            }
        }
    };
});
0 голосов
/ 27 сентября 2018

Если вы хотите отключить определенную ячейку, тогда обрабатывайте логику отключения в CellFactory, а не в RowFactory.Статический метод forTreeTableColumn (..) - удобный метод для быстрого использования.Но это не единственный способ.Вы все еще можете создать свою собственную фабрику для CheckBoxTreeTableCell.

Так что вместо

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

установите клеточный завод, как показано ниже, и это должно работать для вас.

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);
                    }
                };
            }
        });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...