Edit item in JavaFX TreeView


Question

I have this custom TreeView code:

treeView.setCellFactory(new Callback<TreeView<Tree>, TreeCell<Tree>>()
        {
            @Override
            public TreeCell<Tree> call(TreeView<Tree> treeView)
            {
                final TreeCell<Tree> cell = new TreeCell<Tree>()
                {
                    @Override
                    protected void updateItem(Tree item, boolean empty)
                    {
                        super.updateItem(item, empty);
                        if (!empty)
                        {
                            setText(item != null ? item.toString() : "");
                            setGraphic(createImageView(item));
                            setContextMenu(createContextMenuTreeItem(item));
                        }
                        else
                        {
                            setText(null);
                            setGraphic(null);
                            setContextMenu(null);
                        }
                    }
                };

                return cell;
            }
        });

I would like to be able to rename the nodes of the tree using Content Menu. Can you help me to implement this?

1
5
9/2/2014 12:47:16 PM

Accepted Answer

You could simply start the editing of a tree node in MenuItem's EventHandler. Here is an example code that allow the basic editing by double clicking(I didn't try to alter/prevent that) and also from the context menu:

import javafx.application.Application;
import javafx.event.*;
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.*;
import javafx.util.converter.DefaultStringConverter;

public class TreeViewSample extends Application {

    public static void main(String[] args) {
        launch(args);
    }

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

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

        TreeView<String> tree = new TreeView<String> (rootItem);
        tree.setEditable(true);
        tree.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>(){
            @Override
            public TreeCell<String> call(TreeView<String> p) {
                return new RenameMenuTreeCell();
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(tree);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }

    private static class RenameMenuTreeCell extends TextFieldTreeCell<String> {
        private ContextMenu menu = new ContextMenu();

        public RenameMenuTreeCell() {
            super(new DefaultStringConverter());

            MenuItem renameItem = new MenuItem("Rename");
            menu.getItems().add(renameItem);
            renameItem.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent arg0) {
                    startEdit();
                }
            });
        }

        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);

            if (!isEditing()) {
                setContextMenu(menu);
            }
        }
    }
}

This is basically Oracle's example 13-1 with custom tree cells.

8
9/7/2014 3:15:10 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon