JavaFX:如何设置 TabPane header onClick 事件的侦听器

JavaFX: How to set a listener to the TabPane header onClick event

这是一个奇怪的问题,所以我会尽力正确地解释自己。

我想要的是在 TabPane 中的 Tab 被点击时触发一个事件,“点击”我的意思是只是点击,不一定被选中。

我已经尝试使用 TabselectedProperty,但只有在未选中 Tab 时单击它才会调用事件,即使在已选中时单击它也不会调用。

我这样做的原因是我试图制作一个可折叠的选项卡窗格,如果您再次单击打开的选项卡,它会隐藏 TabPane 的内容,我已经编写了用于折叠的代码TabPane 并且有效但是......我不知道如何从选项卡 header.

获取点击事件

我什至还查看了 TabPane 源代码,希望我能找到选项卡 header 容器,但我没有在那里找到它。

无需全新的皮肤 - 我们可以通过查找访问 header 节点。当心:意味着依赖实现细节,这些细节可能会因版本而异。

要查找的(未记录!)样式 ID 是“.tab-container”——这是唯一的 child TabHeaderSkin(== 单个选项卡的区域 header) .它包含标签、关闭按钮(如果有)和焦点标记。此“皮肤”在其属性中保留对其选项卡的引用(当然未记录;)

所以基本的方法是

  • 在皮肤安装后查找所有tab-container秒
  • 对于每个,在其 parent
  • 上注册一个合适的鼠标处理程序
  • 在相应的 mouseEvent 上,做任何需要的事情

请注意,在修改选项卡列表时,听众必须为removed/added(未包含在下面的摘要中)。

在示例代码中:

/** 
 * looks up the styled part of tab header and installs a mouseHandler
 * which calls the work load method.
 * 
 * @param tabPane
 */
private void installTabHandlers(TabPane tabPane) {
    Set<Node> headers = tabPane.lookupAll(".tab-container");
    headers.forEach(node -> {
        // implementation detail: header of tabContainer is the TabHeaderSkin
        Parent parent = node.getParent();
        parent.setOnMouseClicked(ev -> handleHeader(parent));
    });
}

/**
 * Workload for tab.
 * @param tabHeaderSkin
 */
private void handleHeader(Node tabHeaderSkin) {
    // implementation detail: skin keeps reference to associated Tab
    Tab tab = (Tab) tabHeaderSkin.getProperties().get(Tab.class);
    System.out.println("do stuff for tab: " + tab.getText());
}