Как передать параметры в приложение 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 делает следующее, в порядке, когда приложение запускается:
создает экземпляр указанного класса приложения
- вызывает метод init ()
- вызывает start (javafx.ступень.Этап) метод
- ожидает завершения приложения, что происходит, когда происходит одно из следующих событий: приложение вызывает платформу.выход() последнее окно было закрыто, и атрибут implicitExit на платформе true
- вызывает метод 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 в поле.