从Main类方法启动JavaFX,它不会扩展Application

时间:2014-09-02 21:04:54

标签: inheritance javafx javafx-2

我从没有扩展javafx.application.Application的类的Main方法启动JavaFX应用程序时遇到问题

在我的应用程序中,MainApp.java应该在start()中启动覆盖方法MainUIController.java,该Applciation扩展MainUIController.java

当我从public class MainApp { public static void main(String[] args) { PersonJDBCTemplate jdbc = connect(); MainUIController mUIc = new MainUIController(jdbc); mUIc.start(new Stage()); } public static PersonJDBCTemplate connect() { ApplicationContext context = new ClassPathXmlApplicationContext( "Beans.xml"); PersonJDBCTemplate personJDBCTemplate = (PersonJDBCTemplate) context .getBean("personJDBCTemplate"); return personJDBCTemplate; } } 启动Main方法时,一切正常。

MainApp.java

public class MainUIController extends Application {

    private Stage stage;
    // private User loggedUser;
    private final double MINIMUM_WINDOW_WIDTH = 800.0;
    private final double MINIMUM_WINDOW_HEIGHT = 570.0;
    private String version = "0.6";
    private PersonJDBCTemplate jdbc;

    public MainUIController(PersonJDBCTemplate jdbc) {
        this.jdbc = jdbc;

    }

    @Override
    public void start(Stage primaryStage) {
        try {
            stage = primaryStage;
            stage.setTitle("Sharp");
            stage.setMinWidth(MINIMUM_WINDOW_WIDTH);
            stage.setMinHeight(MINIMUM_WINDOW_HEIGHT);
            stage.setResizable(false);
            gotoLogin();
            primaryStage.show();
        } catch (Exception ex) {
            Logger.getLogger(MainUIController.class.getName()).log(
                    Level.SEVERE, null, ex);
        }
    }

    public void gotoLogin() {
        try {
            LoginController login = (LoginController) replaceSceneContent("/fxml/Login.fxml");
            login.setApp(this);
        } catch (Exception ex) {
            Logger.getLogger(MainUIController.class.getName()).log(
                    Level.SEVERE, null, ex);
        }
    }
}

MainUIController.java

Exception in thread "main" java.lang.ExceptionInInitializerError
at javafx.stage.Window.<init>(Window.java:1110)
at javafx.stage.Stage.<init>(Stage.java:236)
at javafx.stage.Stage.<init>(Stage.java:224)
at ch.kit.sharp.main.MainApp.main(MainApp.java:15)
Caused by: java.lang.IllegalStateException: This operation is permitted on the event thread only; currentThread = main
at com.sun.glass.ui.Application.checkEventThread(Application.java:445)
at com.sun.glass.ui.Screen.setEventHandler(Screen.java:245)
at com.sun.javafx.tk.quantum.QuantumToolkit.setScreenConfigurationListener(QuantumToolkit.java:600)
at javafx.stage.Screen.<clinit>(Screen.java:80)
... 4 more

运行 MainApp 后,出现以下错误:

{{1}}

3 个答案:

答案 0 :(得分:22)

除了Nejinx所说的内容之外,您不能直接致电start(),始终致电launch(),因为它会设置 JavaFX环境,包括{{1} }和creation of stage将舞台作为参数传递给它。

The docs有一条特别说明这个

的说明
  

注意:此方法在JavaFX Application Thread

上调用

可以从任何类调用launch(),考虑到该类是否直接不扩展javafx.application.Application,那么您必须通过扩展它的类作为启动方法的参数。

例如,假设您有一个扩展calls start()

的课程JavaFXMain
Application

您可以使用任何其他类来启动JavaFX应用程序。

class JavaFXMain extends Application {...}

在您的情况下,您可以在class Main { ... public void someMethod() { ... JavaFXMain.launch(JavaFXMain.class); // Launch the JavaFX application ... } } 的主要方法中尝试类似的内容:

MainApp

答案 1 :(得分:2)

你需要初始化JavaFX环境,你不能在启动之外创建一个新的阶段(args);在扩展Application的类上首先被调用。

答案 2 :(得分:0)

这非常有用,但将FX应用程序作为独立应用程序。您无法从非FX代码传递对象,并且您无法获得创建的Application实例的句柄。

我提出了这个解决方法,我并不疯狂但它确实允许传入参数。

package hacks;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 * Created by WorkDay on 8/11/16.<br>
 * <br>
 * HelloWorld is a javaFX app that needs parameters that are real objects
 */

class AppParameterLauncher {
    public static void main(String[] args) {
        HelloWorld.launch(new ObjectThatContainsData("brave"), new ObjectThatContainsData("new"));
    }
}


public class HelloWorld extends Application {

    private static ObjectThatContainsData staticData1 = null;
    private static ObjectThatContainsData staticData2 = null;


    public static void launch(ObjectThatContainsData data1, ObjectThatContainsData data2) {
        HelloWorld.staticData1 = data1;
        HelloWorld.staticData2 = data2;
        Application.launch(HelloWorld.class);
    }

    private final ObjectThatContainsData data1 = HelloWorld.staticData1;
    private final ObjectThatContainsData data2 = HelloWorld.staticData2;

    @Override
    public void start(Stage primaryStage) {

        String Text = "Hello "+data1+" "+data2+" World!";
        primaryStage.setTitle(Text);
        Button btn = new Button();
        btn.setText("Say '"+Text+"'");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World!");
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.setX(0);
        primaryStage.setY(0);
        primaryStage.show();
    }
}

class ObjectThatContainsData {
    public final String data;

    ObjectThatContainsData(String data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return data;
    }
}