3

我目前正在研究 TreeView,并希望实现一个在 TreeCell 上右键单击时弹出的 ContextMenu。我已经研究了这些示例,但我不确定如何将 ContextMenu 设置为在每个单元格上弹出,而不仅仅是那些充满孩子的单元格。

Here my code (pretty much the sample code):

Constructor
.
.
.

this.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>()
    {
            @Override
            public TreeCell<String> call(TreeView<String> p) 
            {
                return new TextFieldTreeCellImpl();
            }
        });
    }

    private final class TextFieldTreeCellImpl extends TreeCell<String> 
    {

        private TextField textField;
        private ContextMenu addMenu = new ContextMenu();

        @SuppressWarnings({ "rawtypes", "unchecked" })
    public TextFieldTreeCellImpl() 
        {
            MenuItem addMenuItem = new MenuItem("Add Note");
            addMenu.getItems().add(addMenuItem);
            addMenuItem.setOnAction(new EventHandler() 
            {
                public void handle(Event t) 
                {
                    ImageView noteIcon = new ImageView(new Image(getClass().getResourceAsStream("../icons/note.png")));
            noteIcon.setFitHeight(16);
            noteIcon.setFitWidth(16);

                    TreeItem newNote = new TreeItem<String>("New Note");
                    getTreeItem().getChildren().add(newNote);
                }
            });
        }

        @Override
        public void startEdit() 
        {
            super.startEdit();

            if (textField == null) 
            {
                createTextField();
            }
            setText(null);
            setGraphic(textField);
            textField.selectAll();
        }

        @Override
        public void cancelEdit() 
        {
            super.cancelEdit();

            setText((String) getItem());
            setGraphic(getTreeItem().getGraphic());
        }

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

            if (empty) 
            {
                setText(null);
                setGraphic(null);
            } 
            else
            {
                if (isEditing()) 
                {
                    if (textField != null) 
                    {
                        textField.setText(getString());
                    }
                    setText(null);
                    setGraphic(textField);
                } 
                else 
                {
                    setText(getString());
                    setGraphic(getTreeItem().getGraphic());
                    if (!getTreeItem().isLeaf()&&getTreeItem().getParent()!= null)
                    {
                        setContextMenu(addMenu);
                    }
                }
            }
        }

        private void createTextField() 
        {
            textField = new TextField(getString());
            textField.setOnKeyReleased(new EventHandler<KeyEvent>() 
            {
                @Override
                public void handle(KeyEvent t) 
                {
                    if (t.getCode() == KeyCode.ENTER) 
                    {
                        commitEdit(textField.getText());
                    } 
                    else if (t.getCode() == KeyCode.ESCAPE) 
                    {
                        cancelEdit();
                    }
                }
            });     
        }

        private String getString() 
        {
            return getItem() == null ? "" : getItem().toString();
        }
    }
}
4

1 回答 1

2

仅将 contextMenu 显示为“充满子项”的单元格由以下行控制:

if (!getTreeItem().isLeaf() && getTreeItem().getParent() != null) {
    setContextMenu(addMenu);
}

删除 if 控件以将 contextMenu 弹出到所有节点/单元格。

于 2012-07-01T23:59:54.640 回答