【发布时间】:2015-04-25 17:41:52
【问题描述】:
有没有办法在 JavaFX 中启动多个独立阶段?独立是指所有阶段都是从主线程创建的。
目前我的应用程序或多或少是一种算法,我想在执行期间绘制一些图表和表格(主要是检查结果是否正确/进行调试)。
问题是我无法弄清楚如何独立创建和显示多个阶段,即我想做这样的事情
public static void main(){
double[] x = subfunction.dosomething();
PlotUtil.plot(x); //creates a new window and shows some chart/table etc.
double[] y = subfunction.dosomethingelse();
PlotUtil.plot(y); //creates a new window and shows some chart/table etc.
.....
}
这将允许使用PlotUtil,就像在其他脚本语言(如 Matlab 或 R)中使用绘图函数一样。
所以主要问题是如何“设计”PlotUtils?到目前为止,我尝试了两件事
- PlotUtils 对每个绘图调用使用 Application.launch(每次都使用一个场景创建一个新阶段)--> 不起作用,因为
Application.launch只能调用一次。 - 在第一次调用 PlotUtils 期间创建某种“主阶段”,获取对创建的应用程序的引用并从那里开始后续阶段 --> 无法使用
Application.launch(SomeClass.class)我无法获得参考到创建的应用程序实例。
什么样的结构/设计可以让我实现这样的 PlotUtils 功能?
更新 1:
我想出了以下想法,想知道这个解决方案是否存在任何重大错误。
所有“绘图”要实现的接口
public abstract class QPMApplication implements StageCreator {
@Override
public abstract Stage createStage();
}
绘图功能:
public class PlotStage {
public static boolean toolkitInialized = false;
public static void plotStage(String title, QPMApplication stageCreator) {
if (!toolkitInialized) {
Thread appThread = new Thread(new Runnable() {
@Override
public void run() {
Application.launch(InitApp.class);
}
});
appThread.start();
}
while (!toolkitInialized) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Platform.runLater(new Runnable() {
@Override
public void run() {
Stage stage = stageCreator.createStage();
stage.show();
}
});
}
public static class InitApp extends Application {
@Override
public void start(final Stage primaryStage) {
toolkitInialized = true;
}
}
}
使用它:
public class PlotStageTest {
public static void main(String[] args) {
QPMApplication qpm1 = new QPMApplication() {
@Override
public Stage createStage() {
Stage stage = new Stage();
StackPane root = new StackPane();
Label label1 = new Label("Label1");
root.getChildren().add(label1);
Scene scene = new Scene(root, 300, 300);
stage.setTitle("First Stage");
stage.setScene(scene);
return stage;
}
};
PlotStage.plotStage(qpm1);
QPMApplication qpm2 = new QPMApplication() {
@Override
public Stage createStage() {
Stage stage = new Stage();
StackPane root = new StackPane();
Label label1 = new Label("Label2");
root.getChildren().add(label1);
Scene scene = new Scene(root, 300, 200);
stage.setTitle("Second Stage");
stage.setScene(scene);
return stage;
}
};
PlotStage.plotStage(qpm2);
System.out.println("Done");
}
}
【问题讨论】:
-
只需创建多个
Stage实例并在它们上调用show()。 -
感谢您的反馈。但我仍然必须确保 1. 工具包已初始化,以及 2. 阶段是在 fx 线程(而不是主线程)上创建的。我相应地更新了帖子,非常感谢您提供进一步的建议。
-
我想我不了解您的整个应用程序生命周期。如果我从头开始编写 R 接口,我的应用程序
start(...)方法将显示一个控制台并在初级阶段显示它。当用户输入命令时,它将处理命令(在事件处理程序中)并输出到同一个控制台,或者(例如,如果需要显示图形),创建一个新的Stage来显示图形.你能这样构造它吗?如果是这样,那就很简单了。 -
您当然是对的,但我的用例略有不同。首先,也许最重要的是,我不希望控制流由 JavaFX 应用程序启动/驱动。我宁愿寻找的是一种快速(希望不是太脏)的方式来绘制一些数字,而不是(就像你在 R/Matlab 脚本中在调试/开发期间绘制一些中间结果一样)而不必担心Toolkit beeing 初始化,确保在 JavaFX 线程上绘图等等......无论如何,我真的很感激 cmets。
-
我很难理解为什么您不使用 JavaFX 应用程序来驱动它(即使该应用程序没有做任何其他事情):毕竟,您必须使用一些东西来驱动它。但是,如果您真的不能这样做,那么强制 JavaFX 应用程序启动(如果尚未启动)的“快速破解”方法是在 AWT 事件调度线程上创建一个
JFXPanel。
标签: javafx