JavaFX从TabContent(节点)访问选项卡或TabPane

JavaFX从TabContent(节点)访问选项卡或TabPane,java,javafx,javafx-2,javafx-8,Java,Javafx,Javafx 2,Javafx 8,如果您只引用了选项卡中的节点,是否有一种方法可以在没有临时方法的情况下获取对选项卡或选项卡的引用 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

如果您只引用了
选项卡
中的
节点
,是否有一种方法可以在没有临时方法的情况下获取对
选项卡
选项卡
的引用

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
如何获取
选项卡
。 我对
Node.setUserData()
也不感兴趣
drect.getParent().getClass().getName()
返回
TabPaneSkin
anon内部类
TabContentRegion
:两个陌生人

我想说的是
节点。getParent()
应该返回父节点
节点
,一般的uni-knowledge节点在场景图中的表示可以用getParent()来跟踪),但是,当涉及到
选项卡时,它是完全错误的,因此我的问题

编辑

为什么我需要这个,假设你有一个
TabPane
由很多
Tab
组成,在一个特定的
Tab
中,你有一个
TreeView
s作为它的
节点内容
,它是从一些条件中选择的,对于特定的
TreeView
您有不同的自定义
单元格
s,因为它的
TreeItem
s在UI和功能上有所不同,比如更改
样式
绑定
字体
&其他绑定和动画
选项卡
选项卡
中隐藏其他
选项卡
,关闭其他
选项卡
s

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


感谢James_D爵士

选项卡
本身不是
节点
,因此您无法通过任何方式迭代场景图来获取选项卡。如果您在层次结构中的位置足够高,则可以访问
选项卡窗格
。例如:

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


然而,需要这样做似乎你的设计是错误的。如果在选项卡窗格中放置一个节点,那么在某个时候您会创建一个选项卡,因此您应该只组织代码,以便有对该选项卡的引用。

我知道这是一个有点老的问题,但我将为仍在努力解决此问题的人发布解决方案

以下是
选项卡窗格
的FXML结构示例

<!-- (1) -->
<TabPane>
  <tabs>
    <!-- (2) -->
    <Tab>
      <!-- (3) -->
      <content>
        <!-- (4) -->
        <Pane>
          <!-- (5) -->
          <Node />
        </Pane>
      </content>
    </Tab>
  </tabs>
</TabPane>
  • 获取
    选项卡窗格
    对象和
    选项卡的选项卡内容区域
    来自
    节点的对象
    对象

  • 扫描
    选项卡中包含的所有
    对象(在阶段1中检索)

  • 获取
    选项卡
    对象,其内容区域等于选项卡内容区域(在阶段1中检索)
  • 下面显示了更简单的方法

    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;
    }
    
    公共选项卡getParentTab2(节点){ TabPane TabPane=null; Tab=null; 节点tabContentRegion=null; 对于(Node n=Node.getParent();n!=null&&tabPane==null;n=n.getParent()){ 如果(n.getStyleClass()包含(“选项卡内容区域”)){ tabContentRegion=n; } if(n个选项卡窗格实例){ tabPane=(tabPane)n; } } if(tabPane!=null&&tabContentRegion!=null){ //对象的列表 ObservableList tabList=tabPane.getTabs(); 用于(选项卡t:小报列表){ 如果(t.getContent().getParent().equals(tabContentRegion)){ tab=t; 打破 } } } 返回选项卡; }
    这是我的解决方案

    要获取选项卡窗格,请执行以下操作:

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

    选项卡
    不是
    节点
    ,因此
    getParent()
    无法为您提供
    选项卡
    。因为你的节点“知道”它被添加到了一个标签中是没有意义的,除非你设计了一个标签,否则就没有办法从节点获取标签。在您发布的代码中,您有一个对选项卡的引用,因此如果您以后需要它,您只需要组织代码以访问它。也许可以编辑你的问题,从更广泛的意义上解释你想做什么。好吧,那么
    选项卡
    不是一个
    节点
    ,但是它的内容区域包含一个
    节点
    ,一个
    节点
    在场景图中的表示可以通过
    getParent()
    进行跟踪,所以为什么跟踪是不合法的,甚至
    上下文菜单
    MenuItem
    可以跟踪它们也不是
    节点
    s-我明白你的意思,但在正常关系中,应该有跟踪。这正是我想要的,但似乎没有什么比这更好的了。我会做一些编辑。顺便说一句,谢谢您的时间,先生@James_DIf如果您一直递归地调用
    getParent()
    ,在某个时候您会进入
    选项卡窗格
    ,不是吗?但真的,你应该解释为什么你需要这个(或者你认为你需要这个)。现在你在说:),让我试试,先生-如果它起作用,你会得到我的赏金。“然而……你的设计是错误的。”不,我只是在违反规则。我猜。:)马上回来
    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;
    }