Erkunden der JavaFX-Anwendungsklasse

JavaFX-Anwendungen basieren auf der JavaFX- ApplicationKlasse. Vielleicht sind Sie mit dieser Klasse nicht vertraut und haben Fragen zur Verwendung Applicationund zu den Angeboten dieser Klasse für Ihren Anwendungscode. Dieser Beitrag versucht, diese Fragen beim Erkunden zu beantworten Application.

Einführung in die Anwendung

Die javafx.application.ApplicationKlasse bietet ein Framework zum Verwalten einer JavaFX-Anwendung. Diese Anwendung muss eine erweiterte Klasse enthalten, die Applicationverschiedene Methoden überschreibt, die die JavaFX-Laufzeit aufruft, um anwendungsspezifischen Code auszuführen.

Eine Anwendung kann ApplicationMethoden aufrufen , um Startparameter abzurufen, auf Hostdienste zuzugreifen, sich selbst als eigenständige Anwendung zu starten, mit dem Preloader (einer kleinen Anwendung, die vor der Hauptanwendung gestartet wurde, um die Starterfahrung anzupassen) zu interagieren und auf den Benutzeragenten zuzugreifen ( Webbrowser) Stylesheet.

Anwendungsstile

Eine JavaFX-Anwendung kann als eigenständige Anwendung, als Applet und als Java WebStart-Anwendung gestartet werden. In diesem Beitrag zeige ich nur den eigenständigen Anwendungsstil.

Anwendungslebenszyklus

Eine der ApplicationAufgaben besteht darin, den Lebenszyklus der Anwendung zu verwalten . Die folgenden überschreibbaren ApplicationMethoden spielen in diesem Lebenszyklus eine Rolle:

  • void init(): Initialisieren Sie eine Anwendung. Eine Anwendung kann diese Methode überschreiben, um die Initialisierung durchzuführen, bevor die Anwendung gestartet wird. ApplicationDie init()Methode macht nichts.
  • void start(Stage primaryStage): Starten Sie eine Anwendung. Eine Anwendung muss diese abstrakte Methode überschreiben, um den Einstiegspunkt der Anwendung bereitzustellen. Das primaryStageArgument gibt einen Container für die Benutzeroberfläche an.
  • void stop(): Beenden Sie eine Anwendung. Eine Anwendung kann diese Methode überschreiben, um sich auf das Beenden der Anwendung vorzubereiten und Ressourcen zu zerstören. ApplicationDie stop()Methode macht nichts.

Die JavaFX-Laufzeit interagiert mit einer Anwendung und ruft diese Methoden in der folgenden Reihenfolge auf:

  1. Erstellen Sie eine Instanz der Klasse, die erweitert wird Application.
  2. Rufen Sie init()den JavaFX Launcher-Thread auf. Da init()ist nicht auf dem JavaFX Anwendung Gewinde aufgerufen, darf es nicht schaffen javafx.scene.Sceneoder javafx.stage.StageObjekte, sondern können andere JavaFX Objekte erstellen.
  3. Rufen Sie start()nach der init()Rückkehr den JavaFX-Anwendungsthread auf, und die JavaFX-Laufzeit ist bereit, damit die JavaFX-Anwendung ausgeführt werden kann.
  4. Warten Sie, bis die Anwendung abgeschlossen ist. Die Anwendung wird beendet, wenn sie aufgerufen wird javafx.application.Platform.exit()oder wenn das letzte Fenster geschlossen wurde und Platformdas implicitExitAttribut auf gesetzt ist true.
  5. Rufen Sie stop()den JavaFX-Anwendungsthread auf. Nachdem diese Methode zurückgegeben wurde, wird die Anwendung beendet.

JavaFX erstellt einen Anwendungsthread, der als JavaFX-Anwendungsthread bezeichnet wird , um die Anwendungen start()und stop()Methoden auszuführen, Eingabeereignisse zu verarbeiten und Animationszeitleisten auszuführen. Das Erstellen von JavaFX Sceneund StageObjekten sowie das Anwenden von Änderungsvorgängen für Szenendiagramme auf Live-Objekte (die Objekte, die bereits an eine Szene angehängt sind) müssen im JavaFX-Anwendungsthread ausgeführt werden.

Das javaLauncher-Tool lädt und initialisiert die angegebene ApplicationUnterklasse im JavaFX-Anwendungsthread. Wenn main()die ApplicationKlasse keine Methode enthält oder die main()Methode aufruft Application.launch(), wird eine Instanz der ApplicationUnterklasse im JavaFX-Anwendungsthread erstellt.

Die init()Methode wird im JavaFX Launcher-Thread aufgerufen. Dies ist der Thread, der die Anwendung startet. Es wird im JavaFX-Anwendungsthread nicht aufgerufen. Daher darf eine Anwendung kein Sceneoder StageObjekt in erstellen init(). Eine Anwendung kann jedoch andere JavaFX-Objekte in der init()Methode erstellen .

Unbehandelte Ausnahmen

Alle nicht behandelten Ausnahmen, die im JavaFX-Anwendungsthread auftreten (während des Ereignisauslösens, Ausführen von Animationszeitleisten oder anderen Codes), werden an den nicht erfassten Ausnahmebehandler des Threads weitergeleitet.

Listing 1 zeigt eine einfache JavaFX-Anwendung, die diesen Lebenszyklus demonstriert.

Listing 1: LifeCycle.java

import javafx.application.Application; import javafx.application.Platform; import javafx.stage.Stage; public class LifeCycle extends Application { @Override public void init() { System.out.printf("init() called on thread %s%n", Thread.currentThread()); } @Override public void start(Stage primaryStage) { System.out.printf("start() called on thread %s%n", Thread.currentThread()); Platform.exit(); } @Override public void stop() { System.out.printf("stop() called on thread %s%n", Thread.currentThread()); } }

Kompilieren Sie Listing 1 wie folgt:

javac LifeCycle.java

Führen Sie das Ergebnis LifeCycle.classwie folgt aus:

java LifeCycle

Sie sollten die folgende Ausgabe beachten:

init() called on thread Thread[JavaFX-Launcher,5,main] start() called on thread Thread[JavaFX Application Thread,5,main] stop() called on thread Thread[JavaFX Application Thread,5,main]

Die Ausgabe zeigt, dass init()auf einem anderen Thread als start()und stopaufgerufen wird, die auf demselben Thread aufgerufen werden. Da verschiedene Threads beteiligt sind, müssen Sie möglicherweise die Synchronisierung verwenden.

Wenn Sie einen Kommentar abgeben Platform.exit(), wird die stop() called on thread Thread[JavaFX Application Thread,5,main]Nachricht nicht angezeigt , da die JavaFX-Laufzeit nicht aufgerufen wird stop()und die Anwendung nicht beendet wird.

Anwendungsparameter

ApplicationBietet die Application.Parameters getParameters()Methode zum Zurückgeben der Parameter der Anwendung, einschließlich der in der Befehlszeile übergebenen Argumente, unbenannter Parameter, die in einer JNLP-Datei (Java Network Launch Protocol) angegeben sind, und Paare, die in einer JNLP-Datei angegeben sind.

Über getParameters()

getParameters()kann aufgerufen init()werden start(), stop()und alle Methoden, die von diesen Methoden aufgerufen werden. Es wird zurückgegeben, nullwenn es von einem der Konstruktoren der Anwendungsunterklasse aufgerufen wird.

Application.Parameters kapselt die Parameter und bietet die folgenden Methoden für den Zugriff darauf:

  • Map getNamed(): Gibt eine schreibgeschützte Karte der genannten Parameter zurück. Die Karte ist möglicherweise leer, aber niemals null. Zu den benannten Parametern gehören Paare, die explizit in einer JNLP-Datei angegeben sind, sowie alle Befehlszeilenargumente der folgenden Form : .--name=value
  • List getRaw(): Return a read-only list of the raw arguments. This list may be empty but is never null. For a standalone application, it's the ordered list of arguments specified on the command line. For an applet or WebStart application, it includes unnamed parameters as well as named parameters. For named parameters, each pair is represented as a single argument of the form --name=value.
  • List getUnnamed(): Return a read-only list of the unnamed parameters. This list may be empty but is never null. Named parameters (which are represented as pairs) are filtered out.

Listing 2 presents a simple JavaFX application that demonstrates these methods.

Listing 2. Parameters.java

import java.util.List; import java.util.Map; import javafx.application.Application; import javafx.application.Platform; import javafx.stage.Stage; public class Parameters extends Application { @Override public void start(Stage primaryStage) { Application.Parameters parm = getParameters(); System.out.printf("Named parameters: %s%n", parm.getNamed()); System.out.printf("Raw parameters: %s%n", parm.getRaw()); System.out.printf("Unnamed parameters: %s%n", parm.getUnnamed()); Platform.exit(); } }

Compile Listing 2 as follows:

javac Parameters.java

Run the resulting Parameters.class as follows:

java Parameters a b c --name=w -name2=x --foo=y -foo=z bar=q

You should observe the following output:

Named parameters: {foo=y, name=w} Raw parameters: [a, b, c, --name=w, -name2=x, --foo=y, -foo=z, -bar=q] Unnamed parameters: [a, b, c, -name2=x, -foo=z, -bar=q]

Host services

Application provides the HostServices getHostServices() method for accessing the host services provider, which lets the application obtain its code and document bases, show a Web page in a browser, and communicate with the enclosing Web page using JavaScript when running in a browser.

The javafx.application.HostServices class declares the following methods:

  • String getCodeBase(): Get the code base URI for this application. If the application was launched via a JNLP file, this method returns the codebase parameter specified in the JNLP file. If the application was launched in standalone mode, this method returns the directory containing the application JAR file. If the application is not packaged in a JAR file, this method returns the empty string.
  • String getDocumentBase(): Get the document base URI for this application. If the application is embedded in a browser, this method returns the URI of the Web page containing the application. If the application was launched in WebStart mode, this method returns the the codebase parameter specified in the JNLP file (the document base and the code base are the same in this mode). If the application was launched in standalone mode, this method returns the URI of the current directory.
  • JSObject getWebContext(): Return the JavaScript handle of the enclosing DOM window of the Web page containing this application. This handle is used to access the Web page by calling from Java into JavaScript. If the application is not embedded in a Web page, this method returns null.
  • String resolveURI(String base, String rel): Resolve the specified relative URI against the base URI and return the resolved URI. This method throws java.lang.NullPointerException when either the base or the rel strings are null. It throws java.lang.IllegalArgumentException when there is an error parsing either the base or rel URI strings, or when there is any other error in resolving the URI.
  • void showDocument(String uri): Open the specified URI in a new browser window or tab. The determination of whether it is a new browser window or a tab in an existing browser window will be made by the browser preferences. Note that this will respect the pop-up blocker settings of the default browser; it will not try to circumvent them.

Listing 3 presents a simple JavaFX application that demonstrates most of these methods.

Listing 3. HostServ.java

import javafx.application.Application; import javafx.application.HostServices; import javafx.application.Platform; import javafx.stage.Stage; public class HostServ extends Application { @Override public void start(Stage primaryStage) { HostServices hs = getHostServices(); System.out.printf("Code base: %s%n", hs.getCodeBase()); System.out.printf("Document base: %s%n", hs.getDocumentBase()); System.out.printf("Web context: %s%n", hs.getWebContext()); Platform.exit(); } }

Compile Listing 3 as follows:

javac HostServ.java

Run the resulting HostServ.class as follows:

java HostServ

You should observe something similar to the following output:

Code base: Document base: file:/C:/cpw/javaqa/article19/code/HostServ/ Web context: null

Launching a standalone application

A JavaFX application doesn't require a main() method. The JavaFX runtime takes care of launching the application and saving command-line arguments. However, if you need to perform various tasks before the application is launched, you can specify a main() method and have it invoke one of the following static methods:

  • void launch(Class appClass, String... args): Launch a standalone application, where appClass identifies the class that's constructed and executed by the launcher, and args identifies the command-line arguments that are passed to the application. This method doesn't return until the application has exited, either via Platform.exit() or by all of the application windows having been closed. It throws java.lang.IllegalStateException when invoked more than once, and throws IllegalArgumentException when appClass doesn't subclass Application.
  • void launch(String... args): Launch a standalone application. This method is equivalent to invoking the previous method with the Class object of the immediately enclosing class of the method that called launch().

Listing 4 presents a simple JavaFX application that demonstrates the second launch() method.

Listing 4. Launch.java

import javafx.application.Application; import javafx.application.Platform; import javafx.stage.Stage; public class Launch extends Application { @Override public void start(Stage primaryStage) { System.out.printf("start() called on %s%n", Thread.currentThread()); Platform.exit(); } public static void main(String[] args) { System.out.printf("main() called on %s%n", Thread.currentThread()); Application.launch(args); System.out.printf("terminating"); } }

Compile Listing 4 as follows:

javac Launch.java

Führen Sie das Ergebnis Launch.classwie folgt aus:

java Launch

Sie sollten die folgende Ausgabe beachten:

main() called on Thread[main,5,main] start() called on Thread[JavaFX Application Thread,5,main] terminating