2014-09-02 96 views
11

我有问题,从不延伸javafx.application.Application从不延伸应用

在我的应用程序类的主要方法开始JavaFX应用程序类的主要方法开始JavaFX的存在MainApp.java当我开始Main方法从MainUIController.java一切工作正常,应启动在MainUIController.java,延伸Applciation

的覆盖方法start()

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 

回答

19

除了什么Nejinx说,你一定不要直接打电话给你的start(),随时调用launch(),因为它设置了JavaFX的环境,包括creation of stagecalls start()传递阶段作为一个参数给它。

The docs有一个注释专门说明这个

注意:此方法被调用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的主要方法中:

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

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

0

这是非常有益的,但离开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; 
    } 
}