【问题标题】:JavaFX TreeView edit ItemJavaFX TreeView 编辑项
【发布时间】:2017-01-20 19:35:31
【问题描述】:

我正在尝试编辑 TreeView 项目,下面是我的代码,

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.*;

public class TreeViewSample extends Application {

    public static void main(String[] args) {
        launch(args);
    }
    TreeView<Object> tree;

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Tree View Sample");

        TreeItem<Object> rootItem = new TreeItem<Object>("Tree");
        rootItem.setExpanded(true);
        for (int i = 1; i < 6; i++) {
            TreeItem<Object> item = new TreeItem<Object>("Item" + i);
            rootItem.getChildren().add(item);
        }

        ContextMenu menu = new ContextMenu();
        MenuItem renameItem = new MenuItem("Rename");
        menu.getItems().add(renameItem);

        tree = new TreeView<Object>(rootItem);
        tree.setContextMenu(menu);
        tree.setEditable(true);

        tree.setCellFactory(new Callback<TreeView<Object>, TreeCell<Object>>() {
            @Override
            public TreeCell<Object> call(TreeView<Object> p) {
                return new TextFieldTreeCell<Object>();
            }
        });
        renameItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                tree.edit(tree.getSelectionModel().getSelectedItem());
            }
        });

        tree.setOnEditCommit(new EventHandler<TreeView.EditEvent<Object>>() {
            @Override
            public void handle(TreeView.EditEvent<Object> event) {
                System.out.println("Commit Value");
            }
        });
        StackPane root = new StackPane();
        root.getChildren().add(tree);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}

在编辑和提交值时,

如果TreeViewTreeItem 泛型类型是String 我用过 return new TextFieldTreeCell&lt;String&gt;(new DefaultStringConverter());

当我使用 Object 时,我不确定如何使用 字符串转换器 导致 ,

Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: 
Attempting to convert text input into Object, but provided StringConverter is null. Be sure to set a StringConverter in your cell factory.

我怎样才能缓解这个异常。

【问题讨论】:

    标签: java javafx treeview


    【解决方案1】:

    TreeView 中显示Object 实例实际上没有意义,因为它们不存储任何要显示的信息。

    实际上,以下StringConverter 可以帮助您消除错误:

    tree.setCellFactory(new Callback<TreeView<Object>, TreeCell<Object>>() {
        @Override
        public TreeCell<Object> call(TreeView<Object> p) {
            return new TextFieldTreeCell<Object>(new StringConverter<Object>(){
    
                @Override
                public String toString(Object object) {
                    return object.toString();
                }
    
                @Override
                public Object fromString(String string) {
                    return new Object();
                }
            });
        }
    });
    

    它的作用:它定义了一个StringConverter,它将返回一个新的Object实例在提交时输入TextField的任何字符串(因为Object不存储任何要识别的信息,这是您可以拥有的最好的信息)并将显示从Object 实例的toString() 方法获得的String

    但是:您应该提供一个数据模型供TreeView显示,它至少能够存储可以显示的文本数据。

    我已更新您的代码,以创建由一个非常简单的数据模型支持的TreeView示例

    它定义了树(Item 类)的数据模型,该类对项的名称有一个单一的属性。 TreeView 的通用参数设置为此 Item 类,因此 TreeView 能够显示 Item 实例。

    如你所见,我还定义了一个StringConverter,现在更有意义:fromString 方法在输入的文本被提交时执行,在这种情况下,该方法将返回一个新的Item 实例,其名称设置为输入字符串。需要toString 方法来指定如何以文本方式显示Item 实例。在我们的例子中,我们将返回特定实例的名称。

    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.control.cell.TextFieldTreeCell;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    import javafx.util.*;
    
    public class TreeViewSample2 extends Application {
    
        public static void main(String[] args) {
            launch(args);
        }
        TreeView<Item> tree;
    
        @Override
        public void start(Stage primaryStage) {
            primaryStage.setTitle("Tree View Sample");
    
            TreeItem<Item> rootItem = new TreeItem<Item>(new Item("Root"));
    
    
            rootItem.setExpanded(true);
            for (int i = 1; i < 6; i++) {
                TreeItem<Item> item = new TreeItem<Item>(new Item("Item"+i));
                rootItem.getChildren().add(item);
            }
    
            ContextMenu menu = new ContextMenu();
            MenuItem renameItem = new MenuItem("Rename");
            menu.getItems().add(renameItem);
    
            tree = new TreeView<Item>(rootItem);
            tree.setContextMenu(menu);
            tree.setEditable(true);
    
            tree.setCellFactory(new Callback<TreeView<Item>, TreeCell<Item>>() {
                @Override
                public TreeCell<Item> call(TreeView<Item> p) {
                    return new TextFieldTreeCell<Item>(new StringConverter<Item>(){
    
                        @Override
                        public String toString(Item object) {
                            return object.getName();
                        }
    
                        @Override
                        public Item fromString(String string) {
                            return new Item(string);
                        }
                    });
                }
            });
            renameItem.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    tree.edit(tree.getSelectionModel().getSelectedItem());
                }
            });
    
            tree.setOnEditCommit(new EventHandler<TreeView.EditEvent<Item>>() {
                @Override
                public void handle(TreeView.EditEvent<Item> event) {
                    System.out.println("Commit Value");
                }
            });
            StackPane root = new StackPane();
            root.getChildren().add(tree);
            primaryStage.setScene(new Scene(root, 300, 250));
            primaryStage.show();
        }
    }
    
    class Item {
        private SimpleStringProperty name = new SimpleStringProperty("");
        public SimpleStringProperty nameProperty() {
            return name;
        }
    
        public final String getName() { return nameProperty().get();}
        public final void setName(String newName) { nameProperty().set(newName);}
    
        public Item(String name) {
            setName(name);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多