【问题标题】:Is it possible to launch a JavaFX application through another JavaFX application?是否可以通过另一个 JavaFX 应用程序启动 JavaFX 应用程序?
【发布时间】:2020-02-17 11:27:42
【问题描述】:

我说的时候能知道为什么会有错误吗?

Stage s = new Stage();

new CaeserCipherFX().start(s);

这是我下面的代码。我需要从这个启动另一个 JavaFX 应用程序。请帮忙。谢谢。

public class Main extends Application
{

    String args[];
    @Override
    public void start(Stage stage) throws Exception
    {

        // creating types of encryptions (Button)

        Button caeserCipher = new Button("1. Caeser Cipher");
        Button runningKeyCipher = new Button("2. Running Key Cipher");
        Button trithemiusCipher = new Button("3. Trithemius Cipher");
        Button vignereCipher = new Button("4. Vignere Cipher");

        //setting styles
        caeserCipher.setTextFill(Color.BLUE);
        runningKeyCipher.setTextFill(Color.BLUE);
        trithemiusCipher.setTextFill(Color.BLUE);
        vignereCipher.setTextFill(Color.BLUE);

        /*need to add more!*/
        //setting action listeners
        String arr [] = {"CaeserCipher","RunningKeyCipher","TrithemiusCipher","VignereCipher"};
        caeserCipher.setOnAction((ActionEvent event)->{
                //open caeser cipher
                Stage s = new Stage();
                new CaeserCipherFX().start(s);

            });
        runningKeyCipher.setOnAction((ActionEvent event)->{
                //open running key cipher
                stage.hide();
            });
        trithemiusCipher.setOnAction((ActionEvent event)->{
                //open trithemius cipher 
                stage.hide();
            });
        vignereCipher.setOnAction((ActionEvent event)->{
                //open vignere cipher
                stage.hide();
            });
        // creating flowpane(FlowPane)
        FlowPane menu = new FlowPane();
        menu.setHgap(25);
        menu.setVgap(25);
        menu.setMargin(caeserCipher, new Insets(20, 0, 20, 20));

        //list for Flowpane(ObservableList)
        ObservableList list = menu.getChildren();

        //adding list to flowpane
        list.addAll(caeserCipher,runningKeyCipher,trithemiusCipher,vignereCipher);

        //scene for stage
        Scene scene = new Scene(menu);

        stage.setTitle("Main Menu");
        stage.setScene(scene);
        // stage.initStyle(StageStyle.UTILITY);
        stage.setHeight(100);
        stage.setWidth(600);
        stage.setResizable(false);

        // Show the Stage (window)
        stage.show();
    }

}

我想启动下面的代码:

public class CaeserCipherFX extends Application
{

    @Override
    public void start(Stage stage) throws Exception
    {//some other code
        //some other code
    }
 }

【问题讨论】:

标签: javafx bluej


【解决方案1】:

有一个无处不在的 JavaFX 主应用程序线程,需要一段时间才能适应。

把它想象成前端线程。从理论上讲,您应该使用该线程来处理 UI 更新和复杂的 cpu 任务,例如在 BD 中查找某些内容或计算 PI 的第 100000 位应该在后台线程中完成。如果您不这样做,UI 将变得无响应,直到返回 DB 数据或找到该小数点。

public class TestClass extends Application {

    public static void main(String[] args) {
        System.out.println("here");
        Application.launch(TestClass.class, args);
        System.out.println("this is called once application launch is terminated.");
    }

    @Override
    public void init() throws Exception {
        super.init(); //To change body of generated methods, choose Tools | Templates.
        System.out.println("message from init");
    }

    @Override
    public void start(Stage primaryStage) throws Exception { // this is abstract.
        System.out.println("message from start");
        Platform.exit(); // if you remove this line, the application won't exit. 
    }
}

由于 JavaFX 带有一些先决条件,因此您需要使用前端来启动您的应用程序。您可以解决此问题,但从技术上讲,

public void start(Stage primaryStage)

是什么,出于所有密集目的,启动您的程序。

从这里,您可以使用 primaryStage 来控制您的大部分应用程序。最好在其中放置一个 .onCloseRequest() 来调用 Platform.exit();

如果你想在你的应用程序中有多个窗口,你可以使用类似的东西

public class TestClass extends Application {

    public static void main(String[] args) {
        System.out.println("here");
        Application.launch(TestClass.class, args);
        System.out.println("this is called once application launch is terminated.");
    }

    @Override
    public void init() throws Exception {
        super.init(); //To change body of generated methods, choose Tools | Templates.
        System.out.println("message from init");
    }

    @Override
    public void start(Stage primaryStage) throws Exception { // this is abstract.
        primaryStage.setScene(new Scene(new TextArea("this is the first stage (window)")));
        primaryStage.setTitle("stage 1");
        primaryStage.show();

        primaryStage.setOnCloseRequest((event) -> {
            Platform.exit();
        });

        Stage secondaryStage = new Stage();
        secondaryStage.setTitle("stage 2");
        TextArea ta2 = new TextArea("this is a different stage.");
        Scene scene = new Scene(ta2);
        secondaryStage.setScene(scene);
        secondaryStage.show();

        primaryStage.setX(200);

        secondaryStage.setX(200 + primaryStage.getWidth() + 50);

    }
}

这就是我假设你想要做的。基本上每当您按下按钮时都会创建一个新窗口。您可以像这样创建阶段。

您无法按照自己的方式进行操作的原因是因为您试图通过调用新的 CaeserCipherFX 来启动另一个 javafx 线程,这是一个应用程序对象,而不是 Stage。

new CaeserCipherFX().start(s); // this can only be called once.

如果您绝对希望拥有 2 个不同的应用程序(注意:不是应用程序窗口),那么您需要拥有 2 个不同的进程。

最后,两个示例中使用的 primaryStage 参数在开始时基本上是一个占位符(因为它是构造的,但实际上并没有任何东西......就像一个新的 String())。您可以使用不同的舞台对象作为您的“主要”用户界面。

最后,如果取决于您要解密的内容,您可能需要使用后台线程来保持 UI 响应能力。为此,您需要查看 javafx 教程的并发部分。

【讨论】:

    【解决方案2】:

    是否可以通过另一个 JavaFX 应用程序启动 JavaFX 应用程序?不是真的。

    或者,您可以使用 java.lang.ProcessBuilder

    这个类本质上是向你的操作系统外壳发送命令行。

    您可以在单击按钮时使用它来运行类似“java -jar XXX\YYY\CaeserCipherFX.jar”的内容。 (您必须将 CaeserCypherFX 项目构建到 jar 文件中)

    这将创建一个新的 JVM。这意味着没有内存状态共享。您可以通过 IPC 处理。

    【讨论】:

    • ...但说实话没有意义。 ...您为什么不创建新的阶段并展示它们,而不是完全创建新的应用程序?
    • 我是 JavaFX 的新手,所以我不明白如何将阶段作为参数传递
    猜你喜欢
    • 2013-03-17
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 2012-12-02
    • 2016-09-28
    相关资源
    最近更新 更多