可以使用JavaFX节点';是否已访问/确定的父类?

可以使用JavaFX节点';是否已访问/确定的父类?,java,class,javafx,javafx-8,parent,Java,Class,Javafx,Javafx 8,Parent,补充说明:虽然我没有找到一个干净的解决方案来解决我所说的问题,但根本问题是我试图解决“错误的问题”。这是由于在不同的JavaFX对象上调用initialize()的时间,并且很快就变丑了(例如,如果/当GridPane在Tab上设置适当的值之前访问Tab会发生什么情况?)。真正的解决方案是,在正确填充选项卡的值之后,后退一步,重新评估实现,并在GridPane上从选项卡使用setUserData()。仍然有点混乱,但比我最初尝试的要干净和可靠得多,这需要下面要求的解决方案 我正在向选项卡添加一个

补充说明:虽然我没有找到一个干净的解决方案来解决我所说的问题,但根本问题是我试图解决“错误的问题”。这是由于在不同的JavaFX对象上调用initialize()的时间,并且很快就变丑了(例如,如果/当GridPane在Tab上设置适当的值之前访问Tab会发生什么情况?)。真正的解决方案是,在正确填充选项卡的值之后,后退一步,重新评估实现,并在GridPane上从选项卡使用setUserData()。仍然有点混乱,但比我最初尝试的要干净和可靠得多,这需要下面要求的解决方案

我正在向选项卡添加一个GridPane,需要访问Tab.getText()。在GridPane的initialize()中,我可以使用GridPane.getParent()获取父级。但是,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);
    }
}

不过,你可能想找到一个更好的方法。例如,您是否可以直接插入选项卡而不是(或同时)插入网格窗格。似乎无论你需要做什么,都应该在一个“知道”选项卡的级别上进行处理。在最坏的情况下,您可以将网格窗格的文本设置为选项卡的文本。但这感觉像是一个问题:你根本不需要这样做。

没有特别干净的方法来做这件事。在场景等中放置选项卡后,可以向上迭代节点层次,直到找到选项卡窗格,然后迭代选项卡窗格的选项卡列表,查看内容是否与节点匹配。例如:

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

不过,你可能想找到一个更好的方法。例如,您是否可以直接插入选项卡而不是(或同时)插入网格窗格。似乎无论你需要做什么,都应该在一个“知道”选项卡的级别上进行处理。在最坏的情况下,您可以将网格窗格的文本设置为选项卡的文本。但这感觉像是:你根本不需要这样做。

我发现最简单的方法就是创建Gridpane的子类,并在构建它时将它添加到选项卡中。

我发现最简单的方法就是创建Gridpane的子类,并在构建时将它添加到选项卡中它。

我问这个问题已经有一段时间了,我已经修改了实现,这不再是一个问题

解决方案是放弃在FXML中声明控制器,并以编程方式将控制器与FXMLLoader实例关联。这允许在加载/实例化GridPane之前,将信息传递给GridPane的控制器(通过构造函数或其他公共方法)

这样做,所需的信息已经驻留在控制器中,并且可以在初始化期间访问


生活和学习…

我问这个问题已经有一段时间了,我已经修改了实现,这不再是一个问题

解决方案是放弃在FXML中声明控制器,并以编程方式将控制器与FXMLLoader实例关联。这允许在加载/实例化GridPane之前,将信息传递给GridPane的控制器(通过构造函数或其他公共方法)

这样做,所需的信息已经驻留在控制器中,并且可以在初始化期间访问


生活和学习…

是的,这件事很快就变得很糟糕,我觉得我找错了方向(尽管我仍然对它感兴趣)。底线是涉及到一系列初始值设定项,因此“父节点”甚至没有填充,因为节点直到创建之后才添加到父节点中(即,在子节点的initialize()终止之后,尝试执行我尝试的操作为时已晚)。因为所有的UI组件都是针对一个公共数据模型构建的,所以我通过在模型的MOD实际完成后在数据模型上触发一个事件来管理所需的行为。是的,这很快就变得很糟糕,我确定我选错了树(尽管我仍然感兴趣)。底线是涉及到一系列初始值设定项,因此“父节点”甚至没有填充,因为节点直到创建之后才添加到父节点中(即,在子节点的initialize()终止之后,尝试执行我尝试的操作为时已晚)。因为所有的UI组件都是根据一个公共数据模型构建的,所以我通过在模型的MOD实际完成后在数据模型上触发一个事件来管理所需的行为。但是,我正试图走FXML路线,问题最终是-initialize()的计时问题(请参阅上面的注释)。如果我手动滚动GridPane,这将起作用。但是,我正试图走FXML路线,问题最终是-initialize()的计时问题(参见上面的评论)。的可能重复请看:请看: