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编写的
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运行)(