我正在运行我的JavaFX应用程序:
public class MainEntry {
public static void main(String[] args) {
Controller controller = new Controller();
Application.launch(MainStage.class);
}
}
MainStage
类扩展Appication
。 Application.launch
在一个特殊的FX线程中启动我的JavaFX窗口,但在我的主要方法中,我甚至没有MainStage
类的实例。
如何将非String参数(在我的情况下为 controller )传递给MainStage
实例?这是一个有缺陷的设计吗?
答案 0 :(得分:4)
通常,除了传递给main的程序参数之外,不需要将参数传递给主应用程序。人们想要这样做的唯一原因是创建一个可重用的Application
。但是Application
不需要是可重用的,因为它是组装应用程序的代码片段。将start
方法视为新的main
!
因此,不是编写在Application
方法中配置的可重用main
,而是应用程序本身应该是配置程序并使用可重用组件在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);
}
}
答案 1 :(得分:4)
从JavaFX 9开始,您可以触发JavaFX平台的启动"手动"使用公共API。唯一的缺点是stop
方法不会像通过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);
});
}
}
在JavaFX应用程序线程上调用传递给Runnable
的{{1}}。
答案 2 :(得分:3)
我甚至没有MainStage类的实例!
您的主要方法不需要MainStage
的实例来调用MainStage
的start()。此作业由JavaFX启动程序自动完成。
来自文档
JavaFX应用程序的入口点是Application类。无论何时启动应用程序,JavaFX运行时都会按顺序执行以下操作:
构造指定Application类的实例
- 调用init()方法
- 调用start(javafx.stage.Stage)方法
- 等待应用程序完成,当发生以下任一情况时会发生: 应用程序调用Platform.exit() 最后一个窗口已关闭且Platform上的implicitExit属性为true
- 调用stop()方法
醇>
和
Java启动程序加载并初始化指定的Application JavaFX应用程序线程上的类。如果没有主要方法 Application类,或者main方法调用 然后是Application.launch(),然后是Application的一个实例 在JavaFX应用程序线程上构建。
如何将非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)
}
}
答案 3 :(得分:3)
这是我找到elsewhere
的一个很好的例子@Override
public void init () throws Exception
{
super.init ();
Parameters parameters = getParameters ();
Map<String, String> namedParameters = parameters.getNamed ();
List<String> rawArguments = parameters.getRaw ();
List<String> unnamedParameters = parameters.getUnnamed ();
System.out.println ("\nnamedParameters -");
for (Map.Entry<String, String> 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);
}
答案 4 :(得分:2)
传递给String
方法的main()
数组是应用程序的参数,如果您任意选择使用JavaFX,则不是特定于JavaFX模块。
最简单的解决方案可能是存储争论以供以后使用(例如main()
方法旁边的静态属性,以及访问它的静态getter方法。)
答案 5 :(得分:0)
您可以在MainStage类中设置Controller。但你必须静态,否则它将为空。
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;
}
}
答案 6 :(得分:0)
当然,需要并且有可能将参数传递给JavaFX应用程序。
我这样做是为了从不同的地方运行我的JavaFX客户端,需要不同的网络配置(直接或通过代理)。为了不对代码进行即时更改,我在应用程序运行命令中实现了几个网络配置,其参数如 - configurationIndex = 1 。默认代码值为0.
List<String> 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 插入字段。
答案 7 :(得分:0)
情况1 = Java标准类型-以java字符串“ --name = value”的形式传输它们,然后使用dmolony的答案将它们转换为最终目标。
for ( Map.Entry<String, String> entry : namedParameters.entrySet ()){
System.out.println (entry.getKey() + " : " + entry.getValue ());
switch( entry.getKey()){
case "media_url": media_url_received = entry.getValue(); break;
}
}
该参数在Application.launch创建,并在init解码
String args[] = {"--media_url=" + media_url, "--master_level=" + master_level};
Application.launch( args);
case 2 =如果您必须传输Java对象,请使用此变通办法(这仅适用于一次javafx应用程序启动,如果情况复杂,则创建变通办法Map并以字符串形式发送索引)
public static Transfer_param javafx_tp;
在您的类的init中,将对象的实例设置为它自己的类中的静态对象
Transfer_param.javafx_tp = tp1;
现在您可以静态地找到仅用于一个JavaFx应用程序的最后一个对象(请记住,如果您有大量的JavaFx应用程序处于活动状态,则应在Map或数组中发送带有静态变量标识的String,这样您就不用来自您的静态结构的伪造的对象地址(使用此答案的情况1的示例传输--javafx_id = 3 ...)