Запуск JavaFX из основного метода classа, который не расширяет Application

У меня возникла проблема с запуском приложения JavaFX из основного метода classа, который не расширяет javafx.application.Application

В моем приложении есть MainApp.java который должен запустить метод overriden start() в MainUIController.java , который расширяет Applciation

Когда я запускаю метод Main из MainUIController.java все работает отлично.

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.(Window.java:1110) at javafx.stage.Stage.(Stage.java:236) at javafx.stage.Stage.(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.(Screen.java:80) ... 4 more 

В дополнение к тому, что сказал Nejinx, вы не должны напрямую вызывать свой start() , всегда вызывайте launch() , потому что он настраивает среду JavaFX , включая creation of stage и calls start() передающие сцену в качестве параметра к ней.

В документах есть примечание, в котором указано это

ПРИМЕЧАНИЕ. Этот метод вызывается в приложении JavaFX Application Thread

launch() можно вызывать из любого classа , принимая во внимание, если class напрямую не расширяет javafx.application.Application , то вы должны передать class, расширяющий его как аргумент метода запуска.

Например, рассмотрим, что у вас есть class JavaFXMain который расширяет Application

 class JavaFXMain extends Application {...} 

Вы можете использовать любой другой class, чтобы запустить приложение JavaFX.

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

В вашем случае вы можете попробовать что-то подобное в основном методе MainApp :

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

Вам нужно инициализировать среду JavaFX, вы не можете создать новый этап вне запуска (args); вызывается первым в classе, который расширяет приложение.

Это было очень полезно, но оно оставляет приложение 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.
*
* 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() { @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; } }
  • Свободные интерфейсы и наследование в C #
  • Класс не является абстрактным и не отменяет абстрактного метода
  • operator = и функции, не наследуемые в C ++?
  • Почему я должен использовать ключевое слово «using» для доступа к методу базового classа?
  • Каков наилучший способ обеспечения статического конструктора базового classа?
  • Хорошие причины запретить наследование Java?
  • Когда использовать собственное наследование C ++ над составом?
  • Когда мне следует позвонить супер?
  • Почему в Java нет множественного наследования, но допускается реализация нескольких интерфейсов?
  • Почему я не могу наследовать статические classы?
  • В чем разница между переопределением виртуальных функций и скрытием не виртуальных функций?
  • Давайте будем гением компьютера.