所以我一直在努力解决这个问题,并且在这些论坛上已经得到过解答,但是我非常感谢您的帮助,因为没有人能真正解决我的问题或提出非常不同的解决方案,而且我不确定该怎么做(即使我已经尝试了所有方法,我还是敢说)。
问题是这样的:我有一个带有6个场景及其各自控制器的JavaFX应用程序。我有一个Person类创建一个对象,然后将该对象存储在全局ArrayList中(即所有场景均可访问),以便在我关闭应用程序时可以调用另一个方法将其保存到序列化的对象中。文件。
我实际上并没有在前两个场景中使用ArrayList,因为它们是菜单,因此创建对象的实际方法要等到第三个场景才运行。
我已经成功创建了场景,可以在它们之间进行切换,我只是不知道
我目前使用该类在场景之间切换:
public class SelectScene {
public void setScene(String fxmlFileName, String title, ActionEvent event) throws IOException{
Stage stage = (Stage) ((Node)event.getSource()).getScene().getWindow();
Parent root = FXMLLoader.load(getClass().getResource(fxmlFileName));
Scene scene = new Scene(root);
scene.getStylesheets().add(FinalDossier.class.getResource("style.css").toExternalForm());
stage.setTitle(title);
stage.setScene(scene);
}
感谢您的帮助:)
有几种方法可以做到这一点:基本上所有方法都涉及不使用静态FXMLLoader.load(URL)
方法,而是创建一个FXMLLoader
实例。
一种方法是在代码中创建控制器,使用共享List对其进行初始化,然后将其传递给setController(...)
。在此版本中,您将从fx:controller
FXML文件中删除属性。
不过,在您的情况下,这似乎是一种更好的方法,那就是为定义一个控制器工厂FXMLLoader
。这个对象告诉FXMLLoader
如何从fx:controller
属性中定义的类名称获取实例。这只是涉及一点反射魔术。所以你会做类似的事情
public class SelectScene {
private Callback<Class<?>, Object> controllerFactory ;
public SelectScene(final List<...> data) {
controllerFactory = new Callback<Class<?>, Object>() {
@Override
public Object call(Class<?> type) {
try {
Constructor<?> constructor = type.getDeclaredConstructor(List.class);
return constructor.newInstance(data);
} catch (NoSuchMethodException exc) {
return type.newInstance();
} catch (Exception ex) {
// trouble...
ex.printStackTrace();
return null ;
}
}
};
}
public void setScene(String fxmlFileName, String title, ActionEvent event) throws IOException{
Stage stage = (Stage) ((Node)event.getSource()).getScene().getWindow();
FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlFileName));
loader.setControllerFactory(controllerFactory);
Parent root = (Parent)loader.load();
Scene scene = new Scene(root);
scene.getStylesheets().add(FinalDossier.class.getResource("style.css").toExternalForm());
stage.setTitle(title);
stage.setScene(scene);
}
}
对于需要访问共享数据的控制器,只需使用带有List的参数定义一个构造函数:
public class MyController {
private final List<...> data ;
public MyController(List<...> data) {
this.data = data ;
}
public void initialize() {
// usual initialize method
}
}
对于没有该构造函数的控制器,控制器工厂将使用默认的构造函数。
您可以在方便的地方定义List:直接在SelectScene类中(如代码所示),或者可以更早地定义它(例如,在start()方法中),然后将其传递给SelectScene构造函数。这仅取决于您可能需要在其他地方访问它。
更新:完整示例在这里
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句