JavaFX 启动另一个应用程序

Posted

技术标签:

【中文标题】JavaFX 启动另一个应用程序【英文标题】:JavaFX launch another application 【发布时间】:2013-03-17 04:41:50 【问题描述】:

我一直在用 JavaFx 砸我的头......

这适用于没有运行应用程序实例的情况:

public class Runner 

    public static void main(String[] args) 
        anotherApp app = new anotherApp();
        new Thread(app).start();
    
 

public class anotherApp extends Application implements Runnable 

    @Override
    public void start(Stage stage) 
    

    @Override
    public void run()
        launch();
    

但是如果我在另一个应用程序中执行new Thread(app).start() within,我会收到一个异常,指出我不能进行两次启动。

我的方法也被其他应用程序上的观察者调用,如下所示:

@Override
public void update(Observable o, Object arg) 
    // new anotherApp().start(new Stage());
            /* Not on FX application thread; exception */

    // new Thread(new anotherApp()).start();
            /* java.lang.IllegalStateException: Application launch must not be called more than once */

它在一个 JavaFX 类中,例如:

public class Runner extends Applications implements Observer 

    public static void main(String[] args) 
        launch(args);
    

    @Override
    public void start(Stage stage)
    //...code...//
    
    //...methods..//
    //...methods..//

    @Override
    public void update(Observable o, Object arg) 
    //the code posted above//
    

我尝试将 ObjectProperties 与侦听器一起使用,但没有成功。我需要以某种方式从 java.util.observer 的更新方法中运行这个新阶段。

欢迎提出任何建议。谢谢。

【问题讨论】:

您的意图只是打开另一个窗口吗?如果是,您可以在 UI 线程中创建一个新的Stagefinal Stage stage = new Stage(); stage.setScene(yourScene); stage.show(); 是的,我的意图是打开另一个窗口(另一个类中的应用程序),但我必须在 java.util.observer 的更新方法中而不是 UI 线程中进行。 你可以通过调用runLater方法在UI线程中运行一堆代码:Platform.runLater(new Runnable() @Override public void run() //runs in the UI thread);所以你可以在update方法内部调用它。 【参考方案1】:

应用程序不仅仅是一个窗口——它是一个Process。因此,每个 VM 只允许使用一个 Application#launch()

如果你想有一个新窗口——创建一个Stage

如果你真的想重用 anotherApp 类,只需将其包装在 Platform.runLater()

@Override
public void update(Observable o, Object arg) 
    Platform.runLater(new Runnable() 
       public void run()              
           new anotherApp().start(new Stage());
       
    );

【讨论】:

好的。有效!现在但是..,文档说“在未来的未指定时间运行”。那是什么意思?它可能会在某些情况下运行 10 分钟或类似的东西?未指定的时间取决于什么?谢谢。 您可以期待它立即发生。除非您同时进行 100500 次此类调用,否则它们会在瞬间执行:) 你是救生员@SergeyGrinev 使用新的 anotherApp().start(new Stage());我也因类似的问题而自责,您的建议有所帮助。谢谢! 你忘了捕捉 start(stage) 抛出的异常。 这只有在你的应用程序不依赖于预加载器时才有效。【参考方案2】:

我在主类AnotherClass ac = new AnotherClass(); 中做了另一个JFX 类的构造函数,然后调用了方法ac.start(new Stage);。它对我很好。你可以把它放在 main() 或其他方法中。它的作用可能与 launch(args) 方法的作用相同

【讨论】:

【参考方案3】:

想提供第二个答案,因为有一个使用警告 Application.start(Stage stage)。

在init方法返回后调用start方法

如果您的 JavaFX 应用程序具有 Override Application.init(),则该代码永远不会执行。您在第二个应用程序主方法中也没有任何代码。

启动第二个 JavaFX 应用程序的另一种方法是使用 ProcessBuilder API 启动一个新进程。

    final String javaHome = System.getProperty("java.home");
    final String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
    final String classpath = System.getProperty("java.class.path");
    final Class<TestApplication2> klass = TestApplication2.class;
    final String className = klass.getCanonicalName();
    final ProcessBuilder builder = new ProcessBuilder(javaBin, "-cp", classpath, className);

    final Button button = new Button("Launch");
    button.setOnAction(event -> 

        try 
            Process process = builder.start();
         catch (IOException e) 
            e.printStackTrace();
        

    );

【讨论】:

以上是关于JavaFX 启动另一个应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何从 JavaFX 中的另一个控制器类访问 UI 元素?

启动 JavaFX 应用程序时的内部 NPE

从 Eclipse 启动使用 Maven 配置的 JavaFX 应用程序

在普通 Java 应用程序中创建 JavaFX 初级阶段

从另一个类(java、javafx)调用对象

为啥 javafx 忽略 main 的返回并仍然启动应用程序?