Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ScalaFX(或JavaFX)-多次从另一个主类调用GUI_Java_Scala_Javafx_Jvm_Scalafx - Fatal编程技术网

ScalaFX(或JavaFX)-多次从另一个主类调用GUI

ScalaFX(或JavaFX)-多次从另一个主类调用GUI,java,scala,javafx,jvm,scalafx,Java,Scala,Javafx,Jvm,Scalafx,我是从上一个问题开始的: 我正在为一个模拟软件包编写一个独立的可视化软件包 模拟包是由我们的一个团队在Scala编写的 我想做的是为这个模拟包创建一个类似matplotlib的包。我设想的最终用途类似于matplotlib: import matplotlib.pyplot as plt plt.plot([1, 2, 3, 4]) plt.ylabel('some numbers') plt.show() plt.plot([10, 20, 3000, 4121212]) plt.yl

我是从上一个问题开始的:

  • 我正在为一个模拟软件包编写一个独立的可视化软件包
  • 模拟包是由我们的一个团队在Scala编写的
我想做的是为这个模拟包创建一个类似matplotlib的包。我设想的最终用途类似于matplotlib:

import matplotlib.pyplot as plt

plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()

plt.plot([10, 20, 3000, 4121212])
plt.ylabel('some numbers')
plt.show()
对于我的软件包,我会做一些类似的事情。这里假设myFXPackage是用ScalaFX编写的图表包。在我的驾驶课上:

Import myFXPackage
// run some simulation code here...
myFXPackage.plot(results)

// run some MORE simulation code here...
myFXPackage.plot(results)
现在看来,对于ScalaFX,整个应用程序只能有一个入口点;这是JFXApp类。但是,我希望导入包,并在我的驱动程序类中多次运行此代码,如上所示。因此,驱动程序类如何调用ScalaFX并运行绘图,关闭绘图,然后运行另一个绘图


这是否可行?如果是这样的话,我该怎么做呢?

大多数JavaFX示例代码将
main
方法与
应用程序
子类合并在一起,在许多情况下甚至在同一类中进行UI布局等。不一定有理由这样做,在后一种情况下,这不是一个特别好的设计

假设您在UI代码中适当地分离关注点,您可能会有一个类似

public class MainUI {

    private BorderPane root ;

    public MainUI() {
        root = new BorderPane();
        // do layout, register event handlers, etc etc
    }

    public Pane getView() {
        return root ;
    }
}
然后,如果您想要一个独立的JavaFX应用程序,您可以这样做

public class JavaFxApp extends Application {

    @Override
    public void start(Stage stage) {
        MainUI ui = new MainUI();
        Scene scene = new Scene(ui.getView());
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}
但这不是唯一可以使用UI类的地方。在JavaFX中(与大多数UI工具包一样),您必须在UI线程(即FX应用程序线程)上创建新阶段并执行其他UI任务

此外,在JavaFX中,必须显式启动FX工具包。在上面的代码中,这是通过
Application.launch()
方法完成的

JavaFX9引入了一个
Platform.startup(Runnable)
,它启动FX工具包并在FX应用程序线程上执行提供的
Runnable

因此,使用JavaFX9和更高版本,您可以获得如下代码

public class SomeApp {

    public static void main(String[] args) {
        // start FX toolkit
        // Since we don't want it to exit when we close a window, set 
        // implicit exit to false:
        Platform.startup(() -> Platform.setImplicitExit(false));

        // do some other stuff...

        // whenever you need to:
        Platform.runLater(SomeApp::showStage);

        // do other stuff...
    }

    private static void showStage() {
        Scene scene = new Scene(new MainUI().getView());
        Stage stage = new Stage();
        stage.show();
    }
}
在JavaFX9之前,您仍然可以这样做,但需要启动一个“空白”应用程序:

public class FXStartup extends Application {

    @Override
    public void start(Stage ignored) {
        // probably need this:
        Platform.setImplicitExit(false);
    }
}
请注意,
launch()
方法会一直阻塞,直到工具箱退出,因此应用程序需要在另一个线程中启动它:

public class SomeApp {

    public static void main(String[] args) {
        // start FX toolkit
        new Thread(() -> Application.launch(FXStartup.class, args)).start();

        // do some other stuff...

        // whenever you need to:
        Platform.runLater(SomeApp::showStage);

        // do other stuff...
    }

    private static void showStage() {
        Scene scene = new Scene(new MainUI().getView());
        Stage stage = new Stage();
        stage.show();
    }
}

大多数JavaFX示例代码将
main
方法与
Application
子类合并在一起,在许多情况下甚至在同一类中进行UI布局等。不一定有理由这样做,在后一种情况下,这不是一个特别好的设计

假设您在UI代码中适当地分离关注点,您可能会有一个类似

public class MainUI {

    private BorderPane root ;

    public MainUI() {
        root = new BorderPane();
        // do layout, register event handlers, etc etc
    }

    public Pane getView() {
        return root ;
    }
}
然后,如果您想要一个独立的JavaFX应用程序,您可以这样做

public class JavaFxApp extends Application {

    @Override
    public void start(Stage stage) {
        MainUI ui = new MainUI();
        Scene scene = new Scene(ui.getView());
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}
但这不是唯一可以使用UI类的地方。在JavaFX中(与大多数UI工具包一样),您必须在UI线程(即FX应用程序线程)上创建新阶段并执行其他UI任务

此外,在JavaFX中,必须显式启动FX工具包。在上面的代码中,这是通过
Application.launch()
方法完成的

JavaFX9引入了一个
Platform.startup(Runnable)
,它启动FX工具包并在FX应用程序线程上执行提供的
Runnable

因此,使用JavaFX9和更高版本,您可以获得如下代码

public class SomeApp {

    public static void main(String[] args) {
        // start FX toolkit
        // Since we don't want it to exit when we close a window, set 
        // implicit exit to false:
        Platform.startup(() -> Platform.setImplicitExit(false));

        // do some other stuff...

        // whenever you need to:
        Platform.runLater(SomeApp::showStage);

        // do other stuff...
    }

    private static void showStage() {
        Scene scene = new Scene(new MainUI().getView());
        Stage stage = new Stage();
        stage.show();
    }
}
在JavaFX9之前,您仍然可以这样做,但需要启动一个“空白”应用程序:

public class FXStartup extends Application {

    @Override
    public void start(Stage ignored) {
        // probably need this:
        Platform.setImplicitExit(false);
    }
}
请注意,
launch()
方法会一直阻塞,直到工具箱退出,因此应用程序需要在另一个线程中启动它:

public class SomeApp {

    public static void main(String[] args) {
        // start FX toolkit
        new Thread(() -> Application.launch(FXStartup.class, args)).start();

        // do some other stuff...

        // whenever you need to:
        Platform.runLater(SomeApp::showStage);

        // do other stuff...
    }

    private static void showStage() {
        Scene scene = new Scene(new MainUI().getView());
        Stage stage = new Stage();
        stage.show();
    }
}

不太熟悉JavaFX,但使用swing,您可以创建多个JFrame,并根据需要关闭它们。在JavaFX中几乎相同:您可以创建新的
Stage
a和
show()
它们。就像在Swing中一样,您必须在UI线程上执行此操作。唯一的区别是,在JavaFX中,必须首先显式启动JavaFX工具包。我不知道Scala,所以JavaFX只回答可以吗?是的@James_D,JavaFX可以。但问题是我需要将包基本上导入到另一个主程序中。据我所知,JavaFX/ScalaFX劫持了主要权利?有没有一种方法可以让我使用JavaFX简单地构建图表,渲染但不影响我的主程序来做其他事情?@finite\u diffidence是的,如果我正确理解需求的话。看看贴出的答案是否有用。不太熟悉JavaFX,但使用swing,您可以创建多个JFrame,并根据需要关闭它们。JavaFX中的情况几乎相同:您可以创建新的
Stage
a和
show()
它们。就像在Swing中一样,您必须在UI线程上执行此操作。唯一的区别是,在JavaFX中,必须首先显式启动JavaFX工具包。我不知道Scala,所以JavaFX只回答可以吗?是的@James_D,JavaFX可以。但问题是我需要将包基本上导入到另一个主程序中。据我所知,JavaFX/ScalaFX劫持了主要权利?有没有一种方法可以让我使用JavaFX简单地构建图表,渲染但不影响我的主程序来做其他事情?@finite\u diffidence是的,如果我正确理解需求的话。看看张贴的答案是否有用。谢谢@James\u D这是一个很好的答案。但有一个问题,什么是Platform.runLater(SomeApp::showtage);做什么?在我的IDE中,它显示为一个类型错误(我在使用Scala时以Platform.runLater(this.showtage())的形式运行)@finite_difference它是一个方法引用。它相当于
Platform.runLater(()->SomeApp.showtage())
在Java中,任何时候只要有一个lambda表达式调用一个与目标FunctionInterface中的方法具有相同签名的方法,就可以用方法引用替换它。(这个想法是模仿可以将函数作为参数传递的语言。)谢谢@James_D这是一个很好的答案。但有一个问题,什么是Platform.runLater(SomeApp::showtage);做什么?在我的IDE中,它显示为一个类型错误(我以Platform.runLater运行)(