Is there a way to get a reference to Tab
or TabPane
without no improvised way if you have reference to only the Node
inside the Tab
for eg
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"));
assume i only have reference to drect
how can i get tab
.
I am not interested in Node.setUserData()
also drect.getParent().getClass().getName()
returns
TabPaneSkin
anon inner class TabContentRegion
: two strangers.
All i am trying to say is Node.getParent()
should return the parent Node
, general uni-knowledge ( node's representation in the scene graph can be traced with getParent() ), but, when it comes to Tab
s its all wrong, hence my question
EDIT
Why i needed this, suppose you have TabPane
consisting of soo many Tab
, in one particular Tab
you have a TreeView
s as its Node-Content
which is selected out of some conditions, and for that particular TreeView
you have different Custom Cell
s because its TreeItem
s differ in UI and function- like changing styles
binding Fonts
& other bindables and Animating Tab
hiding other Tab
s in the TabPane
, closing other Tab
s
with this scenario following this approach seems legit for me as, you do not do unnecessary stuff, like exposing children to bad weather. :-)
Thanks Sir James_D
The Tab
itself is not a Node
, so you can't get the tab just by iterating through the scene graph in any way. You can get to the TabPane
if you go up far enough in the hierarchy. For example:
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 ;
}
will return the nearest TabPane
containing the node passed in, or null
if the node is not in a tab pane.
However, needing this just seems like your design is wrong. If you put a node in a tab pane, at some point you create a tab, so you should just organize your code so you have the reference to the tab available.
I know this is a little old question, but I will post the solution for someone how is still struggling with this issue.
The following is the FXML structure example of the TabPane
.
<!-- (1) -->
<TabPane>
<tabs>
<!-- (2) -->
<Tab>
<!-- (3) -->
<content>
<!-- (4) -->
<Pane>
<!-- (5) -->
<Node />
</Pane>
</content>
</Tab>
</tabs>
</TabPane>
The following method returns the Tab
object which includes the Node
specified as an argument.
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;
}
Get the TabPane
object and the tab content area of the Tab
object from Node
object.
Scan all Tab
objects who are contained in the TabPane
(that is retrieved in the phase #1).
- Get the
Tab
object whose content area is equivalent to the tab content area (that is retrieved in the phase #1).
The simpler way is shown below.
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;
}