簡體   English   中英

JavaFX TreeView 編輯項

[英]JavaFX TreeView edit item

我正在嘗試編輯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<String>(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.

我怎樣才能減輕這個異常。

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 ,它將在提交時從輸入到TextField的任何字符串返回一個新的Object實例(因為Object不存儲任何要識別的信息,這是你可以擁有的最好的),並將顯示得到的String來自Object實例的toString()方法。

但是:您應該為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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM