JavaFX可以从TabContent(节点)访问Tab或TabPane

时间:2015-10-17 12:45:54

标签: java javafx javafx-2 javafx-8

如果您仅参考Tab内的TabPane,那么有没有办法在没有临时方式的情况下获得NodeTab的引用

TabPane tabPane = new TabPane();
Tab tab = new Tab();
tab.setText("new tab");
Rectangle drect = new Rectangle(200,200, Color.LIGHTSTEELBLUE);
tab.setContent(drect);
tabPane.getTabs().addAll(tab,new Tab("tab 2"));

假设我只提及drect我如何获得tab。 我对Node.setUserData()drect.getParent().getClass().getName()返回不感兴趣 TabPaneSkin anon内部班TabContentRegion:两个陌生人。

所有我想说的是Node.getParent()应该返回父Node,一般单知识 节点在场景图中的表示可以跟踪getParent() ,但是,当谈到Tab时,它的全部错误,因此我的问题

修改

为什么我需要这个,假设您TabPane由很多Tab组成,在一个特定的Tab TreeViewNode-ContentTreeView这是从某些条件中选择的,对于特定Cell,您有不同的自定义TreeItem,因为其styles在UI和功能方面有所不同,例如更改Fonts绑定{ {1}}&安培;其他可绑定项和动画Tab隐藏Tab中的其他TabPane,关闭其他Tab

按照这种方法遵循这种方法对我来说似乎是合法的,因为你不会做不必要的事情,比如让孩子暴露在恶劣的天气里。 :-)

感谢詹姆斯爵士

3 个答案:

答案 0 :(得分:1)

Tab本身不是Node,因此您无法通过以任何方式迭代场景图来获取标签。如果你在层次结构中走得足够远,你可以到达TabPane。例如:

private TabPane findTabPaneForNode(Node node) {
    TabPane tabPane = null ;

    for (Node n = node.getParent(); n != null && tabPane == null; n = n.getParent()) {
        if (n instanceof TabPane) {
            tabPane = (TabPane) n;
        }
    }

    return tabPane ;
}

将返回包含传入节点的最近TabPane,如果节点不在选项卡窗格中,则返回null

然而,需要这个似乎是你的设计错了。如果您在选项卡窗格中放置一个节点,则在某个时刻创建一个选项卡,因此您应该只组织代码,以便引用可用的选项卡。

答案 1 :(得分:0)

我知道这是一个有点老问题,但我会为某人解决这个问题仍在努力解决这个问题。

以下是TabPane

的FXML结构示例
<!-- (1) -->
<TabPane>
  <tabs>
    <!-- (2) -->
    <Tab>
      <!-- (3) -->
      <content>
        <!-- (4) -->
        <Pane>
          <!-- (5) -->
          <Node />
        </Pane>
      </content>
    </Tab>
  </tabs>
</TabPane>

以下方法返回Tab对象,其中包含指定为参数的Node

public static Tab getParentTab1(Node node) {
    // <TabPane> object (described as (1) in the FXML example)
    TabPane tabPane = null;

    // <Tab> object (described as (2))
    Tab tab = null;

    // The object of the tab content area
    Node tabContentRegion = null;

    ClassLoader loader = ClassLoader.getSystemClassLoader();
    Class<?> innerClass = null;

    try {
        innerClass = loader.loadClass("com.sun.javafx.scene.control.skin.TabPaneSkin$TabContentRegion");
    } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
    }

    for (Node n = node.getParent(); n != null && tabPane == null; n = n.getParent()) {
        // If the node is an instance of the inner class of TabPaneSkin
        if (n.getClass().isAssignableFrom(innerClass)) {
            tabContentRegion = n;
        }

        if (n instanceof TabPane) {
            tabPane = (TabPane) n;
        }
    }

    if (tabPane != null && tabContentRegion != null) {
        // The list of the <Tab> objects
        ObservableList<Tab> tabList = tabPane.getTabs();

        for (Tab t : tabList) {
            // t.getContent() returns the first <Node> object on the <Tab> (most likely it's a <Pane> described as (4))
            // t.getContent().getParent() returns the TabPaneSkin$TabContentRegion object
            System.out.println("content: " + t.getContent());
            System.out.println("parent: " + t.getContent().getParent());

            if (t.getContent().getParent().equals(tabContentRegion)) {
                tab = t;
                break;
            }
        }
    }

    return tab;
}
  1. 获取TabPane对象和Tab标签内容区域 来自Node对象的对象。

  2. 扫描Tab中包含的所有TabPane个对象(在阶段#1中检索到的对象)。

  3. 获取内容区域等于标签内容区域Tab对象(在阶段#1中检索)。
  4. 更简单的方法如下所示。

    public Tab getParentTab2(Node node) {
        TabPane tabPane = null;
        Tab tab = null;
        Node tabContentRegion = null;
    
        for (Node n = node.getParent(); n != null && tabPane == null; n = n.getParent()) {
            if (n.getStyleClass().contains("tab-content-area")) {
                tabContentRegion = n;
            }
    
            if (n instanceof TabPane) {
                tabPane = (TabPane) n;
            }
        }
    
        if (tabPane != null && tabContentRegion != null) {
            // The list of the <Tab> objects
            ObservableList<Tab> tabList = tabPane.getTabs();
    
            for (Tab t : tabList) {
                if (t.getContent().getParent().equals(tabContentRegion)) {
                    tab = t;
                    break;
                }
            }
        }
    
        return tab;
    }
    

答案 2 :(得分:0)

这是我的解决方案

获取 TabPane:

private TabPane getParentTabPane(Node node) {

    if(node==null)
        return null;

    final Parent parent = node.getParent();
    return Optional.of(parent).filter(TabPane.class::isInstance).map(TabPane.class::cast).orElseGet(()->getParentTabPane(parent));
}

获取标签:

private Tab getParentTab(Node node) {

    Tab tab = null;
    while(node!=null) {

        final Parent stackPane = node.getParent();
        if(!(stackPane instanceof StackPane)) {
            node = stackPane;
            continue;
        }

        final Parent tabPane = stackPane.getParent();
        if(!(tabPane instanceof TabPane)) {
            node = tabPane;
            continue;
        }

        final Node n = node;
        tab = Optional.ofNullable((TabPane)tabPane).map(TabPane::getTabs).map(List::parallelStream).orElseGet(()->Stream.empty()).filter(t->t.getContent()==n).findAny().orElse(null);
        break;
    }

     return tab;
}