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

时间:2014-07-07 13:31:11

标签: java parameters javafx

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

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

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

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

8 个答案:

答案 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类的实例

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

  

Java启动程序加载并初始化指定的Application   JavaFX应用程序线程上的类。如果没有主要方法   Application类,或者main方法调用   然后是Application.launch(),然后是Application的一个实例   在JavaFX应用程序线程上构建。

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

答案 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 ...)