问题
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 Tabs 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 TreeViews as its Node-Content which is selected out of some conditions, and for that particular TreeView you have different Custom Cells because its TreeItems differ in UI and function- like changing styles binding Fonts& other bindables and Animating Tab hiding other Tabs in the TabPane, closing other Tabs
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
回答1:
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.
回答2:
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
TabPaneobject and the tab content area of theTabobject fromNodeobject.Scan all
Tabobjects who are contained in theTabPane(that is retrieved in the phase #1).- Get the
Tabobject 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;
}
来源:https://stackoverflow.com/questions/33186784/javafx-get-access-to-a-tab-or-tabpane-from-a-tabcontentnode