Как передать параметры в приложение JavaFX?

я запускаю свое приложение JavaFX следующим образом:

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

MainStage класс расширяется Appication. Application.launch запускает мое окно JavaFX в специальном FX-потоке, но в моем основном методе у меня даже нет экземпляра моего MainStage класса.

как принимать Строковый параметр (контроллер в моем случае)MainStage экземпляр? Это дефектный дизайн?

7 ответов


обычно нет необходимости передавать аргументы главному приложению, кроме аргументов программы, переданных вашему основному приложению. Единственная причина, по которой это нужно сделать, - создать многоразовый Application. Но ... --1--> Не нужно повторно использовать, потому что это фрагмент кода, который собирает ваше приложение. Подумайте о 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);
    }
}

Вопрос - Я

у меня даже нет экземпляра моего класса MainStage !

решение

вашему основному методу не нужен экземпляр MainStage чтобы вызвать start () вашего MainStage. Эта работа выполняется автоматически с помощью пусковой установки JavaFX.

Из Docs

точкой входа для приложений JavaFX является класс приложения. Среда выполнения JavaFX делает следующее, в порядке, когда приложение запускается:

создает экземпляр указанного класса приложения

  1. вызывает метод init ()
  2. вызывает start (javafx.ступень.Этап) метод
  3. ожидает завершения приложения, что происходит, когда происходит одно из следующих событий: приложение вызывает платформу.выход() последнее окно было закрыто, и атрибут implicitExit на платформе true
  4. вызывает метод Stop ()

и

Java launcher загружает и инициализирует указанное приложение класс В потоке приложения JavaFX. Если нет основного метода в класс приложения, или если вызов метода main Приложение.launch (), затем экземпляр приложения построенный на потоке приложения JavaFX.

вопрос-II

как передать параметр Non-String (контроллер в моем случае) в экземпляр MainStage?

решение

почему вам нужно передать параметр Non-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 вы можете запустить запуск платформы 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);
        });
    }
}

на Runnable перешло к Platform.startup вызывается в потоке приложения JavaFX.


на String массив передан в main() метод-это параметры приложения, а не специально для модуля JavaFX, если вы произвольно выбираете использовать JavaFX.

самым простым решением может быть хранение аргументов для последующего использования (например, Статический атрибут рядом с main() метод и статический метод геттера для доступа к нему).


вот хороший пример, который я нашел везде

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

Вы можете установить контроллер в классе MainStage. Но вам придется сделать это статично, иначе это будет null.

Хава взглянуть на код:

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<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 вы можете установить этот параметр для отладки непосредственно в своем проекте: Project-Properties-Run-Parameters-insert --configurationIndex=1 в поле.