[英]Editable TableTreeView, how to cancel edit
I have made an editable TreeTableView. 我做了一个可编辑的TreeTableView。 I want to offer editable feature based on row contents. 我想提供基于行内容的可编辑功能。
final TreeTableColumn<XXX, String> col = new TreeTableColumn<>( "Title" );
col.setCellValueFactory( new TreeItemPropertyValueFactory<XXX, String >( "name"));
col.setCellFactory( TextFieldTreeTableCell.forTreeTableColumn());
col.setOnEditStart( e -> {
final XXX x = e.getRowValue().getValue();
if( ! x.isEditable()) {
throw new IllegalStateException();
}
e.consume();
});
This solution works well but I prefer to call Cell.cancelEdit() but I don't find how without overriding a lot of classes. 该解决方案效果很好,但是我更喜欢调用Cell.cancelEdit(),但是我发现不重写很多类就不会怎么做。
I hope a simple instruction (or two) do the trick. 我希望一个简单的指令(或两个)可以解决问题。
Cells already have an editable
property , so you can just call setEditable(...)
on the cell as needed: 单元格已经具有editable
属性 ,因此您可以根据需要在单元格上调用setEditable(...)
:
Callback<TreeTableColumn<XXX, String>, TreeTableCell<XXX, String>> defaultCellFactory = TextFieldTreeTableCell.forTreeTableColumn() ;
col.setCellFactory(c -> {
TreeTableCell<XXX, String> cell = defaultCellFactory.call(c);
cell.indexProperty().addListener((obs, oldIndex, newIndex) -> {
if (newIndex.intValue() >= 0 ) {
TreeItem<XXX> item = cell.getTreeTable().getTreeItems(newIndex.intValue());
boolean canEdit = /* logic depending on item */
cell.setEditable(canEdit);
} else {
cell.setEditable(false);
}
});
return cell ;
});
Your logic may vary depending on exactly what you want to do, eg you might use bindings instead of the listener on the indexProperty
, or a listener on the itemProperty()
, or possibly something more sophisticated, but this general structure should work. 您的逻辑可能会根据您要执行的操作而有所不同,例如,您可以使用绑定而不是indexProperty
上的侦听器或itemProperty()
上的侦听器,或者可能使用更复杂的方法,但是这种常规结构应该可以工作。
Here's a complete example. 这是一个完整的例子。 TreeItem
s containing Employee
s have an editable name
column, TreeItem
s containing Department
s don't: 包含Employee
的TreeItem
具有可编辑的name
列,而包含Department
的TreeItem
没有:
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TextFieldTreeTableCell;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TreeTableCustomEditable extends Application {
@Override
public void start(Stage primaryStage) {
TreeItem<Object> root = new TreeItem<>();
TreeItem<Object> it = new TreeItem<>(new Department("IT"));
TreeItem<Object> management = new TreeItem<>(new Department("Management"));
TreeItem<Object> bill = new TreeItem<>(new Employee("1", "Bill Gates"));
TreeItem<Object> tim = new TreeItem<>(new Employee("2", "Tim Cook"));
TreeItem<Object> larry = new TreeItem<>(new Employee("3", "Larry Ellison"));
TreeItem<Object> larryP = new TreeItem<>(new Employee("4", "Larry Page"));
it.getChildren().addAll(larry, larryP);
management.getChildren().addAll(bill, tim);
root.getChildren().addAll(it, management);
TreeTableView<Object> treeTableView = new TreeTableView<>();
treeTableView.setEditable(true);
treeTableView.setRoot(root);
treeTableView.setShowRoot(false);
TreeTableColumn<Object, String> idCol = new TreeTableColumn<>("ID");
idCol.setCellValueFactory(new TreeItemPropertyValueFactory<Object, String>("id"));
TreeTableColumn<Object, String> nameCol = new TreeTableColumn<>("Name");
nameCol.setCellValueFactory(new TreeItemPropertyValueFactory<Object, String>("name"));
Callback<TreeTableColumn<Object, String>, TreeTableCell<Object, String>> defaultCellFactory = TextFieldTreeTableCell.forTreeTableColumn() ;
nameCol.setCellFactory(c -> {
TreeTableCell<Object, String> cell = defaultCellFactory.call(c);
cell.indexProperty().addListener((obs, oldIndex, newIndex) -> {
if (newIndex.intValue() >= 0) {
TreeItem<Object> item = cell.getTreeTableView().getTreeItem(newIndex.intValue());
boolean canEdit = item != null && item.getValue() instanceof Employee ;
cell.setEditable(canEdit);
} else {
cell.setEditable(false);
}
});
return cell ;
});
treeTableView.getColumns().addAll(idCol, nameCol);
BorderPane uiRoot = new BorderPane(treeTableView);
primaryStage.setScene(new Scene(uiRoot, 600, 600));
primaryStage.show();
}
public static class Employee {
private final StringProperty id = new SimpleStringProperty();
private final StringProperty name = new SimpleStringProperty();
public Employee(String id, String name) {
setId(id);
setName(name);
}
public final StringProperty idProperty() {
return this.id;
}
public final java.lang.String getId() {
return this.idProperty().get();
}
public final void setId(final java.lang.String id) {
this.idProperty().set(id);
}
public final StringProperty nameProperty() {
return this.name;
}
public final java.lang.String getName() {
return this.nameProperty().get();
}
public final void setName(final java.lang.String name) {
this.nameProperty().set(name);
}
}
public static class Department {
private final StringProperty id = new SimpleStringProperty();
public Department(String id) {
setId(id);
}
public final StringProperty idProperty() {
return this.id;
}
public final java.lang.String getId() {
return this.idProperty().get();
}
public final void setId(final java.lang.String id) {
this.idProperty().set(id);
}
}
public static void main(String[] args) {
launch(args);
}
}
I have found a solution but not in one instruction nor two... :-( 我找到了一种解决方案,但没有一条指令,也没有两条... :-(
Explicit feature: 显式功能:
public interface IEditable {
public boolean isEditable();
}
Using feature in a TextFieldTreeTableCell
: 在TextFieldTreeTableCell
使用功能:
final class EditableTextFieldTreeTableCell<S extends IEditable>
extends TextFieldTreeTableCell<S, String>
{
public static <S extends IEditable>
Callback<TreeTableColumn<S,String>, TreeTableCell<S,String>> getCallback() {
return list -> new EditableTextFieldTreeTableCell<>( new DefaultStringConverter());
}
public EditableTextFieldTreeTableCell( StringConverter<String> converter ) {
super( converter );
}
@Override
public void startEdit() {
setEditable( getTreeTableRow().getItem().isEditable());
super.startEdit();
}
}
Using the new specialized Cell class in the main: 在主体中使用新的专用Cell类:
final TreeTableColumn<XXX, String> col = new TreeTableColumn<>( "Title" );
col.setCellValueFactory( new TreeItemPropertyValueFactory<XXX, String >( "name"));
col.setCellFactory( EditableTextFieldTreeTableCell.getCallback());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.