Using a JavaFx application instance from another class


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;

    public void start(Stage primaryStage) {
        System.out.println("Started building GUI....");
        System.out.println("Finished building GUI");
        this.primaryStage = primaryStage;
        primaryStage.setTitle("Hello World!");
        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");
        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()

       // 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) {

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

package drawappfx;

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(;
    Parser parser = new Parser(reader,layout,main);


But when I run this I ran into this error:

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(
    at java.lang.reflect.Method.invoke(
    at com.javafx.main.Main.launchApp(
    at com.javafx.main.Main.main(
Caused by: java.lang.IllegalStateException: Not on FX application thread; currentThread = main
    at javafx.scene.Scene.<init>(
    at javafx.scene.Scene.<init>(
    at drawappfx.MainWindowFX.buildGUI(
    at drawappfx.MainWindowFX.start(
    at drawappfx.DrawAppFx.main(
    ... 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?

8/29/2013 6:11:15 PM

Accepted Answer

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

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

(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.

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:

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:


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){
    public void start(Stage stage) throws Exception {
        primaryStage = stage;
    public void changeToDaf(){

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.

4/18/2018 12:33:21 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow