在阅读javafx 8教程时,这似乎是主要的工作流程:
public class Test extends Application{
public static void main(String[] args){
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(TestFXController.class.getResource("test.fxml"));
Parent root;
try {
root = fxmlLoader.load();
Scene scene = new Scene(root, 1200, 800);
primaryStage.setScene(scene);
primaryStage.show();
TestFXController controller = fxmlLoader.getController();
controller.plotSomething();
} catch (IOException e) {
e.printStackTrace();
}
}
}假设我有一个我想运行的算法。启动上述应用程序后,我可能会得到一个包含"run algorithm“按钮的接口。按下按钮后,动作处理程序将调用该算法。然后我有:启动java应用程序->构建界面->按下按钮解决算法->显示解决方案。将图形内容与算法分离开来的只是一个按钮。实际上,图形界面“驱动”应用程序,因为它负责启动算法。然而,我更喜欢的是这样的:
public class Test2{
public void main(String[] args){
Algorithm alg=new Algorithm();
alg.solve();
GUI gui =new GUI(); //Spawns a Javafx 8 Graphical User Interface
gui.displaySolution(alg.getSolution());
}
}对我来说,这看起来更干净?但是,我不知道如何使用javafx 8来完成这个任务,或者这是否是可能的?任何例子或参考资料都将受到高度赞赏。我应该在GUI类中添加什么,以使它启动javafx 8接口?Test2中的示例还提供了使用干净的观察者设计模式的可能性,如下所示:
public class Test3{
public void main(String[] args){
Algorithm alg=new Algorithm();
alg.addListener(new GUI()); //Add a Javafx 8 GUI as a listener.
alg.addListener(new TextualLogger());
alg.solve();
}
}注意,在Test2和Test3类中,GUI不再驱动应用程序。
为了澄清,我的主要问题是:如果我要在Test2中运行代码,那么GUI类的实现应该是什么?就像这样:
public class GUI extends Application{
public GUI(){
//What should I put here? Perhaps launch(new String[]); ?
}
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(TestFXController.class.getResource("test.fxml"));
Parent root;
try {
root = fxmlLoader.load();
Scene scene = new Scene(root, 1200, 800);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void displaySolution(Solution sol){
...
}
}发布于 2015-08-11 18:08:55
在JavaFX应用程序中,您应该将start(...)方法从本质上看作是“常规”main(...)应用程序中的main(...)方法。(实际上,在Java8中,JavaFX应用程序根本不需要main(...)方法。)引入这种启动JavaFX应用程序的机制是为了迫使程序员尽可能地在正确的线程上初始化UI (与Swing相比,Swing中有大量错误启动GUI的代码)。为了方便起见,start(...)方法通过了初始阶段,但是如果您喜欢使用不同的方法,则不需要使用它。
所以你就可以
public class Test2 extends Application {
@Override
public void start(Stage primaryStage) {
Algorithm alg = new Algorithm();
alg.solve();
GUI gui = new GUI();
gui.displaySolution(alg.getSolution());
}
// included for the benefit of IDEs that do not support
// launching an Application without a main method:
public static void main(String[] args) { launch(args); }
}现在,GUI不是Application子类(这很有意义,因为它代表的是GUI,而不是应用程序):
public class GUI {
public GUI(){
FXMLLoader fxmlLoader = new FXMLLoader(TestFXController.class.getResource("test.fxml"));
Parent root;
try {
root = fxmlLoader.load();
Scene scene = new Scene(root, 1200, 800);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void displaySolution(Solution sol){
...
}
}这里需要记住的一点是,start(...)是在上执行的。因此,一旦显示了UI,任何需要执行的长时间运行的进程都应该在后台线程上执行。在您所描述的用例中,所有的繁重工作都是在显示UI之前完成的,所以这不是一个问题,但是如果您想要扩展这个模式,您可能需要考虑这一点。
发布于 2015-08-11 16:58:18
我不确定我是否完全遵循了你想要做的事情--你是想打开第二个JavaFX窗口吗?
像这样的东西有用吗?
Scene resultScene = algorithm.getSolution();
Stage resultStage = new Stage();
resultStage.setScene(resultScene);
resultStage.addEventHandler() or addEventFilter()
resultStage.show();这个阶段可以是它自己的窗口,也可以是primaryStage的子窗口,所以如果关闭父窗口,它也会关闭。
发布于 2016-06-11 06:45:12
如果您真的想从一个已经运行的窗口中打开第二个JavaFX窗口。你可以去看看。
Launch JavaFX application from another class
它会解决你的问题。
下面是如何运行新的JavaFx应用程序的代码
Platform.runLater(new Runnable(){
@Override
public void run(){
new MainApp().start(new Stage()); // MainApp is the class name of your second Application
}
});使类扩展应用程序并实现Runnable,并在该类中添加下面提到的代码
@Override
public void run(){
launch();
}启动()方法将从run()方法调用。不要在第二个类中使用Main()方法,否则会抛出异常。
https://stackoverflow.com/questions/31947591
复制相似问题