通过右键单击树视图单元格来防止选择树单元格

时间:2014-01-12 18:15:48

标签: treeview javafx-2

我正在开发一个自定义的TreeView对象。 我正在使用自定义cellFactory来提供TreeView的TreeCell对象。 这允许我在各个单元格上安装自定义上下文菜单,具体取决于它们显示的项目。

但我对这种行为并不完全满意。

当左键单击单元格时,它会被选中(OK) 但右键单击一个单元格时,将显示上下文菜单(确定),但也会选中该单元格。 (NOK)

如何更改此行为?

我尝试在树视图上实现一个eventFilter,如果它是右键单击但是这不会改变任何东西,则使用该事件,上述行为仍然适用。

addEventFilter(MouseEvent.MOUSE_CLICKED,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        if (event.getButton() == MouseButton.SECONDARY) {
                            event.consume();
                        }
                    }
                });

setCellFactory(new Callback<TreeView<TreeDisplayable>, TreeCell<TreeDisplayable>>() {
            @Override
            public TreeCell<TreeDisplayable> call(
                    final TreeView<TreeDisplayable> treeView) {
                return new TreeDisplayableTreeCell(owner, javaModel);
            }
        });



public class TreeDisplayableTreeCell extends TreeCell<TreeDisplayable> {
... 
    @Override
    public void updateItem(TreeDisplayable item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
            setText(getItem().treeViewString());
            setGraphic(item.getPic());
            if (getTreeItem().getParent() == null) {
                // it means it's the root node
                setContextMenu(new RootItemContextMenu(javaModel, owner));
            } else {
                setContextMenu(new TreeItemContextMenu(javaModel, owner,getTreeItem().getValue()));
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

对Tony的评论作出反应

创建自定义EventDispatcher可以解决问题。

public class TreeEventDispatcher implements EventDispatcher {

    @Override
    public Event dispatchEvent(Event event, EventDispatchChain tail) {
        if (event instanceof MouseEvent) {
            MouseEvent mouseEvent = (MouseEvent) event;
            if (mouseEvent.getButton() == MouseButton.SECONDARY) {
                event.consume();
            } else {
                event = tail.dispatchEvent(event);
            }
        } else {
            event = tail.dispatchEvent(event);
        }
        return event;
    }

}

除了使用的右键单击事件之外,所有事件的行为都是相同的,因此阻止了对任何TreeCell的右键单击选择。

幸运的是,右键单击仍显示上下文菜单(虽然我不明白为什么......)有人有线索吗?

答案 1 :(得分:0)

上一个 Facewindu 答案实际上是有效的,但是还有另一种方法可以实现该行为,并且右键单击仍显示上下文菜单:

treeView.addEventFilter(MOUSE_PRESSED, event -> {
            if (event.isSecondaryButtonDown()) {
                Node text = (Node) event.getTarget();
                TreeCell<...> treeCell = (TreeCell<...>) text.getParent();
                treeCell.getContextMenu().show(treeCell, 0, 0);
                event.consume();
            }
        });