facewindu
facewindu

Reputation: 715

Prevent selection of Tree Cell from right-click on Tree View Cell

I'm developing a custom TreeView object. I'm using a custom cellFactory to provide the TreeCell objects of my TreeView. This allows me to install custom Context Menu on the various cells, depending on the Item they are displaying.

But I'm not entirely satisfied with the behaviour.

When left-clicking on cell, it gets selected (OK) But when right-clicking a cell, the context menu is displayed (OK) but the cell is also selected. (NOK)

How can I change this behaviour ?

I tried to implement an eventFilter on the tree view, to consume the event if it is a right-click but this doesn't change anything, the above behaviour still applies.

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()));
            }
        }
    }
}

Upvotes: 0

Views: 939

Answers (2)

Diarsid
Diarsid

Reputation: 96

Previous Facewindu answer is actually working, but there is another way to achieve that behavior and still have context menu appearing on right click:

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();
            }
        });

Upvotes: 1

facewindu
facewindu

Reputation: 715

Reacting on Tony's comment

Creating a custom EventDispatcher does the trick.

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;
    }

}

The behaviour is identical for all events, except the right click event, which is consumed, thus preventing the right-click selection of any TreeCell.

Luckily enough, the context menu is still displayed on right click (although I don't understand why ...) Does anybody have a clue ?

Upvotes: 1

Related Questions