JavaFX从另一个应用程序启动Application standalone OR

以下场景:

JavaFxMainApp JavaFXUpdaterApp

两者都是具有GUI和void main()方法的JavaFX应用程序。

  1. Updater必须能够通过访问JavaFxMainApp.jar来启动JavaFXMainApp,只需知道主类 – >它只能! 调用main()。

  2. JavaFxMainApp也必须能够通过启动main()来自行运行。

我无法启动多个VMS,这两个应用程序无法通信。

问题是:

Application.launch()只能在每个JVM上执行一次。

标准javaFx启动应用程序的方式:

Updater + MainApp public static void main(String[] args) { launch(args); } 

这里不可能满足要求1)。 因为两个main()方法都调用launch()。

我找到的第二种方法是:

 Updater + MainApp public static void main(String[] args) { Application app2 = JavaFxMainApp.class.newInstance(); Stage anotherStage = new Stage(); app2.start(anotherStage); } 

首先,我失去了通过args的可能性,但我可以忍受它,因为他们不会被使用。 这里的主要问题是,如果JVM已经运行了JavaFx线程,则此代码仅起作用,因此它要求在之前的某个时刻在JVM中调用launch()。 情况并非如此,因为两个调用都不再是launch()。

混合方法:

 Updater calls launch(), MainApp takes the second approach 

要求2)无法实现,现在启动MainApp而不启动更新程序是不可能的。

另外一个想法是脏的“尝试启动()捕获() – >在两个应用程序中尝试第二种方法(),但这两个应用程序耦合并使设置不那么灵活。

有没有办法实现这一点,而无需覆盖JavaFxs的LauncherImpl或Application类来满足这些需求?

你能做这样的事情:

 public class MainApp extends Application { private Parent uiContent ; public static final double DEFAULT_WIDTH = 800 ; public static final double DEFAULT_HEIGHT = 600 ; public Parent getContent() { if (uiContent == null) { uiContent = initializeUI(); } return uiContent ; } public Scene createScene() { return new Scene(getContent(), DEFAULT_WIDTH, DEFAULT_HEIGHT); } public void initializeAndShowStage(Stage stage) { stage.setScene(createScene()); stage.show(); } private Parent initializeUI() { // probably wise to check we are on the FX Application thread here... Pane root = ... ; // build ui.... return root ; } @Override public void start(Stage primaryStage) throws Exception { initializeAndShowStage(primaryStage); } public static void main(String[] args) { launch(args); } } 

 public class UpdaterApp extends Application { @Override public void start(Stage primaryStage) throws Exception { // whatever you need to launch the updater app here... } // invoke from the FX Application Thread to "start" main app: private void showMainApp(Stage stage) { MainApp app = new MainApp(); app.initializeAndShowStage(stage); } private void showMainApp() { showMainApp(new Stage()); } public static void main(String[] args) { launch(args); } } 

这将是最优选的方法。 如果你的要求迫使你调用main ,那么你可以尝试这样的事情:

 public class MainApp extends Application { @Override public void start(Stage primaryStage) throws Exception { // .... build UI etc } public static void main(String[] args) throws Exception { if (Platform.isFXApplicationThread()) { Stage someStage = new Stage(); MainApp app = new MainApp(); app.start(stage); } else { launch(args); } } } 

然后你的更新程序应用程序可以只调用MainApp().main(new String[0])); 来自FX应用程序线程。

这感觉有点像黑客。

您希望您的MainApp自己启动,并且您还希望UpdateApp在需要时启动MainApp,然后您可以按照我的步骤操作。 我试过,这个模型正在运行。

这是起点。 您需要调用此类来开始您的应用程序

 public class StartAnApp { public static void main(String[] args){ new Thread(new MainApp()).start(); // this will call your MainApp } } 

这是第一个将开始的应用程序。 至于启动JavaFX应用程序,您需要有一个main()方法。 因此,请确保在此课程中提供主要方法。

 public class MainApp extends Application implements Runnable{ public MainApp(){} // constructor @Override public void start(Stage stage){ Text text = new Text("MainApp"); Button startUpdate = new Button("Start Update"); // When this button is pressed. It will launch UpdateApp Application startUpdate.setOnAction( e -> { Platform.runLater(new Runnable(){ @Override public void run(){ new UpdateApp().start(new Stage()); } }); }); Group root = new Group(text); Scene scene = new Scene(root,300,400); stage.setScene(scene); stage.setX(0); stage.setY(0); stage.show(); } // This method will be used when you first start an Application for // which main method is required public static void main(String[] args){ launch(args); } // This will be used when you call this Application from another JavaFX application // if you have closed this application before @Override public void run(){ launch(); } } 

这是您的UpdateApp。 此方法没有main()方法。

 public class UpdateApp extends Application implements Runnable{ public UpdateApp(){} // constructor @Override public void start(Stage stage){ Text text = new Text("UpdateApp"); Button startAnother = new Button("Start Another"); // When this button is pressed. It will launch MainApp Application or you can add any other JavaApplication startAnother.setOnAction( e -> { Platform.runLater(new Runnable(){ @Override public void run(){ new MainApp().start(new Stage()); } }); }); Group root = new Group(text); Scene scene = new Scene(root,300,400); stage.setScene(scene); stage.setX(350); stage.setY(0); stage.show(); } // This will be used when you call this Application from another JavaFX application @Override public void run(){ launch(); } }