Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.application; 027 028import java.security.AccessController; 029import java.security.PrivilegedAction; 030 031/** 032 * Class that is extended to define an optional preloader for a 033 * JavaFX Application. 034 * An application may contain a preloader that is used 035 * to improve the application loading experience, especially for applications 036 * that are embedded in a browser or launched in webstart execution mode. 037 * 038 * <p> 039 * A preloader is a small application that is started 040 * before the main application to customize the startup experience. 041 * The preloader: 042 * </p> 043 * <ul> 044 * <li>gets notification of progress of loading application resources</li> 045 * <li>gets notification of errors</li> 046 * <li>gets notification of application initialization and startup</li> 047 * <li>decides when application should become visible</li> 048 * </ul> 049 * 050 * <p> 051 * The default preloader is shown on top of the application Stage, which is not 052 * visible until the preloader is visible. The preloader need to hide itself 053 * to make the application visible. Good practice is to do this no earlier than 054 * right before application.start() is called, as otherwise application itself 055 * is not visible. 056 * </p> 057 * 058 * <p> 059 * The preloader may also cooperate with the application to achieve advanced 060 * visual effects or share data (e.g. to implement login screen). 061 * The preloader gets a reference to the application and may pull data it 062 * needs for cooperation from the application if the application implements 063 * an interface that the preloader knows about and relies upon. Generally it 064 * is not recommended to design preloaders in such a way that an application 065 * would call them directly, as this will result in bad user experience if 066 * the application is signed and the preloader is not. 067 * </p> 068 * 069 * <p> 070 * If the application does not specify a preloader, then the default preloader 071 * is used. Default preloader appearance can be customized 072 * (set of parameters is TBD). 073 * </p> 074 * 075 * <p> 076 * Custom preloader implementations should follow these rules: 077 * </p> 078 * <ol> 079 * <li>there should be class extending Preloader</li> 080 * <li>classes needed for preloader need to be packaged in the separate jar. 081 * We recommend this jar to be unsigned.</li> 082 * <li>JNLP deployment descriptor should have preloader-class attribute 083 * with full name of the class as value in the javafx-desc element 084 * and jars needed for progress need to have download="progress" type</li> 085 * </ol> 086 * 087 * <p> 088 * Applications may also send custom notification to the preloader using the 089 * notifyCurrentPreloader() method. This way a preloader may also show 090 * application initialization progress. 091 * </p> 092 * 093 * <p> 094 * Note that preloaders are subject to the same rules as other JavaFX 095 * applications including FX threading rules. In particular, the class 096 * constructor and init() method will be called on a non-FX thread and start() 097 * will be executed on the FX application thread. 098 * This also means that the application constructor/init() will run concurrently 099 * with preloader start(). 100 * </p> 101 * 102 * <p> 103 * Callbacks on preloader notification will be delivered on the FX 104 * application thread. 105 * </p> 106 * 107 * <p> 108 * Shutdown (including when stop() is called) is TBD. 109 * </p> 110 */ 111public abstract class Preloader extends Application { 112 113 // Too bad this isn't already available in a Java core class 114 private static final String lineSeparator; 115 116 static { 117 String prop = AccessController.doPrivileged(new PrivilegedAction<String>() { 118 @Override public String run() { 119 return System.getProperty("line.separator"); 120 } 121 }); 122 lineSeparator = prop != null ? prop : "\n"; 123 } 124 125 /** 126 * Indicates progress. 127 * 128 * <p> 129 * The implementation of this method provided by the Preloader class 130 * does nothing. 131 * </p> 132 * 133 * @param info the progress notification 134 */ 135 public void handleProgressNotification(ProgressNotification info) { 136 } 137 138 /** 139 * Indicates a change in application state. 140 * 141 * <p> 142 * The implementation of this method provided by the Preloader class 143 * does nothing. 144 * </p> 145 * 146 * @param info the state change notification 147 */ 148 public void handleStateChangeNotification(StateChangeNotification info) { 149 } 150 151 /** 152 * Indicates an application-generated notification. 153 * Application should not call this method directly, but should use 154 * notifyCurrentPreloader() instead to avoid mixed code dialog issues. 155 * 156 * <p> 157 * The implementation of this method provided by the Preloader class 158 * does nothing. 159 * </p> 160 * 161 * @param info the application-generated notification 162 */ 163 public void handleApplicationNotification(PreloaderNotification info) { 164 } 165 166 /** 167 * Called when an error occurs. 168 * 169 * <p> 170 * The implementation of this method provided by the Preloader class 171 * returns false, indicating that the default error handler should 172 * show the message to the user. 173 * </p> 174 * 175 * @param info the error notification describing the cause of this error 176 * 177 * @return true if error was shown to the user by preloader and no 178 * additional visualization is needed; otherwise, false. 179 */ 180 public boolean handleErrorNotification(ErrorNotification info) { 181 return false; 182 } 183 184// /** 185// * Called when security or other system modal dialog is shown or hidden 186// * (such as proxy auth dialog). 187// * 188// * <p> 189// * The implementation of this method provided by the Preloader class 190// * does nothing. 191// * </p> 192// * 193// * @param info the UI notification 194// */ 195// public void handleUINotification(UINotification info) { 196// // TODO RT-19601: not used for now pending completion of JRE work 197//// System.err.println("Preloader: handleUINotification = " + info); 198// } 199 200 // ------------------------------------------------------------------------ 201 202 /** 203 * Marker interface for all Preloader notification. 204 */ 205 public static interface PreloaderNotification { 206 } 207 208 /** 209 * Preloader notification that reports an error. 210 * This is delivered to preloader in case of problem with applet startup. 211 */ 212 public static class ErrorNotification implements PreloaderNotification { 213 private String location; 214 private String details = ""; 215 private Throwable cause; 216 217 /** 218 * Constructs an error notification. 219 * 220 * @param location the URL associated with an error (if any); may be null 221 * @param details a string describing the error; must be non-null 222 * @param cause the cause of the error; may be null 223 */ 224 public ErrorNotification(String location, String details, Throwable cause) { 225 if (details == null) throw new NullPointerException(); 226 227 this.location = location; 228 this.details = details; 229 this.cause = cause; 230 } 231 232 /** 233 * Retrieves the URL associated with this error, if any. 234 * For example, if there is a download or singing check error, this 235 * will be the URL of the jar file that has the problem. 236 * It may be null. 237 * 238 * @return the location, or null 239 */ 240 public String getLocation() { 241 return location; 242 } 243 244 /** 245 * Retrieves the description of the error. 246 * It may be the empty string, but is always non-null. 247 * 248 * @return the description of the error 249 */ 250 public String getDetails() { 251 return details; 252 } 253 254 /** 255 * Retrieves the Exception or Error associated with this error 256 * notification, if any. It may be null. 257 * 258 * @return the cause of the error, or null 259 */ 260 public Throwable getCause() { 261 return cause; 262 } 263 264 /** 265 * Returns a string representation of this {@code ErrorNotification} object. 266 * @return a string representation of this {@code ErrorNotification} object. 267 */ 268 @Override public String toString() { 269 StringBuilder str = new StringBuilder("Preloader.ErrorNotification: "); 270 str.append(details); 271 if (cause != null) { 272 str.append(lineSeparator).append("Caused by: ").append(cause.toString()); 273 } 274 if (location != null) { 275 str.append(lineSeparator).append("Location: ").append(location); 276 } 277 return str.toString(); 278 } 279 } 280 281 /** 282 * Preloader notification that reports progress. This is typically used to 283 * report progress while downloading and initializing the application. 284 */ 285 public static class ProgressNotification implements PreloaderNotification { 286 private final double progress; 287 private final String details; 288 289 /** 290 * Constructs a progress notification. 291 * 292 * @param progress a value indicating the progress. 293 * A negative value for progress indicates that the progress is 294 * indeterminate. A value between 0 and 1 indicates the amount 295 * of progress. Any value greater than 1 is interpreted as 1. 296 */ 297 public ProgressNotification(double progress) { 298 this(progress, ""); 299 } 300 301 // NOTE: We could consider exposing details in the future, but currently 302 // have no plan to do so. This method is private for now. 303 /** 304 * Constructs a progress notification. 305 * 306 * @param progress a value indicating the progress. 307 * A negative value for progress indicates that the progress is 308 * indeterminate. A value between 0 and 1 indicates the amount 309 * of progress. Any value greater than 1 is interpreted as 1. 310 * 311 * @param details the details of this notification 312 */ 313 private ProgressNotification(double progress, String details) { 314 this.progress = progress; 315 this.details = details; 316 } 317 318 /** 319 * Retrieves the progress for this notification. Progress is in the 320 * range of 0 to 1, or is negative for indeterminate progress. 321 * 322 * @return the progress 323 */ 324 public double getProgress() { 325 return progress; 326 } 327 328 /** 329 * Retrieves the details of the progress notification 330 * 331 * @return the details of this notification 332 */ 333 private String getDetails() { 334 return details; 335 } 336 } 337 338 /** 339 * A notification that signals a change in the application state. 340 * A state change notification is sent to a preloader immediately prior 341 * to loading 342 * the application class (and constructing an instance), calling the 343 * application init method, or calling the application start method. 344 */ 345 public static class StateChangeNotification implements PreloaderNotification { 346 347 /** 348 * Enum that defines the type of change associated with this notification 349 */ 350 public enum Type { 351 /** 352 * Indicates that the application class is about to be loaded and 353 * constructed. 354 */ 355 BEFORE_LOAD, 356 357 /** 358 * Indicates that the application's init method is about to be called. 359 */ 360 BEFORE_INIT, 361 362 /** 363 * Indicates that the application's start method is about to be called. 364 */ 365 BEFORE_START 366 } 367 368 private final Type notificationType; 369 private final Application application; 370 371 /** 372 * Constructs a StateChangeNotification of the specified type. 373 * 374 * @param notificationType the type of this notification. 375 */ 376 public StateChangeNotification(Type notificationType){ 377 this.notificationType = notificationType; 378 this.application = null; 379 } 380 381 /** 382 * Constructs an StateChangeNotification of the specified type for the 383 * specified application. 384 * 385 * @param notificationType the type of this notification. 386 * @param application the application instance associated with this 387 * notification. 388 */ 389 public StateChangeNotification(Type notificationType, Application application) { 390 this.notificationType = notificationType; 391 this.application = application; 392 } 393 394 /** 395 * Returns the type of notification. 396 * 397 * @return one of: BEFORE_LOAD, BEFORE_INIT, BEFORE_START 398 */ 399 public Type getType() { 400 return notificationType; 401 } 402 403 /** 404 * Returns the Application instance associated with this notification. 405 * This is null for a BEFORE_LOAD notification and non-null for other 406 * notification types. 407 * 408 * @return the Application instance or null. 409 */ 410 public Application getApplication() { 411 return application; 412 } 413 } 414 415// /** 416// * Used to signal about global modal dialogs to be shown that block 417// * application launch. In particular proxy and security dialogs 418// */ 419// public static class UINotification implements PreloaderNotification { 420// //TODO RT-19601: implementation pending JRE work 421// } 422 423}