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