JavaFX 节点的父节点 class 可以 accessed/determined 吗?
Can a JavaFX node's parent class by accessed/determined?
添加注意:虽然我没有找到解决我所述问题的干净解决方案,但根本问题原来是我试图解决 "wrong problem"。这是由于在不同的 JavaFX 对象上调用 initialize() 的时间,并且很快变得丑陋(即,在 Tab 上设置适当的值之前 if/when GridPane 访问 Tab 会发生什么?) .真正的解决方案是退后一步,重新评估实现,并在 Tab 的值被正确填充后,在 Tab 的 GridPane 上使用 setUserData()。仍然有点混乱,但比我最初尝试的更清晰可靠,这需要下面要求的解决方案。
我正在将 GridPane 添加到选项卡,我需要访问 Tab.getText()。在 GridPane 的 initialize() 中,我可以使用 GridPane.getParent() 获取 Parent。但是,Parent 没有实现 getText(),我不能做 (Tab)Parent,也不能使用 instanceof.
我找到了访问 GridPane 控制器的机制,但我真的不想这样做,除非有必要(即,我希望 GridPane 实例在没有外部访问权限的情况下执行 "the right thing"刺激)。
我知道下面的代码片段没有 compile/run,但是是否有一种干净的方法来实现代码背后的想法?
@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);
}
}
尽管如此,您可能想找到更好的方法。例如。您可以直接注入选项卡而不是(或同时)注入网格窗格吗?似乎无论您需要做什么,都应该在 "knows about" 选项卡的级别进行处理。在最坏的情况下,您可以设置 user data of the grid pane to the text of the tab. But this feels like an x-y problem:您根本不需要这样做。
我发现最简单的方法就是创建 Gridpane 的子类,并在构建它时将其添加到选项卡中。
我问这个问题已经有一段时间了,后来我修改了实现,这不再是问题。
解决方案是放弃在 FXML 中声明控制器,并以编程方式将控制器关联到 FXMLLoader 实例。这允许将信息传递给 GridPane 的控制器(通过构造函数或其他 public 方法)在 GridPane 成为 loaded/instantiated.
之前
这样做,需要的信息已经驻留在控制器中,可以在初始化时访问。
生活和学习...
添加注意:虽然我没有找到解决我所述问题的干净解决方案,但根本问题原来是我试图解决 "wrong problem"。这是由于在不同的 JavaFX 对象上调用 initialize() 的时间,并且很快变得丑陋(即,在 Tab 上设置适当的值之前 if/when GridPane 访问 Tab 会发生什么?) .真正的解决方案是退后一步,重新评估实现,并在 Tab 的值被正确填充后,在 Tab 的 GridPane 上使用 setUserData()。仍然有点混乱,但比我最初尝试的更清晰可靠,这需要下面要求的解决方案。
我正在将 GridPane 添加到选项卡,我需要访问 Tab.getText()。在 GridPane 的 initialize() 中,我可以使用 GridPane.getParent() 获取 Parent。但是,Parent 没有实现 getText(),我不能做 (Tab)Parent,也不能使用 instanceof.
我找到了访问 GridPane 控制器的机制,但我真的不想这样做,除非有必要(即,我希望 GridPane 实例在没有外部访问权限的情况下执行 "the right thing"刺激)。
我知道下面的代码片段没有 compile/run,但是是否有一种干净的方法来实现代码背后的想法?
@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);
}
}
尽管如此,您可能想找到更好的方法。例如。您可以直接注入选项卡而不是(或同时)注入网格窗格吗?似乎无论您需要做什么,都应该在 "knows about" 选项卡的级别进行处理。在最坏的情况下,您可以设置 user data of the grid pane to the text of the tab. But this feels like an x-y problem:您根本不需要这样做。
我发现最简单的方法就是创建 Gridpane 的子类,并在构建它时将其添加到选项卡中。
我问这个问题已经有一段时间了,后来我修改了实现,这不再是问题。
解决方案是放弃在 FXML 中声明控制器,并以编程方式将控制器关联到 FXMLLoader 实例。这允许将信息传递给 GridPane 的控制器(通过构造函数或其他 public 方法)在 GridPane 成为 loaded/instantiated.
之前这样做,需要的信息已经驻留在控制器中,可以在初始化时访问。
生活和学习...