All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javafx.application.Preloader Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javafx.application;

import java.security.AccessController;
import java.security.PrivilegedAction;

/**
 * Class that is extended to define an optional preloader for a
 * JavaFX Application.
 * An application may contain a preloader that is used
 * to improve the application loading experience.
 *
 * 

* A preloader is a small application that is started * before the main application to customize the startup experience. * The preloader: *

*
    *
  • gets notification of progress of loading application resources
  • *
  • gets notification of errors
  • *
  • gets notification of application initialization and startup
  • *
  • decides when application should become visible
  • *
* *

* The default preloader is shown on top of the application Stage, which is not * visible until the preloader is visible. The preloader need to hide itself * to make the application visible. Good practice is to do this no earlier than * right before application.start() is called, as otherwise application itself * is not visible. *

* *

* The preloader may also cooperate with the application to achieve advanced * visual effects or share data (e.g. to implement login screen). * The preloader gets a reference to the application and may pull data it * needs for cooperation from the application if the application implements * an interface that the preloader knows about and relies upon. Generally it * is not recommended to design preloaders in such a way that an application * would call them directly, as this will result in bad user experience if * the application is signed and the preloader is not. *

* *

* If the application does not specify a preloader, then the default preloader * is used. Default preloader appearance can be customized * (set of parameters is TBD). *

* *

* Custom preloader implementations should follow these rules: *

*
    *
  1. a custom preloader class should extend Preloader
  2. *
  3. classes needed for preloader need to be packaged in the separate jar.
  4. *
* *

* Applications may also send custom notification to the preloader using the * {@link #notifyPreloader notifyPreloader} method. This way a preloader may * also show application initialization progress. *

* *

* Note that preloaders are subject to the same rules as other JavaFX * applications including FX threading rules. In particular, the class * constructor and init() method will be called on a non-FX thread and start() * will be executed on the FX application thread. * This also means that the application constructor/init() will run concurrently * with preloader start(). *

* *

* Callbacks on preloader notification will be delivered on the FX * application thread. *

* *

* Shutdown (including when stop() is called) is TBD. *

* @since JavaFX 2.0 */ public abstract class Preloader extends Application { // Too bad this isn't already available in a Java core class private static final String lineSeparator; static { @SuppressWarnings("removal") String prop = AccessController.doPrivileged((PrivilegedAction) () -> System.getProperty("line.separator")); lineSeparator = prop != null ? prop : "\n"; } /** * Constructor for subclasses to call. */ public Preloader() { } /** * Indicates download progress. * This method is called by the FX runtime to indicate progress while * application resources are being loaded. It will not be called to deliver * a ProgressNotification sent to {@link #notifyPreloader notifyPreloader}. * *

* The implementation of this method provided by the Preloader class * does nothing. *

* * @param info the progress notification */ public void handleProgressNotification(ProgressNotification info) { } /** * Indicates a change in application state. * This method is called by the FX runtime as part of the * application life-cycle. * *

* The implementation of this method provided by the Preloader class * does nothing. *

* * @param info the state change notification */ public void handleStateChangeNotification(StateChangeNotification info) { } /** * Indicates an application-generated notification. * This method is called by the FX runtime to deliver a notification sent * via {@link #notifyPreloader notifyPreloader}. * *

* Applications should not call this method directly, but should use * {@link #notifyPreloader notifyPreloader} instead to avoid mixed code dialog issues. *

* *

* The implementation of this method provided by the Preloader class * does nothing. *

* * @param info the application-generated notification */ public void handleApplicationNotification(PreloaderNotification info) { } /** * Called when an error occurs. * *

* The implementation of this method provided by the Preloader class * returns false, indicating that the default error handler should * show the message to the user. *

* * @param info the error notification describing the cause of this error * * @return true if error was shown to the user by preloader and no * additional visualization is needed; otherwise, false. */ public boolean handleErrorNotification(ErrorNotification info) { return false; } // /** // * Called when security or other system modal dialog is shown or hidden // * (such as proxy auth dialog). // * // *

// * The implementation of this method provided by the Preloader class // * does nothing. // *

// * // * @param info the UI notification // */ // public void handleUINotification(UINotification info) { // // TODO RT-19601: not used for now pending completion of JRE work //-- System.err.println("Preloader: handleUINotification = " + info); // } // ------------------------------------------------------------------------ /** * Marker interface for all Preloader notification. * @since JavaFX 2.0 */ public static interface PreloaderNotification { } /** * Preloader notification that reports an error. * This is delivered to preloader in case of problem with application startup. * @since JavaFX 2.0 */ public static class ErrorNotification implements PreloaderNotification { private String location; private String details = ""; private Throwable cause; /** * Constructs an error notification. * * @param location the URL associated with an error (if any); may be null * @param details a string describing the error; must be non-null * @param cause the cause of the error; may be null */ public ErrorNotification(String location, String details, Throwable cause) { if (details == null) throw new NullPointerException(); this.location = location; this.details = details; this.cause = cause; } /** * Retrieves the URL associated with this error, if any. * For example, if there is a download or singing check error, this * will be the URL of the jar file that has the problem. * It may be null. * * @return the location, or null */ public String getLocation() { return location; } /** * Retrieves the description of the error. * It may be the empty string, but is always non-null. * * @return the description of the error */ public String getDetails() { return details; } /** * Retrieves the Exception or Error associated with this error * notification, if any. It may be null. * * @return the cause of the error, or null */ public Throwable getCause() { return cause; } /** * Returns a string representation of this {@code ErrorNotification} object. * @return a string representation of this {@code ErrorNotification} object. */ @Override public String toString() { StringBuilder str = new StringBuilder("Preloader.ErrorNotification: "); str.append(details); if (cause != null) { str.append(lineSeparator).append("Caused by: ").append(cause.toString()); } if (location != null) { str.append(lineSeparator).append("Location: ").append(location); } return str.toString(); } } /** * Preloader notification that reports progress. This is typically used to * report progress while downloading and initializing the application. * @since JavaFX 2.0 */ public static class ProgressNotification implements PreloaderNotification { private final double progress; private final String details; /** * Constructs a progress notification. * * @param progress a value indicating the progress. * A negative value for progress indicates that the progress is * indeterminate. A value between 0 and 1 indicates the amount * of progress. Any value greater than 1 is interpreted as 1. */ public ProgressNotification(double progress) { this(progress, ""); } // NOTE: We could consider exposing details in the future, but currently // have no plan to do so. This method is private for now. /** * Constructs a progress notification. * * @param progress a value indicating the progress. * A negative value for progress indicates that the progress is * indeterminate. A value between 0 and 1 indicates the amount * of progress. Any value greater than 1 is interpreted as 1. * * @param details the details of this notification */ private ProgressNotification(double progress, String details) { this.progress = progress; this.details = details; } /** * Retrieves the progress for this notification. Progress is in the * range of 0 to 1, or is negative for indeterminate progress. * * @return the progress */ public double getProgress() { return progress; } /** * Retrieves the details of the progress notification * * @return the details of this notification */ private String getDetails() { return details; } } /** * A notification that signals a change in the application state. * A state change notification is sent to a preloader immediately prior * to loading * the application class (and constructing an instance), calling the * application init method, or calling the application start method. * @since JavaFX 2.0 */ public static class StateChangeNotification implements PreloaderNotification { /** * Enum that defines the type of change associated with this notification * @since JavaFX 2.0 */ public enum Type { /** * Indicates that the application class is about to be loaded and * constructed. */ BEFORE_LOAD, /** * Indicates that the application's init method is about to be called. */ BEFORE_INIT, /** * Indicates that the application's start method is about to be called. */ BEFORE_START } private final Type notificationType; private final Application application; /** * Constructs a StateChangeNotification of the specified type. * * @param notificationType the type of this notification. */ public StateChangeNotification(Type notificationType){ this.notificationType = notificationType; this.application = null; } /** * Constructs an StateChangeNotification of the specified type for the * specified application. * * @param notificationType the type of this notification. * @param application the application instance associated with this * notification. */ public StateChangeNotification(Type notificationType, Application application) { this.notificationType = notificationType; this.application = application; } /** * Returns the type of notification. * * @return one of: BEFORE_LOAD, BEFORE_INIT, BEFORE_START */ public Type getType() { return notificationType; } /** * Returns the Application instance associated with this notification. * This is null for a BEFORE_LOAD notification and non-null for other * notification types. * * @return the Application instance or null. */ public Application getApplication() { return application; } } // /** // * Used to signal about global modal dialogs to be shown that block // * application launch. In particular proxy and security dialogs // */ // public static class UINotification implements PreloaderNotification { // //TODO RT-19601: implementation pending JRE work // } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy