在阅读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();
}
}
}
假设我有一个我想要运行的算法。在启动上述应用程序后,我可能会得到一个包含“运行算法”按钮的界面。按下按钮后,动作处理程序将调用该算法。 然后我有:启动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){
...
}
}
答案 0 :(得分:3)
在JavaFX应用程序中,您应该将start(...)
方法视为“常规”Java应用程序中main(...)
方法的等效方法。 (事实上,在Java 8中,JavaFX应用程序根本不需要main(...)
方法。)引入了这种启动JavaFX应用程序的机制,以便尽可能地迫使程序员初始化UI在正确的线程上(与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(...)
在FX应用程序线程上执行。因此,一旦显示了UI,就应该在后台线程上执行需要执行的任何进一步长时间运行的进程。在您描述的用例中,所有繁重的工作都是在显示UI之前完成的,所以这不是问题,但如果您尝试扩展此模式,则可能需要考虑这一点。
答案 1 :(得分:0)
我不确定我是否完全遵循您的尝试 - 您是否尝试打开第二个JavaFX窗口?
这样的事情会起作用吗?
Scene resultScene = algorithm.getSolution();
Stage resultStage = new Stage();
resultStage.setScene(resultScene);
resultStage.addEventHandler() or addEventFilter()
resultStage.show();
这个阶段可以是它自己的窗口或primaryStage的子窗口,这样如果你关闭父窗口,它也会关闭。
答案 2 :(得分:0)
如果你真的想从已经运行的第二个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
}
});
让您的类扩展Application并实现Runnable,并在该类中添加以下提及的代码
@Override
public void run(){
launch();
}
将从run()方法调用launch()方法。不要在第二个类中使用Main()方法,否则抛出异常。