如何将参数传递给JavaFX应用程序?

我正在运行我的JavaFX应用程序:

public class MainEntry { public static void main(String[] args) { Controller controller = new Controller(); Application.launch(MainStage.class); } } 

MainStage类扩展了AppicationApplication.launch在一个特殊的FX线程中启动我的JavaFX窗口,但在我的main方法中,我甚至没有我的MainStage类的实例。

如何将非String参数(在我的情况下为控制器 )传递给MainStage实例? 这是一个有缺陷的设计吗?

通常,除了传递给main的程序参数之外,不需要将参数传递给主应用程序。 人们想要这样做的唯一原因是创建一个可重用的Application 。 但是Application不需要是可重用的,因为它是组装应用程序的代码片段。 把start方法想象成新的main吧!

因此,不是编写在main方法中配置的可重用Application ,而是应用程序本身应该是配置程序并使用可重用组件在start方法中构建应用程序,例如:

 public class MyApplication extends Application { @Override public void start(Stage stage) throws Exception { // Just on example how it could be done... Controller controller = new Controller(); MyMainComponent mainComponent = new MyMainComponent(controller); mainComponent.showIn(stage); } public static void main(String[] args) { Application.launch(args); } } 

问题 – 我

我甚至没有MainStage类的实例!

您的main方法不需要MainStage实例来调用MainStage的start()。 此作业由JavaFX启动程序自动完成。

来自Docs

JavaFX应用程序的入口点是Application类。 无论何时启动应用程序,JavaFX运行时都会按顺序执行以下操作:

构造指定Application类的实例

  1. 调用init()方法
  2. 调用start(javafx.stage.Stage)方法
  3. 等待应用程序完成,当发生以下任何一种情况时会发生:应用程序调用Platform.exit(),最后一个窗口已关闭,Platform上的implicitExit属性为true
  4. 调用stop()方法

Java启动程序在JavaFX应用程序线程上加载并初始化指定的Application类。 如果Application类中没有main方法,或者main方法调用Application.launch(),则会在JavaFX Application Thread上构造Application的实例。

问题 – II

如何将非String参数(在我的情况下为控制器)传递给MainStage实例?

为什么需要将非String参数传递给MainStage ? 如果您需要一个控制器对象,只需从FXML获取它

 public class MainEntry extends Application { @Override public void start(Stage stage) throws Exception { FXMLLoader loader = new FXMLLoader(); Pane pane = (Pane) loader.load(getClass().getResourceAsStream("sample.fxml")); //Get the controller Controller controller = (Controller)loader.getController(); Scene scene = new Scene(pane, 200, 200); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args);// or launch(MainEntry.class) } } 

从JavaFX 9开始,您可以使用公共API“手动”触发JavaFX平台的启动。 唯一的缺点是, stop方法的调用方式不同于Application.launch启动的Application.launch

 public class MainEntry { public static void main(String[] args) { Controller controller = new Controller(); final MainStage mainStage = new MainStage(controller); mainStage.init(); Platform.startup(() -> { // create primary stage Stage stage = new Stage(); mainStage.start(stage); }); } } 

传递给Platform.startupRunnable在JavaFX应用程序线程上调用。

传递给main()方法的String数组是应用程序的参数,如果您任意选择使用JavaFX,则不是特定于JavaFX模块的参数。

最简单的解决方案可能是存储争论以供以后使用(例如main()方法旁边的静态属性,以及访问它的静态getter方法)。

这是我在别处找到的一个很好的例子

 @Override public void init () throws Exception { super.init (); Parameters parameters = getParameters (); Map namedParameters = parameters.getNamed (); List rawArguments = parameters.getRaw (); List unnamedParameters = parameters.getUnnamed (); System.out.println ("\nnamedParameters -"); for (Map.Entry entry : namedParameters.entrySet ()) System.out.println (entry.getKey () + " : " + entry.getValue ()); System.out.println ("\nrawArguments -"); for (String raw : rawArguments) System.out.println (raw); System.out.println ("\nunnamedParameters -"); for (String unnamed : unnamedParameters) System.out.println (unnamed); } 

您可以在MainStage类中设置Controller。 但你必须静态,否则它将为null。

Hava看看代码:

 public class MainEntry { public static void main(String[] args) { Controller controller = new Controller(); MainStage ms = new MainStage(); ms.setController(controller); Application.launch(MainStage.class, (java.lang.String[]) null); } 

}

 public class MainStage extends Application { private static Controller controller; public void start(Stage primaryStage) throws Exception { System.out.println(controller); primaryStage.show(); } public void setController(Controller controller){ this.controller = controller; } 

}

当然,需要并且有可能将参数传递给JavaFX应用程序。

我这样做是为了从不同的地方运行我的JavaFX客户端,需要不同的网络配置(直接或通过代理)。 为了不对代码进行即时更改,我在应用程序运行命令中实现了几个网络配置,其参数类似于–configurationIndex = 1 。 默认代码值为0。

 List parameters; int parameterIndex; String parameter; parameters = getParameters().getRaw(); for (parameterIndex = 0; parameterIndex < parameters.size(); parameterIndex++) { parameter = parameters.get( parameterIndex); if (parameter.contains("configurationIndex")) { configurationIndex = Integer.valueOf( parameters.get(parameterIndex). split("=")[1]); } } 

在Netbeans中,您可以直接在项目中为调试需要设置此参数:项目 - 属性 - 运行 - 参数 - 插入--configurationIndex = 1到字段中。