使用来自另一个类的JavaFx应用程序实例 [英] Using a JavaFx application instance from another class

查看:136
本文介绍了使用来自另一个类的JavaFx应用程序实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MainWindowFx类,如下所示。它基本上创建了一个简单的 JavaFX GUI。

I have a MainWindowFx class like below. It basically creates a simple JavaFX GUI.

package drawappfx;


import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.control.TextAreaBuilder;


/**
 *
 * @author Hieu
 */
public class MainWindowFX extends Application{
    public static final int DEFAULT_WIDTH = 600;
    public static final int DEFAULT_HEIGHT = 600;

    private int width;
    private int height;

    private Scene scene;
    private TextArea messageView;
    private Button quitButton;
    private BorderPane layout;
    private Stage primaryStage;

    @Override
    public void start(Stage primaryStage) {
        System.out.println("Started building GUI....");
        this.buildGUI();
        System.out.println("Finished building GUI");
        this.primaryStage = primaryStage;
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(this.scene);
        primaryStage.show();
        System.out.println("Where the hell are you?");
    }

    public Scene getScene() {
        return this.scene;
    }

    public BorderPane getBorderPane() {
        return this.layout;
    }

    public Stage getPrimaryStage() {
        return this.primaryStage;
    }

    public void buildGUI() {
        System.out.println("Before layout");
        this.layout = new BorderPane();
        System.out.println("Before vbox");
        this.layout.setBottom(this.addVBox());
        System.out.println("before new scene");
        this.scene = new Scene(this.layout, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        System.out.println("after new scene");
    }


    public VBox addVBox() {
       VBox vbox = new VBox();
       vbox.setPadding(new Insets(15, 12, 15, 12));

       // message box
       this.messageView = TextAreaBuilder.create()
               .prefRowCount(5)
               .editable(false)
               .build();

       // quit button
       this.quitButton = new Button("Quit");
       this.quitButton.setPrefSize(100, 20);
       System.out.println("think of a good message?");
       vbox.getChildren().addAll(this.messageView, this.quitButton);
       System.out.println("before returning vbox");
       return vbox;
    }

    public void postMessage(final String s) {
        this.messageView.appendText(s);
    }
}

现在我想在这个对象的实例中使用另一个类:

Now I want to use an instance of this object in another class:

package drawappfx;

import java.io.InputStreamReader;
import java.io.Reader;
import javafx.scene.layout.BorderPane;

public class DrawAppFx
{
  public static void main(String[] args)
  {
    final MainWindowFX main = new MainWindowFX();
    BorderPane layout = main.getBorderPane();
    Reader reader = new InputStreamReader(System.in);
    Parser parser = new Parser(reader,layout,main);
    main.start(main.getPrimaryStage());
    parser.parse();
  }    

}

但是当我跑这个我跑的时候进入此错误:

But when I run this I ran into this error:

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.javafx.main.Main.launchApp(Main.java:658)
    at com.javafx.main.Main.main(Main.java:805)
Caused by: java.lang.IllegalStateException: Not on FX application thread; currentThread = main
    at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:237)
    at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:397)
    at javafx.scene.Scene.<init>(Scene.java:287)
    at javafx.scene.Scene.<init>(Scene.java:226)
    at drawappfx.MainWindowFX.buildGUI(MainWindowFX.java:74)
    at drawappfx.MainWindowFX.start(MainWindowFX.java:47)
    at drawappfx.DrawAppFx.main(DrawAppFx.java:39)
    ... 6 more
Java Result: 1

我已经对此进行了一些搜索并猜测它与线程有关......但我仍然不知道。有什么建议吗?

I've done some searches on this and guessed that it has something to do with threading... but I still have no idea. Any suggestions?

推荐答案

我已经多次遇到过这个问题,并且有一种相当简单的方法可以解决它。

I've had this problem several times and there is a fairly easy way to resolve it.

首先让我向您介绍 Mediator模式,基本上你想创建一个与你所有的 GUI 类有关系的类

First of all let me introduce you to the Mediator pattern, basically you want to create a class that has the relationship with all your GUI classes

(即不同的GUI类没有彼此拥有自己的实例,而不是所有人都有相同的参与者。)

(I.e the different GUI classes do not have their own instance of each other instead all of them has the same reference to the Mediator).

这对你的问题来说是个偏见。

That was a sidetrack now to your question.

为了更改窗口,您需要传递 Stage ,其中应放置新窗口,因此您的代码只需要微小的变化:

In order to change window you need to pass the Stage of which the new window should be placed upon because of this your code needs only a minor change:

现在我不经常这样做,但在你的情况下,我会做一个例外,下面的代码包含一个你可以复制粘贴的类你的程序并使用那个wi我将在代码之后解决问题我将完全解释我做了什么:

Now I do not often do this but in your case, I will make an exception the following code consists of a class that you can "Copy Paste" into your program and use that will fix the problem after the code I will explain exactly what I did:

Mediator

public class Mediator extends Application {

    private DrawAppFx daf;
    private MainWindowFX mainWindow;
    private Stage primaryStage;
    public Mediator(){
        daf = new DrawAppFx(this);
        mainWindow = new MainWindowFx(this);

    }
    public static void main(String[] args){
        launch(args);
    }
    @Override
    public void start(Stage stage) throws Exception {
        primaryStage = stage;
        mainWindow.start(primaryStage);
    }
    public void changeToDaf(){
        daf.start(primaryStage);
    }
}

现在每个 DrawAppFx MainWindowFx 必须有一个传递Mediator对象的构造函数,因此与 Has-a 有关系介体

Now each of the DrawAppFx and MainWindowFx must have a constructor that passes a Mediator object and therefore have a "Has-a" relationship with the mediator

这背后的原因是介体模式现在处于控制状态,如果你创建更多的窗口,它很容易实现,只需将它们添加到介体并添加方法调解员可以改为该窗口。

The reason behind this is that the mediator pattern is now in control and should you create more windows it is easy to implement just add them to the mediator and add a method for which the mediator can change to that window.

这篇关于使用来自另一个类的JavaFx应用程序实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆