Add Note:虽然我没有找到一个干净的解决方案来解决我所陈述的问题,但根本问题原来是我试图解决"错误的问题"。这是由于在不同的JavaFX对象上调用initialize()的时间,并且很快变得丑陋(即,如果/当GridPane在Tab上设置适当的值之前访问Tab会发生什么?)。真正的解决方案是后退一步,重新评估实现,并在Tab的值正确填充后,在GridPane上从Tab使用setUserData()。仍然有点拼凑,但比我最初尝试的要干净和可靠得多,这需要下面要求的解决方案。
我正在添加GridPane到一个选项卡,我需要访问Tab. gettext()。在GridPane的initialize()中,我可以使用GridPane. getparent()获得Parent。但是,Parent不实现getText(),我不能做(Tab)Parent,也不能使用instanceof.
我已经找到了访问GridPane的控制器的机制,但我真的不想这样做,除非必要(即,我希望GridPane实例做"正确的事情"没有外部刺激)。
我知道下面的代码片段不能编译/运行,但是有没有一种干净的方式来完成代码背后的想法?
@FXML private GridPane gridPane;
@FXML
public void initialize() {
Parent parent = gridPane.getParent();
if (parent instanceof Tab) {
String foo = (( Tab )parent).getText();
}
}
没有特别干净的方法来做到这一点。一旦选项卡被放置在场景中,你就可以迭代节点层次,直到找到一个选项卡面板,然后迭代选项卡面板的选项卡列表,看看内容是否与节点匹配。例如:
import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;
public class TabPaneTest extends Application {
@Override
public void start(Stage primaryStage) {
TabPane pane = new TabPane();
Tab tab = new Tab("Test tab");
Label label = new Label("Test Label");
tab.setContent(label);
pane.getTabs().addAll(tab);
primaryStage.setScene(new Scene(pane));
primaryStage.show();
for (Node n = label ; n != null ; n = n.getParent()) {
if (n instanceof TabPane) {
System.out.println("Found Tab Pane...");
for (Tab t : ((TabPane)n).getTabs()) {
if (t.getContent() == label) {
System.out.println("Tab containing label: "+t.getText());
}
}
}
}
}
public static void main(String[] args) {
launch(args);
}
}
你可能想找到一个更好的方法来做到这一点。例如,你可以直接注入选项卡,而不是(或者)注入网格窗格吗?似乎无论你需要做什么,都应该在一个"知道"标签的级别上处理。在最坏的情况下,您可以将网格窗格的用户数据设置为选项卡的文本。但这感觉像是一个x-y问题:您根本不需要这样做。
我发现这样做的最简单的方法就是创建Gridpane的子类,并在构建它时为它添加标签
我问这个问题已经有一段时间了,我已经修改了实现,这不再是一个问题。
解决方案是放弃在FXML中声明控制器,并以编程方式将控制器与FXMLLoader实例关联。这允许在 GridPane被加载/实例化之前将信息传递给GridPane的控制器(通过构造函数或其他公共方法)。
这样做,所需的信息已经驻留在控制器中,可以在初始化时访问。