1 /* 2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.apple.eawt; 27 28 import java.awt.*; 29 import java.awt.peer.*; 30 import java.beans.Beans; 31 32 import javax.swing.JMenuBar; 33 34 import sun.lwawt.*; 35 import sun.lwawt.macosx.*; 36 37 /** 38 * The <code>Application</code> class allows you to integrate your Java application with the native Mac OS X environment. 39 * You can provide your Mac OS X users a greatly enhanced experience by implementing a few basic handlers for standard system events. 40 * 41 * For example: 42 * <ul> 43 * <li>Open an about dialog when a user chooses About from the application menu.</li> 44 * <li>Open a preferences window when the users chooses Preferences from the application menu.</li> 45 * <li>Create a new document when the user clicks on your Dock icon, and no windows are open.</li> 46 * <li>Open a document that the user double-clicked on in the Finder.</li> 47 * <li>Open a custom URL scheme when a user clicks on link in a web browser.</li> 48 * <li>Reconnect to network services after the system has awoke from sleep.</li> 49 * <li>Cleanly shutdown your application when the user chooses Quit from the application menu, Dock icon, or types Command-Q.</li> 50 * <li>Cancel shutdown/logout if the user has unsaved changes in your application.</li> 51 * </ul> 52 * 53 * @since 1.4 54 */ 55 public class Application { 56 private static native void nativeInitializeApplicationDelegate(); 57 58 static Application sApplication = null; 59 60 static { 61 java.security.AccessController.doPrivileged( 62 new java.security.PrivilegedAction<Void>() { 63 public Void run() { 64 System.loadLibrary("awt"); 65 return null; 66 } 67 }); 68 69 checkSecurity(); 70 if (!Beans.isDesignTime()) { 71 nativeInitializeApplicationDelegate(); 72 } 73 74 sApplication = new Application(); 75 } 76 77 private static void checkSecurity() { 78 final SecurityManager security = System.getSecurityManager(); 79 if (security == null) return; 80 security.checkPermission(new RuntimePermission("canProcessApplicationEvents")); 81 } 82 83 /** 84 * @return the singleton representing this Mac OS X Application 85 * 86 * @since 1.4 87 */ 88 public static Application getApplication() { 89 checkSecurity(); 90 return sApplication; 91 } 92 93 // some singletons, since they get called back into from native 94 final _AppEventHandler eventHandler = _AppEventHandler.getInstance(); 95 final _AppMenuBarHandler menuBarHandler = _AppMenuBarHandler.getInstance(); 96 final _AppDockIconHandler iconHandler = new _AppDockIconHandler(); 97 98 /** 99 * Creates an Application instance. Should only be used in JavaBean environments. 100 * @deprecated use {@link #getApplication()} 101 * 102 * @since 1.4 103 */ 104 @Deprecated 105 public Application() { 106 checkSecurity(); 107 } 108 109 /** 110 * Adds sub-types of {@link AppEventListener} to listen for notifications from the native Mac OS X system. 111 * 112 * @see AppForegroundListener 113 * @see AppHiddenListener 114 * @see AppReOpenedListener 115 * @see ScreenSleepListener 116 * @see SystemSleepListener 117 * @see UserSessionListener 118 * 119 * @param listener 120 * @since Java for Mac OS X 10.6 Update 3 121 * @since Java for Mac OS X 10.5 Update 8 122 */ 123 public void addAppEventListener(final AppEventListener listener) { 124 eventHandler.addListener(listener); 125 } 126 127 /** 128 * Removes sub-types of {@link AppEventListener} from listening for notifications from the native Mac OS X system. 129 * 130 * @see AppForegroundListener 131 * @see AppHiddenListener 132 * @see AppReOpenedListener 133 * @see ScreenSleepListener 134 * @see SystemSleepListener 135 * @see UserSessionListener 136 * 137 * @param listener 138 * @since Java for Mac OS X 10.6 Update 3 139 * @since Java for Mac OS X 10.5 Update 8 140 */ 141 public void removeAppEventListener(final AppEventListener listener) { 142 eventHandler.removeListener(listener); 143 } 144 145 /** 146 * Installs a handler to show a custom About window for your application. 147 * 148 * Setting the {@link AboutHandler} to <code>null</code> reverts it to the default Cocoa About window. 149 * 150 * @param aboutHandler the handler to respond to the {@link AboutHandler#handleAbout()} message 151 * @since Java for Mac OS X 10.6 Update 3 152 * @since Java for Mac OS X 10.5 Update 8 153 */ 154 public void setAboutHandler(final AboutHandler aboutHandler) { 155 eventHandler.aboutDispatcher.setHandler(aboutHandler); 156 } 157 158 /** 159 * Installs a handler to create the Preferences menu item in your application's app menu. 160 * 161 * Setting the {@link PreferencesHandler} to <code>null</code> will remove the Preferences item from the app menu. 162 * 163 * @param preferencesHandler 164 * @since Java for Mac OS X 10.6 Update 3 165 * @since Java for Mac OS X 10.5 Update 8 166 */ 167 public void setPreferencesHandler(final PreferencesHandler preferencesHandler) { 168 eventHandler.preferencesDispatcher.setHandler(preferencesHandler); 169 } 170 171 /** 172 * Installs the handler which is notified when the application is asked to open a list of files. 173 * The {@link OpenFilesHandler#openFiles(AppEvent.OpenFilesEvent)} notifications are only sent if the Java app is a bundled application, with a <code>CFBundleDocumentTypes</code> array present in it's Info.plist. 174 * See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a <code>CFBundleDocumentTypes</code> key to your app's Info.plist. 175 * 176 * @param openFileHandler 177 * @since Java for Mac OS X 10.6 Update 3 178 * @since Java for Mac OS X 10.5 Update 8 179 */ 180 public void setOpenFileHandler(final OpenFilesHandler openFileHandler) { 181 eventHandler.openFilesDispatcher.setHandler(openFileHandler); 182 } 183 184 /** 185 * Installs the handler which is notified when the application is asked to print a list of files. 186 * The {@link PrintFilesHandler#printFiles(AppEvent.PrintFilesEvent)} notifications are only sent if the Java app is a bundled application, with a <code>CFBundleDocumentTypes</code> array present in it's Info.plist. 187 * See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a <code>CFBundleDocumentTypes</code> key to your app's Info.plist. 188 * 189 * @param printFileHandler 190 * @since Java for Mac OS X 10.6 Update 3 191 * @since Java for Mac OS X 10.5 Update 8 192 */ 193 public void setPrintFileHandler(final PrintFilesHandler printFileHandler) { 194 eventHandler.printFilesDispatcher.setHandler(printFileHandler); 195 } 196 197 /** 198 * Installs the handler which is notified when the application is asked to open a URL. 199 * The {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} notifications are only sent if the Java app is a bundled application, with a <code>CFBundleURLTypes</code> array present in it's Info.plist. 200 * See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a <code>CFBundleURLTypes</code> key to your app's Info.plist. 201 * 202 * Setting the handler to <code>null</code> causes all {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} requests to be enqueued until another handler is set. 203 * 204 * @param openURIHandler 205 * @since Java for Mac OS X 10.6 Update 3 206 * @since Java for Mac OS X 10.5 Update 8 207 */ 208 public void setOpenURIHandler(final OpenURIHandler openURIHandler) { 209 eventHandler.openURIDispatcher.setHandler(openURIHandler); 210 } 211 212 /** 213 * Installs the handler which determines if the application should quit. 214 * The handler is passed a one-shot {@link QuitResponse} which can cancel or proceed with the quit. 215 * Setting the handler to <code>null</code> causes all quit requests to directly perform the default {@link QuitStrategy}. 216 * 217 * @param quitHandler the handler that is called when the application is asked to quit 218 * @since Java for Mac OS X 10.6 Update 3 219 * @since Java for Mac OS X 10.5 Update 8 220 */ 221 public void setQuitHandler(final QuitHandler quitHandler) { 222 eventHandler.quitDispatcher.setHandler(quitHandler); 223 } 224 225 /** 226 * Sets the default strategy used to quit this application. The default is calling SYSTEM_EXIT_0. 227 * 228 * The quit strategy can also be set with the "apple.eawt.quitStrategy" system property. 229 * 230 * @param strategy the way this application should be shutdown 231 * @since Java for Mac OS X 10.6 Update 3 232 * @since Java for Mac OS X 10.5 Update 8 233 */ 234 public void setQuitStrategy(final QuitStrategy strategy) { 235 eventHandler.setDefaultQuitStrategy(strategy); 236 } 237 238 /** 239 * Enables this application to be suddenly terminated. 240 * 241 * Call this method to indicate your application's state is saved, and requires no notification to be terminated. 242 * Letting your application remain terminatable improves the user experience by avoiding re-paging in your application when it's asked to quit. 243 * 244 * <b>Note: enabling sudden termination will allow your application to be quit without notifying your QuitHandler, or running any shutdown hooks.</b> 245 * User initiated Cmd-Q, logout, restart, or shutdown requests will effectively "kill -KILL" your application. 246 * 247 * This call has no effect on Mac OS X versions prior to 10.6. 248 * 249 * @see <a href="http://developer.apple.com/mac/library/documentation/cocoa/reference/foundation/Classes/NSProcessInfo_Class">NSProcessInfo class references</a> for more information about Sudden Termination. 250 * @see Application#disableSuddenTermination() 251 * 252 * @since Java for Mac OS X 10.6 Update 3 253 * @since Java for Mac OS X 10.5 Update 8 254 */ 255 public void enableSuddenTermination() { 256 _AppMiscHandlers.enableSuddenTermination(); 257 } 258 259 /** 260 * Prevents this application from being suddenly terminated. 261 * 262 * Call this method to indicate that your application has unsaved state, and may not be terminated without notification. 263 * 264 * This call has no effect on Mac OS X versions prior to 10.6. 265 * 266 * @see <a href="http://developer.apple.com/mac/library/documentation/cocoa/reference/foundation/Classes/NSProcessInfo_Class">NSProcessInfo class references</a> for more information about Sudden Termination. 267 * @see Application#enableSuddenTermination() 268 * 269 * @since Java for Mac OS X 10.6 Update 3 270 * @since Java for Mac OS X 10.5 Update 8 271 */ 272 public void disableSuddenTermination() { 273 _AppMiscHandlers.disableSuddenTermination(); 274 } 275 276 /** 277 * Requests this application to move to the foreground. 278 * 279 * @param allWindows if all windows of this application should be moved to the foreground, or only the foremost one 280 * 281 * @since Java for Mac OS X 10.6 Update 1 282 * @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5 283 */ 284 public void requestForeground(final boolean allWindows) { 285 _AppMiscHandlers.requestActivation(allWindows); 286 } 287 288 /** 289 * Requests user attention to this application (usually through bouncing the Dock icon). Critical 290 * requests will continue to bounce the Dock icon until the app is activated. An already active 291 * application requesting attention does nothing. 292 * 293 * @param critical if this is an important request 294 * 295 * @since Java for Mac OS X 10.6 Update 1 296 * @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5 297 */ 298 public void requestUserAttention(final boolean critical) { 299 _AppMiscHandlers.requestUserAttention(critical); 300 } 301 302 /** 303 * Opens the native help viewer application if a Help Book has been added to the 304 * application bundler and registered in the Info.plist with CFBundleHelpBookFolder. 305 * 306 * See http://developer.apple.com/qa/qa2001/qa1022.html for more information. 307 * 308 * @since Java for Mac OS X 10.5 - 1.5 309 * @since Java for Mac OS X 10.5 Update 1 - 1.6 310 */ 311 public void openHelpViewer() { 312 _AppMiscHandlers.openHelpViewer(); 313 } 314 315 /** 316 * Attaches the contents of the provided PopupMenu to the application's Dock icon. 317 * 318 * @param menu the PopupMenu to attach to this application's Dock icon 319 * 320 * @since Java for Mac OS X 10.5 - 1.5 321 * @since Java for Mac OS X 10.5 Update 1 - 1.6 322 */ 323 public void setDockMenu(final PopupMenu menu) { 324 iconHandler.setDockMenu(menu); 325 } 326 327 /** 328 * @return the PopupMenu used to add items to this application's Dock icon 329 * 330 * @since Java for Mac OS X 10.5 - 1.5 331 * @since Java for Mac OS X 10.5 Update 1 - 1.6 332 */ 333 public PopupMenu getDockMenu() { 334 return iconHandler.getDockMenu(); 335 } 336 337 /** 338 * Changes this application's Dock icon to the provided image. 339 * 340 * @param image 341 * 342 * @since Java for Mac OS X 10.5 - 1.5 343 * @since Java for Mac OS X 10.5 Update 1 - 1.6 344 */ 345 public void setDockIconImage(final Image image) { 346 iconHandler.setDockIconImage(image); 347 } 348 349 /** 350 * Obtains an image of this application's Dock icon. 351 * 352 * @return an image of this application's Dock icon 353 * 354 * @since Java for Mac OS X 10.5 - 1.5 355 * @since Java for Mac OS X 10.5 Update 1 - 1.6 356 */ 357 public Image getDockIconImage() { 358 return iconHandler.getDockIconImage(); 359 } 360 361 /** 362 * Affixes a small system provided badge to this application's Dock icon. Usually a number. 363 * 364 * @param badge textual label to affix to the Dock icon 365 * 366 * @since Java for Mac OS X 10.5 - 1.5 367 * @since Java for Mac OS X 10.5 Update 1 - 1.6 368 */ 369 public void setDockIconBadge(final String badge) { 370 iconHandler.setDockIconBadge(badge); 371 } 372 373 /** 374 * Sets the default menu bar to use when there are no active frames. 375 * Only used when the system property "apple.laf.useScreenMenuBar" is "true", and 376 * the Aqua Look and Feel is active. 377 * 378 * @param menuBar to use when no other frames are active 379 * 380 * @since Java for Mac OS X 10.6 Update 1 381 * @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5 382 */ 383 public void setDefaultMenuBar(final JMenuBar menuBar) { 384 menuBarHandler.setDefaultMenuBar(menuBar); 385 } 386 387 /** 388 * Requests that a {@link Window} should animate into or out of full screen mode. 389 * Only {@link Window}s marked as full screenable by {@link FullScreenUtilities#setWindowCanFullScreen(Window, boolean)} can be toggled. 390 * 391 * @param window to animate into or out of full screen mode 392 * 393 * @since Java for Mac OS X 10.7 Update 1 394 */ 395 @SuppressWarnings("deprecation") 396 public void requestToggleFullScreen(final Window window) { 397 final ComponentPeer peer = window.getPeer(); 398 399 if (!(peer instanceof LWWindowPeer)) return; 400 Object platformWindow = ((LWWindowPeer) peer).getPlatformWindow(); 401 if (!(platformWindow instanceof CPlatformWindow)) return; 402 ((CPlatformWindow)platformWindow).toggleFullScreen(); 403 } 404 405 406 // -- DEPRECATED API -- 407 408 /** 409 * Adds the specified ApplicationListener as a receiver of callbacks from this class. 410 * This method throws a RuntimeException if the newer About, Preferences, Quit, etc handlers are installed. 411 * 412 * @param listener an implementation of ApplicationListener that handles ApplicationEvents 413 * 414 * @deprecated register individual handlers for each task (About, Preferences, Open, Print, Quit, etc) 415 * @since 1.4 416 */ 417 @SuppressWarnings("deprecation") 418 @Deprecated 419 public void addApplicationListener(final ApplicationListener listener) { 420 eventHandler.legacyHandler.addLegacyAppListener(listener); 421 } 422 423 /** 424 * Removes the specified ApplicationListener from being a receiver of callbacks from this class. 425 * This method throws a RuntimeException if the newer About, Preferences, Quit, etc handlers are installed. 426 * 427 * @param listener an implementation of ApplicationListener that had previously been registered to handle ApplicationEvents 428 * 429 * @deprecated unregister individual handlers for each task (About, Preferences, Open, Print, Quit, etc) 430 * @since 1.4 431 */ 432 @SuppressWarnings("deprecation") 433 @Deprecated 434 public void removeApplicationListener(final ApplicationListener listener) { 435 eventHandler.legacyHandler.removeLegacyAppListener(listener); 436 } 437 438 /** 439 * Enables the Preferences item in the application menu. The ApplicationListener receives a callback for 440 * selection of the Preferences item in the application menu only if this is set to <code>true</code>. 441 * 442 * If a Preferences item isn't present, this method adds and enables it. 443 * 444 * @param enable specifies whether the Preferences item in the application menu should be enabled (<code>true</code>) or not (<code>false</code>) 445 * 446 * @deprecated no replacement 447 * @since 1.4 448 */ 449 @Deprecated 450 public void setEnabledPreferencesMenu(final boolean enable) { 451 menuBarHandler.setPreferencesMenuItemVisible(true); 452 menuBarHandler.setPreferencesMenuItemEnabled(enable); 453 } 454 455 /** 456 * Enables the About item in the application menu. The ApplicationListener receives a callback for 457 * selection of the About item in the application menu only if this is set to <code>true</code>. Because AWT supplies 458 * a standard About window when an application may not, by default this is set to <code>true</code>. 459 * 460 * If the About item isn't present, this method adds and enables it. 461 * 462 * @param enable specifies whether the About item in the application menu should be enabled (<code>true</code>) or not (<code>false</code>) 463 * 464 * @deprecated no replacement 465 * @since 1.4 466 */ 467 @Deprecated 468 public void setEnabledAboutMenu(final boolean enable) { 469 menuBarHandler.setAboutMenuItemEnabled(enable); 470 } 471 472 /** 473 * Determines if the Preferences item of the application menu is enabled. 474 * 475 * @deprecated no replacement 476 * @since 1.4 477 */ 478 @Deprecated 479 public boolean getEnabledPreferencesMenu() { 480 return menuBarHandler.isPreferencesMenuItemEnabled(); 481 } 482 483 /** 484 * Determines if the About item of the application menu is enabled. 485 * 486 * @deprecated no replacement 487 * @since 1.4 488 */ 489 @Deprecated 490 public boolean getEnabledAboutMenu() { 491 return menuBarHandler.isAboutMenuItemEnabled(); 492 } 493 494 /** 495 * Determines if the About item of the application menu is present. 496 * 497 * @deprecated no replacement 498 * @since 1.4 499 */ 500 @Deprecated 501 public boolean isAboutMenuItemPresent() { 502 return menuBarHandler.isAboutMenuItemVisible(); 503 } 504 505 /** 506 * Adds the About item to the application menu if the item is not already present. 507 * 508 * @deprecated use {@link #setAboutHandler(AboutHandler)} with a non-null {@link AboutHandler} parameter 509 * @since 1.4 510 */ 511 @Deprecated 512 public void addAboutMenuItem() { 513 menuBarHandler.setAboutMenuItemVisible(true); 514 } 515 516 /** 517 * Removes the About item from the application menu if the item is present. 518 * 519 * @deprecated use {@link #setAboutHandler(AboutHandler)} with a null parameter 520 * @since 1.4 521 */ 522 @Deprecated 523 public void removeAboutMenuItem() { 524 menuBarHandler.setAboutMenuItemVisible(false); 525 } 526 527 /** 528 * Determines if the About Preferences of the application menu is present. By default there is no Preferences menu item. 529 * 530 * @deprecated no replacement 531 * @since 1.4 532 */ 533 @Deprecated 534 public boolean isPreferencesMenuItemPresent() { 535 return menuBarHandler.isPreferencesMenuItemVisible(); 536 } 537 538 /** 539 * Adds the Preferences item to the application menu if the item is not already present. 540 * 541 * @deprecated use {@link #setPreferencesHandler(PreferencesHandler)} with a non-null {@link PreferencesHandler} parameter 542 * @since 1.4 543 */ 544 @Deprecated 545 public void addPreferencesMenuItem() { 546 menuBarHandler.setPreferencesMenuItemVisible(true); 547 } 548 549 /** 550 * Removes the Preferences item from the application menu if that item is present. 551 * 552 * @deprecated use {@link #setPreferencesHandler(PreferencesHandler)} with a null parameter 553 * @since 1.4 554 */ 555 @Deprecated 556 public void removePreferencesMenuItem() { 557 menuBarHandler.setPreferencesMenuItemVisible(false); 558 } 559 560 /** 561 * @deprecated Use <code>java.awt.MouseInfo.getPointerInfo().getLocation()</code>. 562 * 563 * @since 1.4 564 */ 565 @Deprecated 566 public static Point getMouseLocationOnScreen() { 567 return java.awt.MouseInfo.getPointerInfo().getLocation(); 568 } 569 }