如何将参数传递给JavaFX应用程序?
我正在运行我的JavaFX应用程序:
public class MainEntry { public static void main(String[] args) { Controller controller = new Controller(); Application.launch(MainStage.class); } }
MainStage
类扩展了Appication
。 Application.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类的实例
- 调用init()方法
- 调用start(javafx.stage.Stage)方法
- 等待应用程序完成,当发生以下任何一种情况时会发生:应用程序调用Platform.exit(),最后一个窗口已关闭,Platform上的implicitExit属性为true
- 调用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.startup
的Runnable
在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到字段中。