TreeTableView:设置一行不可编辑 [英] TreeTableView : setting a row not editable
问题描述
我希望能够根据树中的级别控制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屋!