2014-09-02 8 views
11

nicht Anwendung ich Problem habe erstreckt sich eine JavaFX-Anwendung von einem Haupt Methode einer Klasse zu starten, die nicht javafx.application.ApplicationAb JavaFX aus Main-Methode der Klasse, die

In meiner Anwendung erstreckt sich die MainApp.java die sollte die überschriebene Methode start() im MainUIController.java, beginnen die Applciation

erweitert Wenn ich die Main-Methode starten aus der MainUIController.java alles funktioniert.

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); 
     } 
    } 
} 

Nach dem MainApp läuft, bekomme ich folgende Fehler:

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 

Antwort

19

Zusätzlich zu dem, was Nejinx sagte, müssen Sie nicht direkt anrufen Ihre start(), immer launch() nennen, weil es die JavaFX Umgebung einrichtet, einschließlich creation of stage und calls start() die Bühne als es Parameter.

The docs hat speziell eine Notiz dieses

Hinweis besagt: Diese Methode basiert auf der JavaFX Anwendung Gewinde

genannt

Die launch() von jede Klasse aufgerufen werden kann, berücksichtigt werden, wenn die Klasse erweitert sich nicht direkt javafx.application.Application, dann müssen Sie übergeben die Klasse als Argument für die Startmethode erweitern.

Betrachten wir zum Beispiel eine Klasse JavaFXMain haben, die Application

class JavaFXMain extends Application {...} 

erweitert Sie andere Klasse verwenden können, um die JavaFX-Anwendung zu starten.

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

In Ihrem Fall können Sie so etwas wie dies in der Hauptmethode MainApp versuchen:

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

Sie müssen die JavaFX-Umgebung initialisieren, Sie können keine neue Stage außerhalb des Starts erstellen (args); zuerst in der Klasse aufgerufen wird, die Application erweitert.

0

Das war sehr hilfreich, lassen aber die FX-Anwendung als Stand-alone-Anwendung. Sie können keine Objekte aus Ihrem Nicht-FX-Code übergeben, und Sie erhalten kein Handle für die erstellte Anwendungsinstanz.

Ich kam zu dieser Problemumgehung, die ich nicht verrückt bin, aber es erlaubt Parameter übergeben werden.

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; 
    } 
} 
Verwandte Themen