0
カスタムセルコントロールでツリーテーブルを実装しましたが、セルコントロールから更新されたデータを永続させるのに問題があります。 具体的には、commitEdit、updateControlを呼び出す方法、またはオブジェクトバインディングを使用して、各セルの変更を基底のドメインオブジェクトに確実に保持する方法があります。カスタムコントロールを使用してjavafx treetablecellsの値を永続化する方法
最初の質問に私のコードでMultiple Controls needed in JavaFX Tree Table Cell
あなたは問題が崩壊したときに、セルのデータを保持し、ツリーテーブルノードを展開を見ることができるの下に。
カスタムセルコントロールを使用して更新をトリガーし、データを基になる行オブジェクトに永続化するにはどうすればよいですか?
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Control;
import javafx.scene.control.TextField;
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.TreeItemPropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.converter.BooleanStringConverter;
public class SampleApp extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@SuppressWarnings("unchecked")
@Override
public void start(Stage primaryStage) throws Exception {
TreeItem<MyField> fooFields = new TreeItem<MyField>(new MyField("Foo", "Foo", null, false, null));
TreeItem<MyField> fooText = new TreeItem<MyField>(new MyField("fooText", "fooText", "text", true, null));
TreeItem<MyField> fooCheck = new TreeItem<MyField>(new MyField("fooCheck", "fooCheck", "check", true, null));
List<String> fooCombos = Arrays.asList("foo Combo 1", "foo Combo 2");
TreeItem<MyField> fooCombo = new TreeItem<MyField>(
new MyField("fooCombo", "foo Combo", "combo", true, fooCombos));
fooFields.getChildren().addAll(fooText, fooCheck, fooCombo);
TreeItem<MyField> barFields = new TreeItem<MyField>(new MyField("Bar", "Bar", null, false, null));
TreeItem<MyField> barText = new TreeItem<MyField>(new MyField("barText", "barText", "text", true, null));
TreeItem<MyField> barCheck = new TreeItem<MyField>(new MyField("barCheck", "barCheck", "check", true, null));
List<String> barCombos = Arrays.asList("bar Combo 1", "bar Combo 2");
TreeItem<MyField> barCombo = new TreeItem<MyField>(
new MyField("barCombo", "bar Combo", "combo", true, barCombos));
barFields.getChildren().addAll(barText, barCheck, barCombo);
TreeItem<MyField> hiddenRoot = new TreeItem<MyField>(new MyField("hidden", "hidden", null, false, null));
hiddenRoot.getChildren().addAll(fooFields, barFields);
TreeTableView<MyField> treeTable = new TreeTableView<>(hiddenRoot);
treeTable.setEditable(true);
treeTable.setPrefWidth(400);
treeTable.setShowRoot(false);
TreeTableColumn<MyField, String> nameCol = new TreeTableColumn<MyField, String>("Name");
nameCol.setPrefWidth(150);
nameCol.setCellValueFactory(new TreeItemPropertyValueFactory<MyField, String>("name"));
TreeTableColumn<MyField, String> valueCol = new TreeTableColumn<MyField, String>("Value");
valueCol.setPrefWidth(250);
valueCol.setCellValueFactory(new TreeItemPropertyValueFactory<MyField, String>("value"));
valueCol.setCellFactory(new MyFieldCellFactory());
treeTable.getColumns().addAll(nameCol, valueCol);
HBox root = new HBox(treeTable);
root.setStyle("-fx-padding: 10;" + "-fx-border-style: solid inside;" + "-fx-border-width: 2;"
+ "-fx-border-insets: 5;" + "-fx-border-radius: 5;" + "-fx-border-color: blue;");
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("Multi Control Tree Table View");
primaryStage.show();
}
public class MyField {
private String name;
private StringProperty value;
public String fieldType;
public boolean isEditable;
public List<String> comboVals;
public MyField(String name, String value, String fieldType, boolean isEditable, List<String> comboVals) {
super();
this.name = name;
this.value = new SimpleStringProperty(value);
this.fieldType = fieldType;
this.isEditable = isEditable;
this.comboVals = comboVals;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value.get();
}
public StringProperty valueProperty() {
return value;
}
public void setValue(String value) {
this.value.set(value);
}
public String getFieldType() {
return fieldType;
}
public void setFieldType(String fieldType) {
this.fieldType = fieldType;
}
public List<String> getComboVals() {
return comboVals;
}
public void setComboVals(List<String> comboVals) {
this.comboVals = comboVals;
}
public boolean isEditable() {
return isEditable;
}
public void setEditable(boolean isEditable) {
this.isEditable = isEditable;
}
}
public class MyFieldCellFactory
implements Callback<TreeTableColumn<MyField, String>, TreeTableCell<MyField, String>> {
@Override
public TreeTableCell<MyField, String> call(TreeTableColumn<MyField, String> param) {
return new MyFieldCell();
}
}
public class MyFieldCell extends TreeTableCell<MyField, String> {
private MyEditingControlProvider controlProvider = new MyCellEditingControlProvider();
public MyFieldCell() {
super();
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
setText(null);
System.out.println("updating getItem()" + getItem());
System.out.println("getTableRow().getItem().getName() " + getTreeTableRow().getItem().getName());
setGraphic(controlProvider.getControl(getTreeTableRow().getItem()));
}
}
protected void commitEdit() {
super.commitEdit(getItem());
System.out.println("committing edit");
MyField myField = getTreeTableRow().getItem();
controlProvider.updateFromControl(myField);
}
}
public interface MyEditingControlProvider {
public Control getControl(MyField field);
public void updateFromControl(MyField field);
}
public class MyCellEditingControlProvider implements MyEditingControlProvider {
private Map<String, MyEditingControlProvider> providers;
public MyCellEditingControlProvider() {
providers = new HashMap<>();
providers.put("check", new CheckProvider());
providers.put("combo", new ComboProvider());
providers.put("text", new TextProvider());
}
@Override
public Control getControl(MyField field) {
if (field == null || field.getFieldType() == null) {
return null;
} else {
return providers.get(field.getFieldType()).getControl(field);
}
}
@Override
public void updateFromControl(MyField field) {
providers.get(field.getFieldType()).updateFromControl(field);
}
}
public class CheckProvider implements MyEditingControlProvider {
private CheckBox checkBox;
@Override
public Control getControl(MyField field) {
if (checkBox == null) {
createCheckBox(field);
}
return checkBox;
}
private void createCheckBox(MyField field) {
checkBox = new CheckBox("Check");
checkBox.setSelected(getBoolean(field));
field.valueProperty().bindBidirectional(checkBox.selectedProperty(), new BooleanStringConverter());
checkBox.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (!newValue) {
updateFromControl(field);
}
}
});
}
private Boolean getBoolean(MyField field) {
return field.getValue() == null ? false : convertYNToBoolean(field.getValue());
}
private Boolean convertYNToBoolean(String val) {
if (val != null && val.equals("Y")) {
return true;
} else {
return false;
}
}
private String convertBooleanToYN(Boolean val) {
if (val) {
return "Y";
} else {
return "N";
}
}
@Override
public void updateFromControl(MyField field) {
field.setValue(convertBooleanToYN(checkBox.isSelected()));
}
}
public class ComboProvider implements MyEditingControlProvider {
private ComboBox<String> comboBox;
@Override
public Control getControl(MyField field) {
if (comboBox == null) {
createComboBox(field);
}
return comboBox;
}
private void createComboBox(MyField field) {
comboBox = new ComboBox<String>();
comboBox.setEditable(true);
resetBox(field);
field.valueProperty().bindBidirectional(comboBox.valueProperty());
}
private void resetBox(MyField field) {
comboBox.getItems().clear();
comboBox.getItems().addAll(field.getComboVals());
}
@Override
public void updateFromControl(MyField field) {
field.setValue(comboBox.getValue());
}
}
public class TextProvider implements MyEditingControlProvider {
private TextField textField;
@Override
public Control getControl(MyField field) {
if (textField == null) {
createTextField(field);
}
return textField;
}
private void createTextField(MyField field) {
textField = new TextField(field.getValue());
field.valueProperty().bindBidirectional(textField.textProperty());
}
@Override
public void updateFromControl(MyField field) {
field.setValue(textField.getText());
}
}
}