1 /* 2 * Copyright (c) 2011, 2017, 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.AboutHandler; 33 import java.awt.desktop.AppForegroundListener; 34 import java.awt.desktop.AppHiddenListener; 35 import java.awt.desktop.AppReopenedListener; 36 import java.awt.desktop.OpenFilesEvent; 37 import java.awt.desktop.OpenFilesHandler; 38 import java.awt.desktop.OpenURIEvent; 39 import java.awt.desktop.OpenURIHandler; 40 import java.awt.desktop.PreferencesHandler; 41 import java.awt.desktop.PrintFilesEvent; 42 import java.awt.desktop.PrintFilesHandler; 43 import java.awt.desktop.QuitHandler; 44 import java.awt.desktop.QuitResponse; 45 import java.awt.desktop.QuitStrategy; 46 import java.awt.desktop.ScreenSleepListener; 47 import java.awt.desktop.SystemEventListener; 48 import java.awt.desktop.SystemSleepListener; 49 import java.awt.desktop.UserSessionListener; 50 import java.beans.Beans; 51 52 import javax.swing.JMenuBar; 53 54 import sun.awt.AWTAccessor; 55 import sun.lwawt.LWWindowPeer; 56 import sun.lwawt.macosx.CPlatformWindow; 57 58 /** 59 * The {@code Application} class allows you to integrate your Java application with the native Mac OS X environment. 60 * You can provide your Mac OS X users a greatly enhanced experience by implementing a few basic handlers for standard system events. 61 * 62 * For example: 63 * <ul> 64 * <li>Open an about dialog when a user chooses About from the application menu.</li> 65 * <li>Open a preferences window when the users chooses Preferences from the application menu.</li> 66 * <li>Create a new document when the user clicks on your Dock icon, and no windows are open.</li> 67 * <li>Open a document that the user double-clicked on in the Finder.</li> 68 * <li>Open a custom URL scheme when a user clicks on link in a web browser.</li> 69 * <li>Reconnect to network services after the system has awoke from sleep.</li> 70 * <li>Cleanly shutdown your application when the user chooses Quit from the application menu, Dock icon, or types Command-Q.</li> 71 * <li>Cancel shutdown/logout if the user has unsaved changes in your application.</li> 72 * </ul> 73 * 74 * @since 1.4 75 */ 76 public class Application { nativeInitializeApplicationDelegate()77 private static native void nativeInitializeApplicationDelegate(); 78 79 static Application sApplication = null; 80 81 static { checkSecurity()82 checkSecurity(); Toolkit.getDefaultToolkit()83 Toolkit.getDefaultToolkit(); // Start AppKit 84 if (!Beans.isDesignTime()) { nativeInitializeApplicationDelegate()85 nativeInitializeApplicationDelegate(); 86 } 87 88 sApplication = new Application(); 89 } 90 checkSecurity()91 private static void checkSecurity() { 92 final SecurityManager security = System.getSecurityManager(); 93 if (security == null) return; 94 security.checkPermission(new RuntimePermission("canProcessApplicationEvents")); 95 } 96 97 /** 98 * @return the singleton representing this Mac OS X Application 99 * 100 * @since 1.4 101 */ getApplication()102 public static Application getApplication() { 103 checkSecurity(); 104 return sApplication; 105 } 106 107 // some singletons, since they get called back into from native 108 final _AppEventHandler eventHandler = _AppEventHandler.getInstance(); 109 final _AppMenuBarHandler menuBarHandler = _AppMenuBarHandler.getInstance(); 110 final _AppDockIconHandler iconHandler = new _AppDockIconHandler(); 111 112 /** 113 * Creates an Application instance. Should only be used in JavaBean environments. 114 * @deprecated use {@link #getApplication()} 115 * 116 * @since 1.4 117 */ 118 @Deprecated Application()119 public Application() { 120 checkSecurity(); 121 } 122 123 /** 124 * Adds sub-types of {@link SystemEventListener} to listen for notifications from the native Mac OS X system. 125 * 126 * @see AppForegroundListener 127 * @see AppHiddenListener 128 * @see AppReopenedListener 129 * @see ScreenSleepListener 130 * @see SystemSleepListener 131 * @see UserSessionListener 132 * 133 * @param listener 134 * @since Java for Mac OS X 10.6 Update 3 135 * @since Java for Mac OS X 10.5 Update 8 136 */ addAppEventListener(final SystemEventListener listener)137 public void addAppEventListener(final SystemEventListener listener) { 138 eventHandler.addListener(listener); 139 } 140 141 /** 142 * Removes sub-types of {@link SystemEventListener} from listening for notifications from the native Mac OS X system. 143 * 144 * @see AppForegroundListener 145 * @see AppHiddenListener 146 * @see AppReopenedListener 147 * @see ScreenSleepListener 148 * @see SystemSleepListener 149 * @see UserSessionListener 150 * 151 * @param listener 152 * @since Java for Mac OS X 10.6 Update 3 153 * @since Java for Mac OS X 10.5 Update 8 154 */ removeAppEventListener(final SystemEventListener listener)155 public void removeAppEventListener(final SystemEventListener listener) { 156 eventHandler.removeListener(listener); 157 } 158 159 /** 160 * Installs a handler to show a custom About window for your application. 161 * 162 * Setting the {@link AboutHandler} to {@code null} reverts it to the default Cocoa About window. 163 * 164 * @param aboutHandler the handler to respond to the {@link AboutHandler#handleAbout} message 165 * @since Java for Mac OS X 10.6 Update 3 166 * @since Java for Mac OS X 10.5 Update 8 167 */ setAboutHandler(final AboutHandler aboutHandler)168 public void setAboutHandler(final AboutHandler aboutHandler) { 169 eventHandler.aboutDispatcher.setHandler(aboutHandler); 170 } 171 172 /** 173 * Installs a handler to create the Preferences menu item in your application's app menu. 174 * 175 * Setting the {@link PreferencesHandler} to {@code null} will remove the Preferences item from the app menu. 176 * 177 * @param preferencesHandler 178 * @since Java for Mac OS X 10.6 Update 3 179 * @since Java for Mac OS X 10.5 Update 8 180 */ setPreferencesHandler(final PreferencesHandler preferencesHandler)181 public void setPreferencesHandler(final PreferencesHandler preferencesHandler) { 182 eventHandler.preferencesDispatcher.setHandler(preferencesHandler); 183 } 184 185 /** 186 * Installs the handler which is notified when the application is asked to open a list of files. 187 * The {@link OpenFilesHandler#openFiles(OpenFilesEvent)} notifications are only sent if the Java app is a bundled application, with a {@code CFBundleDocumentTypes} array present in it's Info.plist. 188 * 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} key to your app's Info.plist. 189 * 190 * @param openFileHandler 191 * @since Java for Mac OS X 10.6 Update 3 192 * @since Java for Mac OS X 10.5 Update 8 193 */ setOpenFileHandler(final OpenFilesHandler openFileHandler)194 public void setOpenFileHandler(final OpenFilesHandler openFileHandler) { 195 eventHandler.openFilesDispatcher.setHandler(openFileHandler); 196 } 197 198 /** 199 * Installs the handler which is notified when the application is asked to print a list of files. 200 * The {@link PrintFilesHandler#printFiles(PrintFilesEvent)} notifications are only sent if the Java app is a bundled application, with a {@code CFBundleDocumentTypes} array present in it's Info.plist. 201 * 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} key to your app's Info.plist. 202 * 203 * @param printFileHandler 204 * @since Java for Mac OS X 10.6 Update 3 205 * @since Java for Mac OS X 10.5 Update 8 206 */ setPrintFileHandler(final PrintFilesHandler printFileHandler)207 public void setPrintFileHandler(final PrintFilesHandler printFileHandler) { 208 eventHandler.printFilesDispatcher.setHandler(printFileHandler); 209 } 210 211 /** 212 * Installs the handler which is notified when the application is asked to open a URL. 213 * The {@link OpenURIHandler#openURI(OpenURIEvent)} notifications are only sent if the Java app is a bundled application, with a {@code CFBundleURLTypes} array present in it's Info.plist. 214 * 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} key to your app's Info.plist. 215 * 216 * Setting the handler to {@code null} causes all {@link OpenURIHandler#openURI(OpenURIEvent)} requests to be enqueued until another handler is set. 217 * 218 * @param openURIHandler 219 * @since Java for Mac OS X 10.6 Update 3 220 * @since Java for Mac OS X 10.5 Update 8 221 */ setOpenURIHandler(final OpenURIHandler openURIHandler)222 public void setOpenURIHandler(final OpenURIHandler openURIHandler) { 223 eventHandler.openURIDispatcher.setHandler(openURIHandler); 224 } 225 226 /** 227 * Installs the handler which determines if the application should quit. 228 * The handler is passed a one-shot {@link QuitResponse} which can cancel or proceed with the quit. 229 * Setting the handler to {@code null} causes all quit requests to directly perform the default {@link QuitStrategy}. 230 * 231 * @param quitHandler the handler that is called when the application is asked to quit 232 * @since Java for Mac OS X 10.6 Update 3 233 * @since Java for Mac OS X 10.5 Update 8 234 */ setQuitHandler(final QuitHandler quitHandler)235 public void setQuitHandler(final QuitHandler quitHandler) { 236 eventHandler.quitDispatcher.setHandler(quitHandler); 237 } 238 239 /** 240 * Sets the default strategy used to quit this application. The default is calling SYSTEM_EXIT_0. 241 * 242 * The quit strategy can also be set with the "apple.eawt.quitStrategy" system property. 243 * 244 * @param strategy the way this application should be shutdown 245 * @since Java for Mac OS X 10.6 Update 3 246 * @since Java for Mac OS X 10.5 Update 8 247 */ setQuitStrategy(final QuitStrategy strategy)248 public void setQuitStrategy(final QuitStrategy strategy) { 249 eventHandler.setDefaultQuitStrategy(strategy); 250 } 251 252 /** 253 * Enables this application to be suddenly terminated. 254 * 255 * Call this method to indicate your application's state is saved, and requires no notification to be terminated. 256 * Letting your application remain terminatable improves the user experience by avoiding re-paging in your application when it's asked to quit. 257 * 258 * <b>Note: enabling sudden termination will allow your application to be quit without notifying your QuitHandler, or running any shutdown hooks.</b> 259 * User initiated Cmd-Q, logout, restart, or shutdown requests will effectively "kill -KILL" your application. 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#disableSuddenTermination() 265 * 266 * @since Java for Mac OS X 10.6 Update 3 267 * @since Java for Mac OS X 10.5 Update 8 268 */ enableSuddenTermination()269 public void enableSuddenTermination() { 270 _AppMiscHandlers.enableSuddenTermination(); 271 } 272 273 /** 274 * Prevents this application from being suddenly terminated. 275 * 276 * Call this method to indicate that your application has unsaved state, and may not be terminated without notification. 277 * 278 * This call has no effect on Mac OS X versions prior to 10.6. 279 * 280 * @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. 281 * @see Application#enableSuddenTermination() 282 * 283 * @since Java for Mac OS X 10.6 Update 3 284 * @since Java for Mac OS X 10.5 Update 8 285 */ disableSuddenTermination()286 public void disableSuddenTermination() { 287 _AppMiscHandlers.disableSuddenTermination(); 288 } 289 290 /** 291 * Requests this application to move to the foreground. 292 * 293 * @param allWindows if all windows of this application should be moved to the foreground, or only the foremost one 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 */ requestForeground(final boolean allWindows)298 public void requestForeground(final boolean allWindows) { 299 _AppMiscHandlers.requestActivation(allWindows); 300 } 301 302 /** 303 * Requests user attention to this application (usually through bouncing the Dock icon). Critical 304 * requests will continue to bounce the Dock icon until the app is activated. An already active 305 * application requesting attention does nothing. 306 * 307 * @param critical if this is an important request 308 * 309 * @since Java for Mac OS X 10.6 Update 1 310 * @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5 311 */ requestUserAttention(final boolean critical)312 public void requestUserAttention(final boolean critical) { 313 _AppMiscHandlers.requestUserAttention(critical); 314 } 315 316 /** 317 * Opens the native help viewer application if a Help Book has been added to the 318 * application bundler and registered in the Info.plist with CFBundleHelpBookFolder. 319 * 320 * See http://developer.apple.com/qa/qa2001/qa1022.html for more information. 321 * 322 * @since Java for Mac OS X 10.5 - 1.5 323 * @since Java for Mac OS X 10.5 Update 1 - 1.6 324 */ openHelpViewer()325 public void openHelpViewer() { 326 _AppMiscHandlers.openHelpViewer(); 327 } 328 329 /** 330 * Attaches the contents of the provided PopupMenu to the application's Dock icon. 331 * 332 * @param menu the PopupMenu to attach to this application's Dock icon 333 * 334 * @since Java for Mac OS X 10.5 - 1.5 335 * @since Java for Mac OS X 10.5 Update 1 - 1.6 336 */ setDockMenu(final PopupMenu menu)337 public void setDockMenu(final PopupMenu menu) { 338 iconHandler.setDockMenu(menu); 339 } 340 341 /** 342 * @return the PopupMenu used to add items to this application's Dock icon 343 * 344 * @since Java for Mac OS X 10.5 - 1.5 345 * @since Java for Mac OS X 10.5 Update 1 - 1.6 346 */ getDockMenu()347 public PopupMenu getDockMenu() { 348 return iconHandler.getDockMenu(); 349 } 350 351 /** 352 * Changes this application's Dock icon to the provided image. 353 * 354 * @param image 355 * 356 * @since Java for Mac OS X 10.5 - 1.5 357 * @since Java for Mac OS X 10.5 Update 1 - 1.6 358 */ setDockIconImage(final Image image)359 public void setDockIconImage(final Image image) { 360 iconHandler.setDockIconImage(image); 361 } 362 363 /** 364 * Obtains an image of this application's Dock icon. 365 * 366 * @return an image of this application's Dock icon 367 * 368 * @since Java for Mac OS X 10.5 - 1.5 369 * @since Java for Mac OS X 10.5 Update 1 - 1.6 370 */ getDockIconImage()371 public Image getDockIconImage() { 372 return iconHandler.getDockIconImage(); 373 } 374 375 /** 376 * Affixes a small system provided badge to this application's Dock icon. Usually a number. 377 * 378 * @param badge textual label to affix to the Dock icon 379 * 380 * @since Java for Mac OS X 10.5 - 1.5 381 * @since Java for Mac OS X 10.5 Update 1 - 1.6 382 */ setDockIconBadge(final String badge)383 public void setDockIconBadge(final String badge) { 384 iconHandler.setDockIconBadge(badge); 385 } 386 387 /** 388 * Displays a progress bar to this application's Dock icon. 389 * Acceptable values are from 0 to 100, any other disables progress indication. 390 * 391 * @param value progress value 392 */ setDockIconProgress(final int value)393 public void setDockIconProgress(final int value) { 394 iconHandler.setDockIconProgress(value); 395 } 396 397 /** 398 * Sets the default menu bar to use when there are no active frames. 399 * Only used when the system property "apple.laf.useScreenMenuBar" is "true", and 400 * the Aqua Look and Feel is active. 401 * 402 * @param menuBar to use when no other frames are active 403 * 404 * @since Java for Mac OS X 10.6 Update 1 405 * @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5 406 */ setDefaultMenuBar(final JMenuBar menuBar)407 public void setDefaultMenuBar(final JMenuBar menuBar) { 408 menuBarHandler.setDefaultMenuBar(menuBar); 409 } 410 411 /** 412 * Requests that a {@link Window} should animate into or out of full screen mode. 413 * Only {@link Window}s marked as full screenable by {@link FullScreenUtilities#setWindowCanFullScreen(Window, boolean)} can be toggled. 414 * 415 * @param window to animate into or out of full screen mode 416 * 417 * @since Java for Mac OS X 10.7 Update 1 418 */ requestToggleFullScreen(final Window window)419 public void requestToggleFullScreen(final Window window) { 420 final Object peer = AWTAccessor.getComponentAccessor().getPeer(window); 421 if (!(peer instanceof LWWindowPeer)) return; 422 Object platformWindow = ((LWWindowPeer) peer).getPlatformWindow(); 423 if (!(platformWindow instanceof CPlatformWindow)) return; 424 ((CPlatformWindow)platformWindow).toggleFullScreen(); 425 } 426 427 } 428