2015-02-04 10 views
8

Lassen Sie uns sagen, wir die folgende Klasse haben:Wie startet JavaFX 8 den JavaFX-Anwendungs-Thread in einer fast leeren Application-Klasse?

import javafx.application.Application; 
import javafx.stage.Stage; 

public class Test extends Application 
{ 
    public Test() 
    { 
     System.out.println("Constructor"); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception 
    { 
     System.out.println("start"); 
    } 

    public static void main(String... args) 
    { 
     System.out.println("main"); 
    } 
} 

Aus Application abgeleitet ist, aber es ist nicht eine ihrer Methoden. Normalerweise starten Sie eine JavaFX-Anwendung, indem Sie im Wesentlichen launch(args) aufrufen.

Wenn ich dieses Programm starte, ist die einzige Ausgabe "main", also werden der Konstruktor und der Start nicht aufgerufen, aber das Programm wird nicht beendet, weil ein JavaFX Application Thread läuft. Aber woher kommt es?

Ich habe ein Debugging durchgeführt und festgestellt, dass der Thread vom Hauptthread gestartet wird, bevor die Hauptmethode ausgeführt wird. Der Stack-Trace beginnt mit NativeMethodAccessorImpl.

noch seltsamer Um: wenn ich die Haupt-Methode aus einer anderen Klasse starten, wird der JavaFX Anwendungsthread nicht gestartet:

public class Test2 
{ 
    public static void main(String[] args) 
    { 
     Test.main(args); 
    } 
} 

Also, was diese Art von schwarzer Magie ist?

+0

Upvote für schwarze Magie. – GGrec

+0

In der zweiten Klasse, Test2, haben Sie in Ihrer ursprünglichen Klassendeklaration keine erweiterte Anwendung hinzugefügt. Ihre Runtime hat also keine Ahnung, dass ein JavaFX-Prozess beteiligt ist - es könnte eine Hauptmethode (.) Einer anderen Art von Java-Klasse sein. – Trunk

Antwort

5

Java verwendet verschiedene Ansätze, um die beiden Anwendungen zu starten.

Versuchen Sie den folgenden Code ausführen:

public class Test3 { 

    public static void main(String[] args) { 

     Class<?> actualMainClassTest = LauncherHelper.checkAndLoadMain(true, 1, Test.class.getName()); 
     Class<?> actualMainClassTest2 = LauncherHelper.checkAndLoadMain(true, 1, Test2.class.getName()); 

     System.out.println("Actual loaded main class for Test: " + actualMainClassTest.getName()); 
     System.out.println("Actual loaded main class for Test2: " + actualMainClassTest2.getName()); 
    } 
} 

Der Ausgang ist

  • gerade geladene Hauptklasse für Test: sun.launcher.LauncherHelper $ FXHelper
  • gerade geladene Hauptklasse für Test2: Test2

Sie können sehen, dass die tatsächlich geladene Hauptklasse für die Test2 Klasse ist Test2, aber die geladene Hauptklasse für Test ist sun.launcher.LauncherHelper$FXHelper.

Dies geschieht, weil der Java-Launcher prüft, ob die Hauptklasse, die gestartet werden soll, eine Unterklasse von javafx.application.Application ist. Wenn dies der Fall ist, wird stattdessen die Hauptmethode sun.launcher.LauncherHelper$FXHelper geladen, die für JavaFX-Anwendungen eine Startprogrammmethode aufruft (com.sun.javafx.application.LauncherImpl#launchApplication).

Diese Methode ist verantwortlich für den Start der JavaFX-Anwendung. Test#main aufgerufen wird, nachdem die Anwendung gestartet wird:

enter image description here

Wenn Test#main von Test2 aufgerufen wird, wird der FX-Launcher nicht verwendet, weil Test2 nicht eine Unterklasse von javafx.application.Application ist.

+0

Also, das ist ein Verhalten von java.exe und funktioniert nur für javafx.application.Application? – Rafaesp

Verwandte Themen