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 java.awt; 27 28 import java.awt.peer.DesktopPeer; 29 import java.io.File; 30 import java.io.FilePermission; 31 import java.io.IOException; 32 import java.net.MalformedURLException; 33 import java.net.URI; 34 import java.net.URISyntaxException; 35 import java.net.URL; 36 37 import sun.awt.SunToolkit; 38 import sun.security.util.SecurityConstants; 39 40 /** 41 * The {@code Desktop} class allows a Java application to launch 42 * associated applications registered on the native desktop to handle 43 * a {@link java.net.URI} or a file. 44 * 45 * <p> Supported operations include: 46 * <ul> 47 * <li>launching the user-default browser to show a specified 48 * URI;</li> 49 * <li>launching the user-default mail client with an optional 50 * {@code mailto} URI;</li> 51 * <li>launching a registered application to open, edit or print a 52 * specified file.</li> 53 * </ul> 54 * 55 * <p> This class provides methods corresponding to these 56 * operations. The methods look for the associated application 57 * registered on the current platform, and launch it to handle a URI 58 * or file. If there is no associated application or the associated 59 * application fails to be launched, an exception is thrown. 60 * 61 * <p> An application is registered to a URI or file type; for 62 * example, the {@code "sxi"} file extension is typically registered 63 * to StarOffice. The mechanism of registering, accessing, and 64 * launching the associated application is platform-dependent. 65 * 66 * <p> Each operation is an action type represented by the {@link 67 * Desktop.Action} class. 68 * 69 * <p> Note: when some action is invoked and the associated 70 * application is executed, it will be executed on the same system as 71 * the one on which the Java application was launched. 72 * 73 * @since 1.6 74 * @author Armin Chen 75 * @author George Zhang 76 */ 77 public class Desktop { 78 79 /** 80 * Represents an action type. Each platform supports a different 81 * set of actions. You may use the {@link Desktop#isSupported} 82 * method to determine if the given action is supported by the 83 * current platform. 84 * @see java.awt.Desktop#isSupported(java.awt.Desktop.Action) 85 * @since 1.6 86 */ 87 public static enum Action { 88 /** 89 * Represents an "open" action. 90 * @see Desktop#open(java.io.File) 91 */ 92 OPEN, 93 /** 94 * Represents an "edit" action. 95 * @see Desktop#edit(java.io.File) 96 */ 97 EDIT, 98 /** 99 * Represents a "print" action. 100 * @see Desktop#print(java.io.File) 101 */ 102 PRINT, 103 /** 104 * Represents a "mail" action. 105 * @see Desktop#mail() 106 * @see Desktop#mail(java.net.URI) 107 */ 108 MAIL, 109 /** 110 * Represents a "browse" action. 111 * @see Desktop#browse(java.net.URI) 112 */ 113 BROWSE 114 }; 115 116 private DesktopPeer peer; 117 118 /** 119 * Suppresses default constructor for noninstantiability. 120 */ 121 private Desktop() { 122 Toolkit defaultToolkit = Toolkit.getDefaultToolkit(); 123 // same cast as in isDesktopSupported() 124 if (defaultToolkit instanceof SunToolkit) { 125 peer = ((SunToolkit) defaultToolkit).createDesktopPeer(this); 126 } 127 } 128 129 /** 130 * Returns the <code>Desktop</code> instance of the current 131 * browser context. On some platforms the Desktop API may not be 132 * supported; use the {@link #isDesktopSupported} method to 133 * determine if the current desktop is supported. 465 public void mail(URI mailtoURI) throws IOException { 466 checkAWTPermission(); 467 checkExec(); 468 checkActionSupport(Action.MAIL); 469 if (mailtoURI == null) throw new NullPointerException(); 470 471 if (!"mailto".equalsIgnoreCase(mailtoURI.getScheme())) { 472 throw new IllegalArgumentException("URI scheme is not \"mailto\""); 473 } 474 475 peer.mail(mailtoURI); 476 } 477 478 private void checkExec() throws SecurityException { 479 SecurityManager sm = System.getSecurityManager(); 480 if (sm != null) { 481 sm.checkPermission(new FilePermission("<<ALL FILES>>", 482 SecurityConstants.FILE_EXECUTE_ACTION)); 483 } 484 } 485 } | 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 package java.awt; 26 27 import java.awt.desktop.*; 28 import java.awt.peer.DesktopPeer; 29 import java.io.File; 30 import java.io.FilePermission; 31 import java.io.IOException; 32 import java.net.MalformedURLException; 33 import java.net.URI; 34 import java.net.URISyntaxException; 35 import java.net.URL; 36 37 import sun.awt.SunToolkit; 38 import javax.swing.JMenuBar; 39 import sun.security.util.SecurityConstants; 40 41 /** 42 * The {@code Desktop} class allows a Java application to launch 43 * associated applications registered on the native desktop to handle 44 * a {@link java.net.URI} or a file. 45 * 46 * <p> Supported operations include: 47 * <ul> 48 * <li>launching the user-default browser to show a specified 49 * URI;</li> 50 * <li>launching the user-default mail client with an optional 51 * {@code mailto} URI;</li> 52 * <li>launching a registered application to open, edit or print a 53 * specified file.</li> 54 * </ul> 55 * 56 * <p> This class provides methods corresponding to these 57 * operations. The methods look for the associated application 58 * registered on the current platform, and launch it to handle a URI 59 * or file. If there is no associated application or the associated 60 * application fails to be launched, an exception is thrown. 61 * 62 * <p> An application is registered to a URI or file type; for 63 * example, the {@code "sxi"} file extension is typically registered 64 * to StarOffice. The mechanism of registering, accessing, and 65 * launching the associated application is platform-dependent. 66 * 67 * <p> Each operation is an action type represented by the {@link 68 * Desktop.Action} class. 69 * 70 * <p> Note: when some action is invoked and the associated 71 * application is executed, it will be executed on the same system as 72 * the one on which the Java application was launched. 73 * 74 * <p> 75 * Please note that for Mac OS notifications for 76 * {@link OpenFilesHandler#openFiles(AppEvent.OpenFilesEvent)}, 77 * {@link PrintFilesHandler#printFiles(AppEvent.PrintFilesEvent)} )} and 78 * {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} 79 * are only sent if the Java app is a bundled application, 80 * with a <code>CFBundleDocumentTypes</code> array present in it's 81 * Info.plist. See the 82 * <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist 83 * Key Reference</a> for more information about adding a 84 * <code>CFBundleDocumentTypes</code> key to your app's Info.plist. 85 * 86 * @since 1.6 87 * @author Armin Chen 88 * @author George Zhang 89 */ 90 public class Desktop { 91 92 /** 93 * Represents an action type. Each platform supports a different 94 * set of actions. You may use the {@link Desktop#isSupported} 95 * method to determine if the given action is supported by the 96 * current platform. 97 * @see java.awt.Desktop#isSupported(java.awt.Desktop.Action) 98 * @since 1.6 99 */ 100 public static enum Action { 101 /** 102 * Represents an "open" action. 103 * @see Desktop#open(java.io.File) 104 */ 105 OPEN, 106 /** 107 * Represents an "edit" action. 108 * @see Desktop#edit(java.io.File) 109 */ 110 EDIT, 111 /** 112 * Represents a "print" action. 113 * @see Desktop#print(java.io.File) 114 */ 115 PRINT, 116 /** 117 * Represents a "mail" action. 118 * @see Desktop#mail() 119 * @see Desktop#mail(java.net.URI) 120 */ 121 MAIL, 122 /** 123 * Represents a "browse" action. 124 * @see Desktop#browse(java.net.URI) 125 */ 126 BROWSE, 127 128 /** 129 * Represents a AppForegroundListener 130 * @see java.awt.desktop.AppForegroundListener 131 */ 132 APP_EVENT_FOREGROUND, 133 134 /** 135 * Represents a AppHiddenListener 136 * @see java.awt.desktop.AppHiddenListener 137 */ 138 APP_EVENT_HIDDEN, 139 140 /** 141 * Represents a AppReopenedListener 142 * @see java.awt.desktop.AppReopenedListener 143 */ 144 APP_EVENT_REOPENED, 145 146 /** 147 * Represents a ScreenSleepListener 148 * @see java.awt.desktop.ScreenSleepListener 149 */ 150 APP_EVENT_SCREEN_SLEEP, 151 152 /** 153 * Represents a SystemSleepListener 154 * @see java.awt.desktop.SystemSleepListener 155 */ 156 APP_EVENT_SYSTEM_SLEEP, 157 158 /** 159 * Represents a UserSessionListener 160 * @see java.awt.desktop.UserSessionListener 161 */ 162 APP_EVENT_USER_SESSION, 163 164 /** 165 * Represents a AboutHandler 166 * @see #setAboutHandler(java.awt.desktop.AboutHandler) 167 */ 168 APP_ABOUT, 169 170 /** 171 * Represents a PreferencesHandler 172 * @see #setPreferencesHandler(java.awt.desktop.PreferencesHandler) 173 */ 174 APP_PREFERENCES, 175 176 /** 177 * Represents a OpenFilesHandler 178 * @see #setOpenFileHandler(java.awt.desktop.OpenFilesHandler) 179 */ 180 APP_OPEN_FILE, 181 182 /** 183 * Represents a PrintFilesHandler 184 * @see #setPrintFileHandler(java.awt.desktop.PrintFilesHandler) 185 */ 186 APP_PRINT_FILE, 187 188 /** 189 * Represents a OpenURIHandler 190 * @see #setOpenURIHandler(java.awt.desktop.OpenURIHandler) 191 */ 192 APP_OPEN_URI, 193 194 /** 195 * Represents a QuitHandler 196 * @see #setQuitHandler(java.awt.desktop.QuitHandler) 197 */ 198 APP_QUIT_HANDLER, 199 200 /** 201 * Represents a QuitStrategy 202 * @see #setQuitStrategy(java.awt.desktop.QuitStrategy) 203 */ 204 APP_QUIT_STRATEGY, 205 206 /** 207 * Represents a SuddenTermination 208 * @see #enableSuddenTermination() 209 */ 210 APP_SUDDEN_TERMINATION, 211 212 /** 213 * Represents a requestForeground 214 * @see #requestForeground(boolean) 215 */ 216 APP_REQUEST_FOREGROUND, 217 218 /** 219 * Represents a HelpViewer 220 * @see #openHelpViewer() 221 */ 222 APP_HELP_VIEWER, 223 224 /** 225 * Represents a menu bar 226 * @see #setDefaultMenuBar(javax.swing.JMenuBar) 227 */ 228 APP_MENU_BAR, 229 230 /** 231 * Represents a platform specific full screen 232 * @see #addWindowFullScreenListener(java.awt.Window, java.awt.desktop.FullScreenListener) 233 * @see #removeWindowFullScreenListener(java.awt.Window, java.awt.desktop.FullScreenListener) 234 * @see #setWindowCanFullScreen(java.awt.Window, boolean) 235 * @see #requestToggleFullScreen(java.awt.Window) 236 */ 237 FULLSCREEN, 238 239 /** 240 * Represents a FileManager 241 * @see #getFileManager() 242 */ 243 FILEMANAGER 244 }; 245 246 private DesktopPeer peer; 247 248 /** 249 * Suppresses default constructor for noninstantiability. 250 */ 251 private Desktop() { 252 Toolkit defaultToolkit = Toolkit.getDefaultToolkit(); 253 // same cast as in isDesktopSupported() 254 if (defaultToolkit instanceof SunToolkit) { 255 peer = ((SunToolkit) defaultToolkit).createDesktopPeer(this); 256 } 257 } 258 259 /** 260 * Returns the <code>Desktop</code> instance of the current 261 * browser context. On some platforms the Desktop API may not be 262 * supported; use the {@link #isDesktopSupported} method to 263 * determine if the current desktop is supported. 595 public void mail(URI mailtoURI) throws IOException { 596 checkAWTPermission(); 597 checkExec(); 598 checkActionSupport(Action.MAIL); 599 if (mailtoURI == null) throw new NullPointerException(); 600 601 if (!"mailto".equalsIgnoreCase(mailtoURI.getScheme())) { 602 throw new IllegalArgumentException("URI scheme is not \"mailto\""); 603 } 604 605 peer.mail(mailtoURI); 606 } 607 608 private void checkExec() throws SecurityException { 609 SecurityManager sm = System.getSecurityManager(); 610 if (sm != null) { 611 sm.checkPermission(new FilePermission("<<ALL FILES>>", 612 SecurityConstants.FILE_EXECUTE_ACTION)); 613 } 614 } 615 616 /** 617 * Adds sub-types of {@link SystemEventListener} to listen for notifications 618 * from the native system. 619 * 620 * Has no effect if SystemEventListener's sub-type is unsupported on current 621 * platform. 622 * 623 * @param listener listener 624 * @see AppForegroundListener 625 * @see AppHiddenListener 626 * @see AppReopenedListener 627 * @see ScreenSleepListener 628 * @see SystemSleepListener 629 * @see UserSessionListener 630 */ 631 public void addAppEventListener(final SystemEventListener listener) { 632 peer.addAppEventListener(listener); 633 } 634 635 /** 636 * Removes sub-types of {@link SystemEventListener} to listen for notifications 637 * from the native system. 638 * 639 * Has no effect if SystemEventListener's sub-type is unsupported on current 640 * platform. 641 * 642 * @param listener listener 643 * @see AppForegroundListener 644 * @see AppHiddenListener 645 * @see AppReOpenedListener 646 * @see AppScreenSleepListener 647 * @see AppSystemSleepListener 648 * @see AppUserSessionListener 649 */ 650 public void removeAppEventListener(final SystemEventListener listener) { 651 peer.removeAppEventListener(listener); 652 } 653 654 /** 655 * Installs a handler to show a custom About window for your application. 656 * <p> 657 * Setting the {@link AboutHandler} to <code>null</code> reverts it to the 658 * default behavior. 659 * 660 * @param aboutHandler the handler to respond to the 661 * {@link AboutHandler#handleAbout} )} message 662 */ 663 public void setAboutHandler(final AboutHandler aboutHandler) { 664 checkActionSupport(Action.APP_ABOUT); 665 peer.setAboutHandler(aboutHandler); 666 } 667 668 /** 669 * Installs a handler to show a custom Preferences window for your 670 * application. 671 * <p> 672 * Setting the {@link PreferencesHandler} to <code>null</code> reverts it to 673 * the default behavior 674 * 675 * @param preferencesHandler the handler to respond to the 676 * {@link PreferencesHandler#handlePreferences(PreferencesEvent)} 677 */ 678 public void setPreferencesHandler(final PreferencesHandler preferencesHandler) { 679 checkActionSupport(Action.APP_PREFERENCES); 680 peer.setPreferencesHandler(preferencesHandler); 681 } 682 683 /** 684 * Installs the handler which is notified when the application is asked to 685 * open a list of files. 686 * 687 * @param openFileHandler handler 688 */ 689 public void setOpenFileHandler(final OpenFilesHandler openFileHandler) { 690 checkActionSupport(Action.APP_OPEN_FILE); 691 peer.setOpenFileHandler(openFileHandler); 692 } 693 694 /** 695 * Installs the handler which is notified when the application is asked to 696 * print a list of files. 697 * 698 * @param printFileHandler handler 699 */ 700 public void setPrintFileHandler(final PrintFilesHandler printFileHandler) { 701 checkActionSupport(Action.APP_PRINT_FILE); 702 peer.setPrintFileHandler(printFileHandler); 703 } 704 705 /** 706 * Installs the handler which is notified when the application is asked to 707 * open a URL. 708 * 709 * Setting the handler to <code>null</code> causes all 710 * {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} requests to be 711 * enqueued until another handler is set. 712 * 713 * @param openURIHandler handler 714 */ 715 public void setOpenURIHandler(final OpenURIHandler openURIHandler) { 716 checkActionSupport(Action.APP_OPEN_URI); 717 peer.setOpenURIHandler(openURIHandler); 718 } 719 720 /** 721 * Installs the handler which determines if the application should quit. The 722 * handler is passed a one-shot {@link QuitResponse} which can cancel or 723 * proceed with the quit. Setting the handler to <code>null</code> causes 724 * all quit requests to directly perform the default {@link QuitStrategy}. 725 * 726 * @param quitHandler the handler that is called when the application is 727 * asked to quit 728 */ 729 public void setQuitHandler(final QuitHandler quitHandler) { 730 checkActionSupport(Action.APP_QUIT_HANDLER); 731 peer.setQuitHandler(quitHandler); 732 } 733 734 /** 735 * Sets the default strategy used to quit this application. The default is 736 * calling SYSTEM_EXIT_0. 737 * 738 * @param strategy the way this application should be shutdown 739 */ 740 public void setQuitStrategy(final QuitStrategy strategy) { 741 checkActionSupport(Action.APP_QUIT_STRATEGY); 742 peer.setQuitStrategy(strategy); 743 } 744 745 /** 746 * Enables this application to be suddenly terminated. 747 * 748 * Call this method to indicate your application's state is saved, and 749 * requires no notification to be terminated. Letting your application 750 * remain terminatable improves the user experience by avoiding re-paging in 751 * your application when it's asked to quit. 752 * 753 * <b>Note: enabling sudden termination will allow your application to be 754 * quit without notifying your QuitHandler, or running any shutdown 755 * hooks.</b> 756 * E.g. user initiated Cmd-Q, logout, restart, or shutdown requests will 757 * effectively "kill -KILL" your application. 758 * 759 * @see #disableSuddenTermination() 760 */ 761 public void enableSuddenTermination() { 762 checkActionSupport(Action.APP_SUDDEN_TERMINATION); 763 peer.enableSuddenTermination(); 764 } 765 766 /** 767 * Prevents this application from being suddenly terminated. 768 * 769 * Call this method to indicate that your application has unsaved state, and 770 * may not be terminated without notification. 771 * 772 * @see #enableSuddenTermination() 773 */ 774 public void disableSuddenTermination() { 775 checkActionSupport(Action.APP_SUDDEN_TERMINATION); 776 peer.disableSuddenTermination(); 777 } 778 779 /** 780 * Requests this application to move to the foreground. 781 * 782 * @param allWindows if all windows of this application should be moved to 783 * the foreground, or only the foremost one 784 */ 785 public void requestForeground(final boolean allWindows) { 786 checkActionSupport(Action.APP_REQUEST_FOREGROUND); 787 peer.requestForeground(allWindows); 788 } 789 790 /** 791 * Opens the native help viewer application. 792 */ 793 public void openHelpViewer() { 794 checkActionSupport(Action.APP_HELP_VIEWER); 795 peer.openHelpViewer(); 796 } 797 798 /** 799 * Sets the default menu bar to use when there are no active frames. 800 * 801 * Note, Aqua Look and Feel should be active to support this on Mac OS. 802 * 803 * @param menuBar to use when no other frames are active 804 */ 805 public void setDefaultMenuBar(final JMenuBar menuBar) { 806 checkActionSupport(Action.APP_MENU_BAR); 807 peer.setDefaultMenuBar(menuBar); 808 } 809 810 /** 811 * Attaches a {@link FullScreenListener} to the specified top-level 812 * {@link Window}. 813 * 814 * @param window to attach the {@link FullScreenListener} to 815 * @param listener to be notified when a full screen event occurs 816 * @throws IllegalArgumentException if window is not a 817 * {@link RootPaneContainer} 818 */ 819 public void addWindowFullScreenListener(final Window window, 820 final FullScreenListener listener) { 821 checkActionSupport(Action.FULLSCREEN); 822 peer.addWindowFullScreenListener(window, listener); 823 } 824 825 /** 826 * Removes a {@link FullScreenListener} from the specified top-level 827 * {@link Window}. 828 * 829 * @param window to remove the {@link FullScreenListener} from 830 * @param listener to be removed 831 * @throws IllegalArgumentException if window is not a 832 * {@link RootPaneContainer} 833 */ 834 public void removeWindowFullScreenListener(final Window window, 835 final FullScreenListener listener) { 836 checkActionSupport(Action.FULLSCREEN); 837 peer.removeWindowFullScreenListener(window, listener); 838 } 839 840 /** 841 * Marks a {@link Window} as able to animate into or out of full screen 842 * mode. 843 * 844 * Only top-level {@link Window}s which are {@link RootPaneContainer}s are 845 * able to be animated into and out of full screen mode. The {@link Window} 846 * must be marked as full screen-able before the native peer is created with 847 * {@link Component#addNotify()}. 848 * 849 * @param window window 850 * @param canFullScreen flag 851 * @throws IllegalArgumentException if window is not a 852 * {@link RootPaneContainer} 853 */ 854 public void setWindowCanFullScreen(final Window window, final boolean canFullScreen) { 855 checkActionSupport(Action.FULLSCREEN); 856 peer.setWindowCanFullScreen(window, canFullScreen); 857 } 858 859 /** 860 * Requests that a {@link Window} should get into or out of full screen 861 * mode. Only {@link Window}s marked as full screenable by 862 * {@link #setWindowCanFullScreen(Window, boolean)} can be toggled. 863 * 864 * @param window to animate into or out of full screen mode 865 */ 866 public void requestToggleFullScreen(final Window window) { 867 checkActionSupport(Action.FULLSCREEN); 868 peer.requestToggleFullScreen(window); 869 } 870 871 /** 872 * Returns the mac specific FileManager. 873 * @return FileManager 874 * @see FileManager 875 */ 876 public FileManager getFileManager() { 877 checkActionSupport(Action.FILEMANAGER); 878 return peer.getFileManager(); 879 } 880 881 } |