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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24611789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 13:28:26  来源:igfitidea点击:

How to pass parameters to JavaFX application?

javaparametersjavafx

提问by ferrerverck

I am running my JavaFX application like this:

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

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

MainStageclass extends Appication. Application.launchstarts my JavaFX window in a special FX-thread, but in my main method I don't even have an instance of my MainStageclass.

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

How to pass non-String parameter (controllerin my case) to MainStageinstance? Is it a flawed design?

如何将非字符串参数(在我的例子中是控制器)传递给MainStage实例?这是一个有缺陷的设计吗?

采纳答案by isnot2bad

Usually, there is no need to pass arguments to the main application other than the program arguments passed to your main. The only reason why one wants to do this is to create a reusable Application. But the Applicationdoes not need to be reusable, because it is the piece of code that assembles your application. Think of the startmethod to be the new main!

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

So instead of writing a reusable Applicationthat gets configured in the mainmethod, the application itself should be the configurator and use reusable components to build up the app in the startmethod, e.g.:

因此,与其编写Applicationmain方法中配置的可重用组件,应用程序本身应该是配置器并使用可重用组件在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);
    }
}

回答by icza

The Stringarray passed to the main()method are the parameters of the application, not specifically to the JavaFX module if you arbitrarily choose to use JavaFX.

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

The easiest solution could be to store the argumets for later use (e.g. static attribute next to the main()method, and a static getter method to access it).

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

回答by ItachiUchiha

Question - I

问题 - 我

I don't even have an instance of my MainStage class !

我什至没有我的 MainStage 类的实例!

Solution

解决方案

Your main method doesn't need an instance of MainStageto call the start() of your MainStage. This job is done automatically by the JavaFX launcher.

您的 main 方法不需要实例MainStage来调用您的MainStage. 这项工作由 JavaFX 启动器自动完成。

From Docs

来自文档

The entry point for JavaFX applications is the Application class. The JavaFX runtime does the following, in order, whenever an application is launched:

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

Constructs an instance of the specified Application class

  1. Calls the init() method
  2. Calls the start(javafx.stage.Stage) method
  3. Waits for the application to finish, which happens when either of the following occur: the application calls Platform.exit() the last window has been closed and the implicitExit attribute on Platform is true
  4. Calls the stop() method

构造指定的 Application 类的实例

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

and

The Java launcher loads and initializes the specified Application class on the JavaFX Application Thread. If there is no main method in the Application class, or if the main method calls Application.launch(), then an instance of the Application is then constructed on the JavaFX Application Thread.

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

Question - II

问题 - II

How to pass non-String parameter (controller in my case) to MainStage instance?

如何将非字符串参数(在我的例子中是控制器)传递给 MainStage 实例?

Solution

解决方案

Why do you need to pass non-String parameter to MainStage? If you need an controller object, just fetch it from the FXML

为什么需要将非字符串参数传递给MainStage?如果你需要一个控制器对象,只需从FXML

Example

例子

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)
    }
}

回答by dmolony

Here's a nice example I found 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);
}

回答by mjaque

You can set the Controller in the MainStage class. But you'll have to do it static, otherwise it will be null.

您可以在 MainStage 类中设置控制器。但是你必须做静态的,否则它将为空。

Hava a look at the code:

哈瓦看看代码:

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;
  }

}

}

回答by Zon

Of course there is a need and possibility to pass parameters to JavaFX application.

当然,有必要和可能将参数传递给 JavaFX 应用程序。

I did it to run my JavaFX client from different places, where different network configurations are required (direct or via proxy). Not to make instant changes in code, I implemented several network configurations to be chosen from in application run command with parameter like --configurationIndex=1. The default code value is 0.

我这样做是为了从不同的地方运行我的 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]);
  }
}

In Netbeans you can set this parameter for debugging need directly on your project: Project - Properties - Run - Parameters - insert --configurationIndex=1into field.

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

回答by fabian

Starting with JavaFX 9 you can trigger the launch of the JavaFX platform "manually" using the public API. The only drawback is that the stopmethod is not invoked the way it would be in application started via Application.launch:

从 JavaFX 9 开始,您可以使用公共 API“手动”触发 JavaFX 平台的启动。唯一的缺点是该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);
        });
    }
}

The Runnablepassed to Platform.startupis invoked on the JavaFX application thread.

Runnable传递到Platform.startup被调用JavaFX应用程序线程。

回答by Dorin

case 1 = java standard types - transmit them as java Strings "--name=value" and then convert them to the final destination using the answer of dmolony

case 1 = java 标准类型 - 将它们作为 java Strings "--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;
            }
      }

The parameter is created at Application.launch and decoded at init

该参数在 Application.launch 创建并在 init 解码

String args[] = {"--media_url=" + media_url, "--master_level=" + master_level};
Application.launch( args);

case 2 = If you have to transmit java objects use this workaround (this is for only one javafx Application launch, create a Map of workarounds and send index as strings if you have a complex case)

案例 2 = 如果您必须传输 java 对象,请使用此解决方法(这仅适用于一个 javafx 应用程序启动,如果您有复杂的案例,请创建一个解决方法映射并将索引作为字符串发送)

    public static Transfer_param javafx_tp;

and in your class init set the instance of object to a static inside it's own class

并在您的类 init 中将对象的实例设置为它自己的类中的静态

    Transfer_param.javafx_tp = tp1;

now you can statically find your last object for working with only one JavaFx Applications (remember that if you have a lot of JavaFx applications active you should send a String with a static variable identification inside a Map or array so you do not take a fake object address from your static structures (use the example at case 1 of this answer to transmit --javafx_id=3 ...))

现在你可以静态地找到你最后一个只处理一个 JavaFx 应用程序的对象(请记住,如果你有很多 JavaFx 应用程序处于活动状态,你应该在 Map 或数组中发送一个带有静态变量标识的字符串,这样你就不会使用假对象地址来自您的静态结构(使用本答案案例 1 中的示例来传输 --javafx_id=3 ...))