yoshegg
yoshegg

Reputation: 69

Disable TreeItem's default expand/collapse on double click (JavaFX 8)

How do I disable the default expand/collapse behaviour when double clicking a TreeItem in a TreeView?

My question is exactly the same as this one: Disable TreeItem's default expand/collapse on double click JavaFX 2.2 Unfortunately the provided answers don't work anymore (if they ever did).

UPDATE 1: Unfortunately I didn't know that it is important to mention that I don't use the standard TreeItem, but a modified one. Its constructor looks like this:

public BasicTreeItem(String text) {
  super();

  _label = new Label(text);
  stateIndicator = new ImageView();
  this.setToNever(); // sets the stateIndicator mentioned above

  _hb = new HBox();
  this.setValue(_hb);
  _hb.getChildren().add(stateIndicator);
  _hb.getChildren().add(_label);
  _hb.setAlignment(Pos.CENTER_LEFT);
}

So the thing that is seen in the end is the HBox.

Upvotes: 5

Views: 1659

Answers (1)

DVarga
DVarga

Reputation: 21799

You can for example use the CellFactory of the TreeView to attach an EventFilter on mouse listener to the TreeCells of the tree.

Example:

public class TreeViewExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        StackPane root = new StackPane();

        TreeView tw = new TreeView();
        TreeItem rootNode = new TreeItem("Root");
        TreeItem blockOne = new TreeItem("Block1");
        TreeItem childA = new TreeItem("ChildA");
        TreeItem childB = new TreeItem("ChildB");
        blockOne.getChildren().add(childA);
        blockOne.getChildren().add(childB);
        TreeItem blockTwo = new TreeItem("Block2");
        TreeItem childC = new TreeItem("ChildC");
        TreeItem childD = new TreeItem("ChildD");
        blockTwo.getChildren().add(childC);
        blockTwo.getChildren().add(childD);
        rootNode.getChildren().add(blockOne);
        rootNode.getChildren().add(blockTwo);
        tw.setRoot(rootNode);


        tw.setCellFactory(param -> {
            TreeCell<String> treeCell = new TreeCell<String>() {
                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item == null || empty) {
                        setText("");
                        setGraphic(null);
                        return;
                    }

                    setText(item.toString());
                }
            };

            treeCell.addEventFilter(MouseEvent.MOUSE_PRESSED, (MouseEvent e) -> {
                if (e.getClickCount() % 2 == 0 && e.getButton().equals(MouseButton.PRIMARY))
                    e.consume();
            });
            return treeCell;
        });

        root.getChildren().add(tw);
        Scene scene = new Scene(root, 300, 250);
        primaryStage.setTitle("TreeView!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

Update for your particulat use case:

First of all, your TreeItem implementation is really strange, as it must be something like:

class BasicTreeItem extends TreeItem<HBox>

It's a bad practice to use GUI elements as model. You could implement a class that is able to store all the states that each item can have, and use that class as model for the TreeView and also as generic parameter for your BasicTreeItem implementation.

But to answer the update question: If you want to have the double-click expand behaviour when the Label is double clicked, but you dont want to have it if the ImageView is double clicked.

In this case you can remove the CellFactory completely and add the EventFilter to the ImageView (e.g. in your BasicTreeItem constructor):

stateIndicator.addEventFilter(MouseEvent.MOUSE_PRESSED, (MouseEvent e) -> {
    if (e.getClickCount() % 2 == 0 && e.getButton().equals(MouseButton.PRIMARY))
        e.consume();
});

With this fitler your TreeItem will have the standard double-click behaviour except double clicking on the ImageView.

Upvotes: 7

Related Questions