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.PopupMenu; 30 import java.awt.Toolkit; 31 import java.awt.Window; 32 import java.awt.desktop.*; 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 SystemEventListener} to listen for notifications from the native Mac OS X system. 108 * 109 * @see AppForegroundListener 110 * @see AppHiddenListener 111 * @see AppReOpenedListener 112 * @see AppScreenSleepListener 113 * @see AppSystemSleepListener 114 * @see AppUserSessionListener 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 SystemEventListener listener) { 121 eventHandler.addListener(listener); 122 } 123 124 /** 125 * Removes sub-types of {@link SystemEventListener} from listening for notifications from the native Mac OS X system. 126 * 127 * @see AppForegroundListener 128 * @see AppHiddenListener 129 * @see AppReOpenedListener 130 * @see AppScreenSleepListener 131 * @see AppSystemSleepListener 132 * @see AppUserSessionListener 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 SystemEventListener 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 * Displays a progress bar to this application's Dock icon. 372 * Acceptable values are from 0 to 100, any other disables progress indication. 373 * 374 * @param value progress value 375 * @since 1.9 376 */ 377 public void setDockIconProgress(final int value) { 378 iconHandler.setDockIconProgress(value); 379 } 380 381 /** 382 * Sets the default menu bar to use when there are no active frames. 383 * Only used when the system property "apple.laf.useScreenMenuBar" is "true", and 384 * the Aqua Look and Feel is active. 385 * 386 * @param menuBar to use when no other frames are active 387 * 388 * @since Java for Mac OS X 10.6 Update 1 389 * @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5 390 */ 391 public void setDefaultMenuBar(final JMenuBar menuBar) { 392 menuBarHandler.setDefaultMenuBar(menuBar); 393 } 394 395 /** 396 * Requests that a {@link Window} should animate into or out of full screen mode. 397 * Only {@link Window}s marked as full screenable by {@link FullScreenUtilities#setWindowCanFullScreen(Window, boolean)} can be toggled. 398 * 399 * @param window to animate into or out of full screen mode 400 * 401 * @since Java for Mac OS X 10.7 Update 1 402 */ 403 public void requestToggleFullScreen(final Window window) { 404 final Object peer = AWTAccessor.getComponentAccessor().getPeer(window); 405 if (!(peer instanceof LWWindowPeer)) return; 406 Object platformWindow = ((LWWindowPeer) peer).getPlatformWindow(); 407 if (!(platformWindow instanceof CPlatformWindow)) return; 408 ((CPlatformWindow)platformWindow).toggleFullScreen(); 409 } 410 411 }