web-dev-qa-db-ja.com

アプリケーションを拡張しないクラスのMainメソッドからJavaFXを起動する

_javafx.application.Application_を拡張しないクラスのMainメソッドからJavaFXアプリケーションを起動するのに問題があります

私のアプリケーションには、_MainApp.Java_のオーバーライドされたメソッドstart()を開始する_MainUIController.Java_があります。これはApplciationを拡張します。

_MainUIController.Java_からMainメソッドを開始すると、すべてが正常に機能します。

MainApp.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;
    }
}
_

MainUIController.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);
        }
    }
}
_

MainAppを実行した後、次のエラーが発生します:

_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
_
12
Reubaer

Nejinxが言ったことに加えて、start()を直接呼び出さないでください。を設定するため、常に launch() を呼び出してください。 JavaFX環境。ステージをパラメーターとして渡す_creation of stage_およびcalls start()を含みます。

ドキュメント これを特別に述べたメモがあります

注:このメソッドは、JavaFXアプリケーションスレッドで呼び出されます

launch() は、クラスが直接拡張されていないかどうかを考慮して、任意のクラスから呼び出すことができます _javafx.application.Application_ の場合、起動メソッドへの引数としてそれを拡張するクラスを渡す必要があります。

たとえば、JavaFXMainを拡張するクラスApplicationがあるとします。

_class JavaFXMain extends Application {...}
_

他のクラスを使用して、JavaFXアプリケーションを起動できます。

_class Main {
   ...
   public void someMethod() {
      ...
      JavaFXMain.launch(JavaFXMain.class); // Launch the JavaFX application
      ...
   }
}
_

あなたの場合、MainAppのmainメソッド内で次のようなことを試すことができます。

_// You may remove args if you don't intend to pass any arguments
MainUIController.launch(MainUIController.class, args) 
_
22
ItachiUchiha

JavaFX環境を初期化する必要があります。launch(args)以外に新しいステージを作成することはできません。 Applicationを拡張するクラスで最初に呼び出されます。

2
nejinx

これは非常に役に立ちましたが、FXアプリケーションはスタンドアロンアプリケーションのままです。 FX以外のコードからオブジェクトを渡すことはできず、作成されたアプリケーションインスタンスへのハンドルが提供されません。

私はこの回避策を思いついたのですが、これは気が狂っていませんが、パラメーターを渡すことはできます。

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;
    }
}
0
Bday