禁用TreeItem';双击时的默认展开/折叠(JavaFX8)

禁用TreeItem';双击时的默认展开/折叠(JavaFX8),java,javafx,treeview,javafx-8,Java,Javafx,Treeview,Javafx 8,在树视图中双击树项时,如何禁用默认的展开/折叠行为 我的问题和这个完全一样: 不幸的是,提供的答案不再有效(如果它们曾经有效的话) 更新1: 不幸的是,我不知道有一点很重要,那就是我没有使用标准的TreeItem,而是使用了一个修改过的。其构造函数如下所示: public BasicTreeItem(String text) { super(); _label = new Label(text); stateIndicator = new ImageView(); this.s

在树视图中双击树项时,如何禁用默认的展开/折叠行为

我的问题和这个完全一样: 不幸的是,提供的答案不再有效(如果它们曾经有效的话)

更新1: 不幸的是,我不知道有一点很重要,那就是我没有使用标准的
TreeItem
,而是使用了一个修改过的。其构造函数如下所示:

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

因此,最后看到的是HBox。

例如,您可以使用
TreeView
的将鼠标上的
EventFilter
侦听器附加到树的s

示例:

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();
    }
}
使用GUI元素作为模型是一种不好的做法。您可以实现一个类,该类能够存储每个项可以具有的所有状态,并将该类用作
TreeView
的模型,以及
BasicTreeItem
实现的通用参数

但是要回答更新问题:如果您希望在双击
标签
时具有双击展开行为,但是如果双击
图像视图
则不希望具有该行为

在这种情况下,您可以完全移动
CellFactory
,并将
EventFilter
添加到
ImageView
(例如,在
BasicTreeItem
构造函数中):


使用此fitler,您的
TreeItem
将具有标准的双击行为,除了双击
ImageView

好奇:为什么要更改标准(至少在win上)用户体验?典型用户对这些调整不满意;)我的TreeItems由一个特殊的复选框组成,其中有4个不同的状态,我希望快速更改。如果我在树上点击太快,树就会展开/折叠,这是我不想看到的。但是,如果我双击标签,我仍然希望该项目展开/折叠。感谢提供信息:)非常感谢。不幸的是,我忘了提到我使用了一个自己版本的TreeItem,我现在将它添加到了原始问题中。如果你知道如何为此设置CellFactory,我会非常高兴:)我做到了:)。在我的下一个项目中,我肯定不再使用GUI元素作为模型了,但现在我已经走了很长的一段路来修改所有的东西。只是想弄清楚,你所说的“使用GUI元素作为模型是一种不好的做法”是什么意思?这是因为使用了
HBox```(它实际上只是用来在
TreeView`中显示相关信息,还是因为我在
TreeItem
中存储数据?基本上,我想知道
TreeItem
是否是一个可以存储数据的模型(通过扩展
TreeItem
类)或者甚至用更多的数据来存储一个树状的数据结构。
class BasicTreeItem extends TreeItem<HBox>
stateIndicator.addEventFilter(MouseEvent.MOUSE_PRESSED, (MouseEvent e) -> {
    if (e.getClickCount() % 2 == 0 && e.getButton().equals(MouseButton.PRIMARY))
        e.consume();
});