0

我正在尝试制作一个棘手的(愚蠢的 mb?)算法来在打开的应用程序窗口之间传递参数。我在做什么:

  1. 我有一个带有必要字段的窗格扩展类。这将是“门”。
  2. 调用控制器从 FXML 加载节点树,将其作为子节点附加到“门”对象
  3. 然后创建并显示一个以“门”为根节点的新场景。
  4. 新窗口控制器引用了 FXML 根节点(“门”的直接子节点),他需要做的就是在其上使用 .getParent() 来获取“门”。

但到底是什么!它返回空!我究竟做错了什么?我应该通过 FXMLLoader 设置不同的控制器吗?

将消息流从一个控制器组织到另一个控制器的正确方法是什么?

以下是代码块: 主应用程序类:

private void handleMenuVisibility(ActionEvent event) throws IOException
{
    Parent root = FXMLLoader.load(getClass().getResource("/ContextMenus/Visibility.fxml"));
    final AttributedWrapper aw = new AttributedWrapper();
    aw.getChildren().add(root);
    Scene scene = new Scene(aw);
    Stage stage = new Stage();
    stage.setScene(scene);
    stage.show();
}

和调用的窗口控制器:

public void initialize(URL url, ResourceBundle rb) {
AttributedWrapper aw = (AttributedWrapper) anchorPane.getParent();
}

upd: AttributedWrapper 是一个扩展 javafx.scene.layout.Pane 的类

主要更新: 在这里找到一些信息:如何将在 FXML Controller1 中创建的对象传递给内部 FXML 控件的 Controller2 我使用我的属性包装器作为 FXML 文件的根节点,通常它可以工作。但是问题仍然存在于调用的控制器初始化中。我从主应用程序控制器发送到调用的参数不可用。功能

    public void initialize(URL url, ResourceBundle rb)

恰好在执行 FXMLLoader.load() 时以及在我将数据放入包装器之前开始。

以下是要点: 主应用程序

final AttributedWrapper aw = FXMLLoader.load(getClass().getResource("/ContextMenus/Visibility.fxml"));
Scene scene = new Scene(aw);
Stage stage = new Stage();
stage.setScene(scene);
    aw.writeParam("key1", "value1");
    stage.show()

被调用的控制器

@FXML private AttributedWrapper aw;
public void initialize(URL url, ResourceBundle rb) {
System.out.println(aw.readParam("key1"));
anchorPane.writeParam("key2", "value2");
}

关闭调用的窗口后,我读取了“key2”参数并且没问题,但是从调用的窗口读取“key1”返回null。

在这里传递参数的正确方法是什么?或者我能做的就是制作静态字段?

4

1 回答 1

1

问题是public void initialize(URL url, ResourceBundle rb)在 FXMLLoader 调用期间正在调用该方法:

Parent root = FXMLLoader.load(getClass().getResource("/ContextMenus/Visibility.fxml"));

因此您的父母尚未设置。

有几种方法可以解决这个问题:

  1. 将初始化逻辑移动到单独的方法中并手动调用它:

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/ContextMenus/Visibility.fxml"));
    Parent root = fxmlLoader.load();
    controller = (MyController) fxmlLoader.getController();
    final AttributedWrapper aw = new AttributedWrapper();
    aw.getChildren().add(root);
    controller.doMyInit();
    
  2. 使用您的“主要更新”方法,但再次 - 在设置参数后调用自定义初始化。

  3. 添加侦听器anchorPane.parentProperty()并执行初始化,然后 Parent 变为 not null

    root.parentProperty().addListener(new ChangeListener<Parent>() {
    
        @Override
        public void changed(ObservableValue<? extends Parent> ov, Parent oldP, Parent newP) {
            if (newP != null && oldP == null) {
                System.out.println("my parent is " + newP);
            }
        }
    });
    
于 2012-10-05T10:25:45.500 回答