I am trying to write a JavaFx component which is generally called a "property editor" or a "property grid". A property being a name-value pair.
I guess the property sheet is made for this, but I'd like to use a TreeTableView. Mainly because I have nested properties and eventually several columns.
The component on the right is exactly what I try to achieve.
The problem I encountered with the TreeTableView, is the fact that the cell customisation must occur in the CellFactory which leads to a switch on the item type. This solution makes things really unflexible.
For example, what happens if a string value must be updated via a TextField for a given property and via a ComboBox for another property?
Any suggestion is more than welcome!
Relating questions: javafx-8-custom-listview-cells-its-evil
Update1
I tried to implement the @fabian's 1st suggestion.
I have my bean:
public class PropertyItem {
private StringProperty name = new SimpleStringProperty("");
private EditableItem value;
...
}
A default implementation of the EditableItem, to edit a string via in a TextField:
public class DefaultEditableItem implements EditableItem {
String value = "init value";
private TextField textField = new TextField();
public DefaultEditableItem(String value) {
this.setValue(value);
}
// implementations of assignItem, removeItem, startEdit, cancelEdit,... as suggested for the cell behavior
}
My implementation of the TableView:
PropertyItem rootProp = new PropertyItem("ROOT", new DefaultEditableItem("test roots"));
TreeItem<PropertyItem> root = new TreeItem(rootProp);
// the name column is straightforward ...
// value column
TreeTableColumn<PropertyItem, EditableItem> valueColumn = new TreeTableColumn<>("VALUE");
valueColumn.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<PropertyItem, EditableItem>, ObservableValue<EditableItem>>() {
@Override
public ObservableValue<EditableItem> call(TreeTableColumn.CellDataFeatures<PropertyItem, EditableItem> cellData) {
TreeItem<PropertyItem> treeItem = cellData.getValue();
PropertyItem propertyItem = treeItem.getValue();
// this will not compile...
return propertyItem.value();
}
});
valueColumn.setCellFactory(new Callback<TreeTableColumn<PropertyItem, EditableItem>, TreeTableCell<PropertyItem, EditableItem>>() {
@Override
public TreeTableCell<PropertyItem, EditableItem> call(TreeTableColumn<PropertyItem, EditableItem> param) {
return new EditingTreeTableCell();
}
});
valueColumn.setOnEditCommit(...)
treeTableView.getColumns().addAll(nameColumn, valueColumn);
treeTableView.setEditable(true);
My problem is on the cellValueFactory which needs to return a ObservableValue. What should I do, given that I want this column to be editable?
I guess that EditableItem must extends Property? But then, could my DefaultEditableItem extends SimpleStringProperty?