JavaFX 从 TabContent(Node) 访问 Tab 或 TabPane
JavaFX get access to a Tab or TabPane from a TabContent(Node)
如果您仅引用 Tab
中的 Node
例如
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()
return 不感兴趣
TabPaneSkin
anon inner class TabContentRegion
: 两个陌生人。
我想说的是 Node.getParent()
应该 return parent Node
, 一般 uni-knowledge ( 节点在场景图中的表示可以使用 getParent() ) 进行跟踪,但是,当涉及到 Tab
时,它的都错了,所以我的问题
编辑
为什么我需要这个,假设你有 TabPane
由很多 Tab
组成,在一个特定的 Tab
中你有一个 TreeView
作为它的 Node-Content
,它是根据某些条件选择的,对于那个特定的 TreeView
,你有不同的自定义 Cell
,因为它的 TreeItem
在 UI 和功能上有所不同,比如改变 styles
绑定 Fonts
& 其他可绑定对象和动画 Tab
在 TabPane
中隐藏其他 Tab
,关闭其他 Tab
s
在这种情况下,遵循这种方法对我来说似乎是合法的,因为您不会做不必要的事情,例如将 children 暴露在恶劣天气下。 :-)
谢谢先生 James_D
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 ;
}
将 return 最近的 TabPane
包含传入的节点,或者 null
如果节点不在选项卡窗格中。
但是,需要这个就好像你的设计是错误的。如果您将一个节点放在选项卡窗格中,则在某个时候您会创建一个选项卡,因此您应该只组织您的代码,以便您可以引用该选项卡。
我知道这是一个有点老的问题,但我会 post 为仍在为这个问题苦苦挣扎的人提供解决方案。
下面是TabPane
.
的FXML结构示例
<!-- (1) -->
<TabPane>
<tabs>
<!-- (2) -->
<Tab>
<!-- (3) -->
<content>
<!-- (4) -->
<Pane>
<!-- (5) -->
<Node />
</Pane>
</content>
</Tab>
</tabs>
</TabPane>
以下方法 returns 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;
}
获取TabPane
对象和Tab
的tab内容区域
来自 Node
个对象的对象。
扫描 TabPane
中包含的所有 Tab
个对象(在阶段 #1 中检索)。
- 获取
Tab
对象,其内容区域等于 选项卡内容区域(在阶段 #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;
}
这是我的解决方案
获取 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;
}
如果您仅引用 Tab
中的 Node
例如
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()
return 不感兴趣
TabPaneSkin
anon inner class TabContentRegion
: 两个陌生人。
我想说的是 Node.getParent()
应该 return parent Node
, 一般 uni-knowledge ( 节点在场景图中的表示可以使用 getParent() ) 进行跟踪,但是,当涉及到 Tab
时,它的都错了,所以我的问题
编辑
为什么我需要这个,假设你有 TabPane
由很多 Tab
组成,在一个特定的 Tab
中你有一个 TreeView
作为它的 Node-Content
,它是根据某些条件选择的,对于那个特定的 TreeView
,你有不同的自定义 Cell
,因为它的 TreeItem
在 UI 和功能上有所不同,比如改变 styles
绑定 Fonts
& 其他可绑定对象和动画 Tab
在 TabPane
中隐藏其他 Tab
,关闭其他 Tab
s
在这种情况下,遵循这种方法对我来说似乎是合法的,因为您不会做不必要的事情,例如将 children 暴露在恶劣天气下。 :-)
谢谢先生 James_D
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 ;
}
将 return 最近的 TabPane
包含传入的节点,或者 null
如果节点不在选项卡窗格中。
但是,需要这个就好像你的设计是错误的。如果您将一个节点放在选项卡窗格中,则在某个时候您会创建一个选项卡,因此您应该只组织您的代码,以便您可以引用该选项卡。
我知道这是一个有点老的问题,但我会 post 为仍在为这个问题苦苦挣扎的人提供解决方案。
下面是TabPane
.
<!-- (1) -->
<TabPane>
<tabs>
<!-- (2) -->
<Tab>
<!-- (3) -->
<content>
<!-- (4) -->
<Pane>
<!-- (5) -->
<Node />
</Pane>
</content>
</Tab>
</tabs>
</TabPane>
以下方法 returns 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;
}
获取
TabPane
对象和Tab
的tab内容区域 来自Node
个对象的对象。扫描
TabPane
中包含的所有Tab
个对象(在阶段 #1 中检索)。- 获取
Tab
对象,其内容区域等于 选项卡内容区域(在阶段 #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;
}
这是我的解决方案
获取 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;
}