Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2010, 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; 030import java.util.List; 031import java.util.Map; 032 033import javafx.application.Preloader.PreloaderNotification; 034import javafx.scene.Scene; 035import javafx.stage.Stage; 036 037import com.sun.javafx.application.LauncherImpl; 038import com.sun.javafx.application.ParametersImpl; 039import com.sun.javafx.application.PlatformImpl; 040import com.sun.javafx.css.StyleManager; 041 042/** 043 * Application class from which JavaFX applications extend. 044 * 045 * <p><b>Life-cycle</b></p> 046 * <p> 047 * The entry point for JavaFX applications is the Application class. The 048 * JavaFX runtime does the following, in order, whenever an application is 049 * launched: 050 * </p> 051 * <ol> 052 * <li>Constructs an instance of the specified Application class</li> 053 * <li>Calls the {@link #init} method</li> 054 * <li>Calls the {@link #start} method</li> 055 * <li>Waits for the application to finish, which happens when either of 056 * the following occur: 057 * <ul> 058 * <li>the application calls {@link Platform#exit}</li> 059 * <li>the last window has been closed and the {@code implicitExit} 060 * attribute on {@code Platform} is true</li> 061 * </ul></li> 062 * <li>Calls the {@link #stop} method</li> 063 * </ol> 064 * <p>Note that the {@code start} method is abstract and must be overridden. 065 * The {@code init} and {@code stop} methods have concrete implementations 066 * that do nothing.</p> 067 * 068 * <p><b>Parameters</b></p> 069 * <p> 070 * Application parameters are available by calling the {@link #getParameters} 071 * method from the {@link #init} method, or any time after the {@code init} 072 * method has been called. 073 * </p> 074 * 075 * <p><b>Threading</b></p> 076 * <p> 077 * JavaFX creates an application thread for running the application start 078 * method, processing input events, and running animation timelines. Creation 079 * of JavaFX {@link Scene} and {@link Stage} objects as well as modification of 080 * scene graph operations to <em>live</em> objects (those objects already 081 * attached to a scene) must be done on the JavaFX application thread. 082 * </p> 083 * 084 * <p> 085 * The Application constructor and {@code init} method are called on 086 * the launcher thread, not on the JavaFX Application Thread. 087 * This means that an application must not construct a {@link Scene} 088 * or a {@link Stage} in either the constructor or in the {@code init} 089 * method. 090 * An application may construct other JavaFX objects in the {@code init} 091 * method. 092 * </p> 093 * 094 * <p> 095 * All the unhandled exceptions on the JavaFX application thread that occur during 096 * event dispatching, running animation timelines, or any other code, are forwarded 097 * to the thread's {@link java.lang.Thread.UncaughtExceptionHandler uncaught 098 * exception handler}. 099 * </p> 100 * 101 * <p><b>Example</b></p> 102 * <p>The following example will illustrate a simple JavaFX application.</p> 103 * <pre><code> 104import javafx.application.Application; 105import javafx.scene.Group; 106import javafx.scene.Scene; 107import javafx.scene.shape.Circle; 108import javafx.stage.Stage; 109 110public class MyApp extends Application { 111 public void start(Stage stage) { 112 Circle circ = new Circle(40, 40, 30); 113 Group root = new Group(circ); 114 Scene scene = new Scene(root, 400, 300); 115 116 stage.setTitle("My JavaFX Application"); 117 stage.setScene(scene); 118 stage.show(); 119 } 120} 121 * </code></pre> 122 * 123 * <p>The above example will produce the following:</p> 124 * <p><img src="doc-files/Application.png"/></p> 125 */ 126public abstract class Application { 127 /** 128 * Constant for user agent stylesheet for the "Caspian" theme. Caspian 129 * is the theme that shipped as default in JavaFX 2.x. 130 */ 131 public static final String STYLESHEET_CASPIAN = "CASPIAN"; 132 /** 133 * Constant for user agent stylesheet for the "Modena" theme. Modena 134 * is the default theme for JavaFX 8.x. 135 */ 136 public static final String STYLESHEET_MODENA = "MODENA"; 137 138 /** 139 * Launch a standalone application. This method is typically called 140 * from the main method(). It must not be called more than once or an 141 * exception will be thrown. 142 * 143 * <p> 144 * The launch method does not return until the application has exited, 145 * either via a call to Platform.exit or all of the application windows 146 * have been closed. 147 * 148 * <p> 149 * Typical usage is: 150 * <ul> 151 * <pre> 152 * public static void main(String[] args) { 153 * Application.launch(MyApp.class, args); 154 * } 155 * </pre> 156 * </ul> 157 * where <code>MyApp</code> is a subclass of Application. 158 * 159 * @param appClass the application class that is constructed and executed 160 * by the launcher. 161 * @param args the command line arguments passed to the application. 162 * An application may get these parameters using the 163 * {@link #getParameters()} method. 164 * 165 * @throws IllegalStateException if this method is called more than once. 166 * @throws IllegalArgumentException if <code>appClass</code> is not a 167 * subclass of <code>Application</code>. 168 */ 169 public static void launch(Class<? extends Application> appClass, String... args) { 170 LauncherImpl.launchApplication(appClass, args); 171 } 172 173 /** 174 * Launch a standalone application. This method is typically called 175 * from the main method(). It must not be called more than once or an 176 * exception will be thrown. 177 * This is equivalent to launch(TheClass.class, args) where TheClass is the 178 * immediately enclosing class of the method that called launch. It must 179 * be a subclass of Application or a RuntimeException will be thrown. 180 * 181 * <p> 182 * The launch method does not return until the application has exited, 183 * either via a call to Platform.exit or all of the application windows 184 * have been closed. 185 * 186 * <p> 187 * Typical usage is: 188 * <ul> 189 * <pre> 190 * public static void main(String[] args) { 191 * Application.launch(args); 192 * } 193 * </pre> 194 * </ul> 195 * 196 * @param args the command line arguments passed to the application. 197 * An application may get these parameters using the 198 * {@link #getParameters()} method. 199 * 200 * @throws IllegalStateException if this method is called more than once. 201 */ 202 public static void launch(String... args) { 203 // Figure out the right class to call 204 StackTraceElement[] cause = Thread.currentThread().getStackTrace(); 205 206 boolean foundThisMethod = false; 207 String callingClassName = null; 208 for (StackTraceElement se : cause) { 209 // Skip entries until we get to the entry for this class 210 String className = se.getClassName(); 211 String methodName = se.getMethodName(); 212 if (foundThisMethod) { 213 callingClassName = className; 214 break; 215 } else if (Application.class.getName().equals(className) 216 && "launch".equals(methodName)) { 217 218 foundThisMethod = true; 219 } 220 } 221 222 if (callingClassName == null) { 223 throw new RuntimeException("Error: unable to determine Application class"); 224 } 225 226 try { 227 Class theClass = Class.forName(callingClassName, true, 228 Thread.currentThread().getContextClassLoader()); 229 if (Application.class.isAssignableFrom(theClass)) { 230 Class<? extends Application> appClass = theClass; 231 LauncherImpl.launchApplication(appClass, args); 232 } else { 233 throw new RuntimeException("Error: " + theClass 234 + " is not a subclass of javafx.application.Application"); 235 } 236 } catch (RuntimeException ex) { 237 throw ex; 238 } catch (Exception ex) { 239 throw new RuntimeException(ex); 240 } 241 } 242 243 /** 244 * The application initialization method. This method is called immediately 245 * after the Application class is loaded and constructed. An application may 246 * override this method to perform initialization prior to the actual starting 247 * of the application. 248 * 249 * <p> 250 * The implementation of this method provided by the Application class does nothing. 251 * </p> 252 * 253 * <p> 254 * NOTE: This method is not called on the JavaFX Application Thread. An 255 * application must not construct a Scene or a Stage in this 256 * method. 257 * An application may construct other JavaFX objects in this method. 258 * </p> 259 */ 260 public void init() throws Exception { 261 } 262 263 /** 264 * The main entry point for all JavaFX applications. 265 * The start method is called after the init method has returned, 266 * and after the system is ready for the application to begin running. 267 * 268 * <p> 269 * NOTE: This method is called on the JavaFX Application Thread. 270 * </p> 271 * 272 * @param primaryStage the primary stage for this application, onto which 273 * the application scene can be set. The primary stage will be embedded in 274 * the browser if the application was launched as an applet. 275 * Applications may create other stages, if needed, but they will not be 276 * primary stages and will not be embedded in the browser. 277 */ 278 public abstract void start(Stage primaryStage) throws Exception; 279 280 /** 281 * This method is called when the application should stop, and provides a 282 * convenient place to prepare for application exit and destroy resources. 283 * 284 * <p> 285 * The implementation of this method provided by the Application class does nothing. 286 * </p> 287 * 288 * <p> 289 * NOTE: This method is called on the JavaFX Application Thread. 290 * </p> 291 */ 292 public void stop() throws Exception { 293 } 294 295 private HostServices hostServices = null; 296 297 /** 298 * Gets the HostServices provider for this application. This provides 299 * the ability to get the code base and document base for this application, 300 * and to access the enclosing web page. 301 * 302 * @return the HostServices provider 303 */ 304 public final HostServices getHostServices() { 305 synchronized (this) { 306 if (hostServices == null) { 307 hostServices = new HostServices(this); 308 } 309 return hostServices; 310 } 311 } 312 313 /** 314 * Retrieves the parameters for this Application, including any arguments 315 * passed on the command line and any parameters specified in a JNLP file 316 * for an applet or WebStart application. 317 * 318 * <p> 319 * NOTE: this method should not be called from the Application constructor, 320 * as it will return null. It may be called in the init() method or any 321 * time after that. 322 * </p> 323 * 324 * @return the parameters for this Application, or null if called from the 325 * constructor. 326 */ 327 public final Parameters getParameters() { 328 return ParametersImpl.getParameters(this); 329 } 330 331 /** 332 * Notifies the preloader with an application-generated notification. 333 * Application code calls this method with a PreloaderNotification that is 334 * delivered to the preloader's handleApplicationNotification() method. 335 * This is primarily useful for cases where an application wants the 336 * preloader to show progress during a long application initialization 337 * step. 338 * 339 * @param info the application-generated preloader notification 340 */ 341 public final void notifyPreloader(PreloaderNotification info) { 342 LauncherImpl.notifyPreloader(this, info); 343 } 344 345 /** 346 * Encapsulates the set of parameters for an application. This includes 347 * arguments passed on the command line, unnamed parameters specified 348 * in a JNLP file, and <name,value> pairs specified in a JNLP file. 349 * 350 * <p> 351 * Note that the application and the preloader both get the same set 352 * of parameters for a given run of an application. 353 * </p> 354 */ 355 public static abstract class Parameters { 356 357 /** 358 * Retrieves a read-only list of the raw arguments. This list 359 * may be empty, but is never null. In the case of a standalone 360 * application, it is the ordered list of arguments specified on the 361 * command line. In the case of an applet or WebStart application, 362 * it includes unnamed parameters as well as named parameters. For 363 * named parameters, each <name,value> pair is represented as 364 * a single argument of the form: "--name=value". 365 * 366 * @return a read-only list of raw application arguments 367 */ 368 public abstract List<String> getRaw(); 369 370 /** 371 * Retrieves a read-only list of the unnamed parameters. This list 372 * may be empty, but is never null. The named parameters, that is 373 * the parameters that are represented as <name,value> pairs, are 374 * filtered out. 375 * 376 * @return a read-only list of unnamed parameters. 377 */ 378 public abstract List<String> getUnnamed(); 379 380 /** 381 * Retrieves a read-only map of the named parameters. It may be 382 * empty, but is never null. 383 * Named parameters include those <name,value> pairs explicitly 384 * specified in a JNLP file. It also includes any command line 385 * arguments of the form: "--name=value". 386 * 387 * @return a read-only map of named parameters. 388 */ 389 public abstract Map<String, String> getNamed(); 390 391 } 392 393 private static String userAgentStylesheet = null; 394 395 /** 396 * Get the user agent stylesheet used by the whole application. This is 397 * used to provide default styling for all ui controls and other nodes. 398 * A value of null means the platform default stylesheet is being used. 399 * <p> 400 * NOTE: This method must be called on the JavaFX Application Thread. 401 * </p> 402 * 403 * @return The URL to the stylesheet as a String. 404 */ 405 public static String getUserAgentStylesheet() { 406 return userAgentStylesheet; 407 } 408 409 /** 410 * Set the user agent stylesheet used by the whole application. This is used 411 * to provide default styling for all ui controls and other nodes. Each 412 * release of JavaFX may have a new default value for this so if you need 413 * to guarantee consistency you will need to call this method and choose 414 * what default you would like for your application. A value of null will 415 * restore the platform default stylesheet. This property can also be set 416 * on the command line with {@code -Djavafx.userAgentStylesheetUrl=[URL]} 417 * Setting it on the command line overrides anything set using this method 418 * in code. 419 * <p> 420 * NOTE: This method must be called on the JavaFX Application Thread. 421 * </p> 422 * 423 * 424 * @param url The URL to the stylesheet as a String. 425 */ 426 public static void setUserAgentStylesheet(String url) { 427 userAgentStylesheet = url; 428 if (url == null) { 429 PlatformImpl.setDefaultPlatformUserAgentStylesheet(); 430 } else { 431 PlatformImpl.setPlatformUserAgentStylesheet(url); 432 } 433 } 434}