JavaFX编辑具有自定义对象的TreeView



我需要使TreeView可编辑,并且TreeView具有泛型类型为Content的TreeItem。通过重写Content类中的toString(),我成功地在TreeView上显示了我的对象。然而,尽管我知道自定义编辑功能与CellFactory有关,但我还是无法让它发挥作用。

我想要实现的编辑工作如下:

  1. 当我通过双击或按Enter键开始编辑单元格时,会显示一个TextField
  2. 如果用户编辑时单元格中有":"分隔符,则将前者和后者分别保存在扩展Content的类Property中的namedescription
  3. 如果没有,请将name中的内容保存到扩展Content的类Concept

MainController.java

package jsh.hiercards;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTreeView;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.scene.input.KeyEvent;
import java.net.URL;
import java.util.ResourceBundle;
public class MainController implements Initializable {
@FXML
public JFXTreeView<Content> treeView;
@Override
public void initialize(URL location, ResourceBundle resources) {
TreeItem<Content> root = new TreeItem<>(new Concept("TESTROOT", null));
root.getChildren().add(new TreeItem<>(new Concept("TESTCONCEPT", (Concept) root.getValue())));
root.getChildren().add(new TreeItem<>(new Property("TESTPROPERTY", (Concept) root.getValue(), "DESCRIPTION")));
treeView.setRoot(root);
}
@FXML
public void startEdit(TreeView.EditEvent e) {
System.out.println("Start");
}
@FXML
public void commitEdit(TreeView.EditEvent e) {
System.out.println("Commit");
}
@FXML
public void cancelEdit(TreeView.EditEvent e) {
System.out.println("Cancel");
}
@FXML
public void typeHandle(KeyEvent e) {
System.out.println("Type");
}
}

Content.java

package jsh.hiercards;
import javafx.scene.control.TreeItem;
public abstract class Content {
public String name;
public Concept parent;
private Content() {
}
public Content(String name, Concept parent) {
this.name = name;
this.parent = parent;
}
public abstract String toString();
}

概念.java

package jsh.hiercards;
import javafx.scene.control.TreeItem;
public class Concept extends Content {
public Concept(String name, Concept parent) {
super(name, parent);
}
@Override
public String toString() {
return name;
}
}

Property.java

package jsh.hiercards;
import javafx.scene.control.TreeItem;
public class Property extends Content {
public String description;
public Property(String name, Concept parent, String description) {
super(name, parent);
this.description = description;
}
@Override
public String toString() {
return name + " : " + description;
}
}

我如何对它们进行编码,使其成为一个有效的编辑功能?

--抱歉英语不好,我是一名外国学生:(

以下内容应该适用于您的控制器。如果使用TextFieldTreeCell,则无需自己处理编辑事件。

使用toString()来确定对象在UI中的显示方式也是不好的做法(它用基本上实现视图一部分的代码"污染"了数据模型;您可能也可能希望toString()方法提供不同的信息,例如用于调试(。

所以类似于:

package jsh.hiercards;
public abstract class Content {
private String name;
private Concept parent;
private Content() {
}
public Content(String name, Concept parent) {
this.name = name;
this.parent = parent;
}
public String getName() {
return name ;
}
public Concept getParent() {
return parent ;
}
}
package jsh.hiercards;
public class Concept extends Content {
public Concept(String name, Concept parent) {
super(name, parent);
}
}
package jsh.hiercards;

public class Property extends Content {
private String description;
public Property(String name, Concept parent, String description) {
super(name, parent);
this.description = description;
}
public String getDescription() {
return description ;
}
}
package jsh.hiercards;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTreeView;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.scene.input.KeyEvent;
import javafx.util.StringConverter ;
import java.net.URL;
import java.util.ResourceBundle;
public class MainController implements Initializable {
@FXML
public JFXTreeView<Content> treeView;
@Override
public void initialize(URL location, ResourceBundle resources) {
treeView.setCellFactory(tv -> new TextFieldTreeCell<>(new StringConverter<>() {
@Override
public Content fromString(String text) {
TreeItem<Content> parentItem = getTreeItem().getParent();
Content parent = parentItem == null ? null : parentItem.getValue() ;
String[] tokens = text.split(":", 2);
if (tokens.length < 2) {
return new Concept(tokens[0], parent);
} else return new Property(tokens[0], parent, tokens[1]);
}
@Override
public String toString(Content content) {
if (content instanceof Property property) {
return property.getName() + " : " + property.getDescription();
}
return content.getName();
}
}));
TreeItem<Content> root = new TreeItem<>(new Concept("TESTROOT", null));
root.getChildren().add(new TreeItem<>(new Concept("TESTCONCEPT", (Concept) root.getValue())));
root.getChildren().add(new TreeItem<>(new Property("TESTPROPERTY", (Concept) root.getValue(), "DESCRIPTION")));
treeView.setRoot(root);
}
/*
@FXML
public void startEdit(TreeView.EditEvent e) {
System.out.println("Start");
}
@FXML
public void commitEdit(TreeView.EditEvent e) {
System.out.println("Commit");
}
@FXML
public void cancelEdit(TreeView.EditEvent e) {
System.out.println("Cancel");
}
*/
@FXML
public void typeHandle(KeyEvent e) {
System.out.println("Type");
}
}

最新更新