Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/java/awt/Desktop.java
41152 views
1
/*
2
* Copyright (c) 2005, 2021, 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 java.awt;
27
28
import java.awt.desktop.AboutEvent;
29
import java.awt.desktop.AboutHandler;
30
import java.awt.desktop.OpenFilesHandler;
31
import java.awt.desktop.OpenURIEvent;
32
import java.awt.desktop.OpenURIHandler;
33
import java.awt.desktop.PreferencesEvent;
34
import java.awt.desktop.PreferencesHandler;
35
import java.awt.desktop.PrintFilesHandler;
36
import java.awt.desktop.QuitHandler;
37
import java.awt.desktop.QuitStrategy;
38
import java.awt.desktop.SystemEventListener;
39
import java.awt.peer.DesktopPeer;
40
import java.io.File;
41
import java.io.FilePermission;
42
import java.io.IOException;
43
import java.net.URI;
44
import java.net.URISyntaxException;
45
import java.security.AccessController;
46
import java.security.PrivilegedAction;
47
import java.util.Objects;
48
49
import javax.swing.JMenuBar;
50
51
import sun.awt.SunToolkit;
52
import sun.security.util.SecurityConstants;
53
54
/**
55
* The {@code Desktop} class allows interact with various desktop capabilities.
56
*
57
* <p> Supported operations include:
58
* <ul>
59
* <li>launching the user-default browser to show a specified
60
* URI;</li>
61
* <li>launching the user-default mail client with an optional
62
* {@code mailto} URI;</li>
63
* <li>launching a registered application to open, edit or print a
64
* specified file.</li>
65
* </ul>
66
*
67
* <p> This class provides methods corresponding to these
68
* operations. The methods look for the associated application
69
* registered on the current platform, and launch it to handle a URI
70
* or file. If there is no associated application or the associated
71
* application fails to be launched, an exception is thrown.
72
*
73
* Please see {@link Desktop.Action} for the full list of supported operations
74
* and capabilities.
75
*
76
* <p> An application is registered to a URI or file type.
77
* The mechanism of registering, accessing, and
78
* launching the associated application is platform-dependent.
79
*
80
* <p> Each operation is an action type represented by the {@link
81
* Desktop.Action} class.
82
*
83
* <p> Note: when some action is invoked and the associated
84
* application is executed, it will be executed on the same system as
85
* the one on which the Java application was launched.
86
*
87
* @see Action
88
*
89
* @since 1.6
90
* @author Armin Chen
91
* @author George Zhang
92
*/
93
public class Desktop {
94
95
/**
96
* Represents an action type. Each platform supports a different
97
* set of actions. You may use the {@link Desktop#isSupported}
98
* method to determine if the given action is supported by the
99
* current platform.
100
* @see java.awt.Desktop#isSupported(java.awt.Desktop.Action)
101
* @since 1.6
102
*/
103
public static enum Action {
104
/**
105
* Represents an "open" action.
106
* @see Desktop#open(java.io.File)
107
*/
108
OPEN,
109
/**
110
* Represents an "edit" action.
111
* @see Desktop#edit(java.io.File)
112
*/
113
EDIT,
114
/**
115
* Represents a "print" action.
116
* @see Desktop#print(java.io.File)
117
*/
118
PRINT,
119
/**
120
* Represents a "mail" action.
121
* @see Desktop#mail()
122
* @see Desktop#mail(java.net.URI)
123
*/
124
MAIL,
125
126
/**
127
* Represents a "browse" action.
128
* @see Desktop#browse(java.net.URI)
129
*/
130
BROWSE,
131
132
/**
133
* Represents an AppForegroundListener
134
* @see java.awt.desktop.AppForegroundListener
135
* @since 9
136
*/
137
APP_EVENT_FOREGROUND,
138
139
/**
140
* Represents an AppHiddenListener
141
* @see java.awt.desktop.AppHiddenListener
142
* @since 9
143
*/
144
APP_EVENT_HIDDEN,
145
146
/**
147
* Represents an AppReopenedListener
148
* @see java.awt.desktop.AppReopenedListener
149
* @since 9
150
*/
151
APP_EVENT_REOPENED,
152
153
/**
154
* Represents a ScreenSleepListener
155
* @see java.awt.desktop.ScreenSleepListener
156
* @since 9
157
*/
158
APP_EVENT_SCREEN_SLEEP,
159
160
/**
161
* Represents a SystemSleepListener
162
* @see java.awt.desktop.SystemSleepListener
163
* @since 9
164
*/
165
APP_EVENT_SYSTEM_SLEEP,
166
167
/**
168
* Represents a UserSessionListener
169
* @see java.awt.desktop.UserSessionListener
170
* @since 9
171
*/
172
APP_EVENT_USER_SESSION,
173
174
/**
175
* Represents an AboutHandler
176
* @see #setAboutHandler(java.awt.desktop.AboutHandler)
177
* @since 9
178
*/
179
APP_ABOUT,
180
181
/**
182
* Represents a PreferencesHandler
183
* @see #setPreferencesHandler(java.awt.desktop.PreferencesHandler)
184
* @since 9
185
*/
186
APP_PREFERENCES,
187
188
/**
189
* Represents an OpenFilesHandler
190
* @see #setOpenFileHandler(java.awt.desktop.OpenFilesHandler)
191
* @since 9
192
*/
193
APP_OPEN_FILE,
194
195
/**
196
* Represents a PrintFilesHandler
197
* @see #setPrintFileHandler(java.awt.desktop.PrintFilesHandler)
198
* @since 9
199
*/
200
APP_PRINT_FILE,
201
202
/**
203
* Represents an OpenURIHandler
204
* @see #setOpenURIHandler(java.awt.desktop.OpenURIHandler)
205
* @since 9
206
*/
207
APP_OPEN_URI,
208
209
/**
210
* Represents a QuitHandler
211
* @see #setQuitHandler(java.awt.desktop.QuitHandler)
212
* @since 9
213
*/
214
APP_QUIT_HANDLER,
215
216
/**
217
* Represents a QuitStrategy
218
* @see #setQuitStrategy(java.awt.desktop.QuitStrategy)
219
* @since 9
220
*/
221
APP_QUIT_STRATEGY,
222
223
/**
224
* Represents a SuddenTermination
225
* @see #enableSuddenTermination()
226
* @since 9
227
*/
228
APP_SUDDEN_TERMINATION,
229
230
/**
231
* Represents a requestForeground
232
* @see #requestForeground(boolean)
233
* @since 9
234
*/
235
APP_REQUEST_FOREGROUND,
236
237
/**
238
* Represents a HelpViewer
239
* @see #openHelpViewer()
240
* @since 9
241
*/
242
APP_HELP_VIEWER,
243
244
/**
245
* Represents a menu bar
246
* @see #setDefaultMenuBar(javax.swing.JMenuBar)
247
* @since 9
248
*/
249
APP_MENU_BAR,
250
251
/**
252
* Represents a browse file directory
253
* @see #browseFileDirectory(java.io.File)
254
* @since 9
255
*/
256
BROWSE_FILE_DIR,
257
258
/**
259
* Represents a move to trash
260
* @see #moveToTrash(java.io.File)
261
* @since 9
262
*/
263
MOVE_TO_TRASH
264
};
265
266
private DesktopPeer peer;
267
268
/**
269
* Suppresses default constructor for noninstantiability.
270
*/
271
private Desktop() {
272
Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
273
// same cast as in isDesktopSupported()
274
if (defaultToolkit instanceof SunToolkit) {
275
peer = ((SunToolkit) defaultToolkit).createDesktopPeer(this);
276
}
277
}
278
279
private void checkEventsProcessingPermission() {
280
@SuppressWarnings("removal")
281
SecurityManager sm = System.getSecurityManager();
282
if (sm != null) {
283
sm.checkPermission(new RuntimePermission(
284
"canProcessApplicationEvents"));
285
}
286
}
287
288
/**
289
* Returns the {@code Desktop} instance of the current
290
* desktop context. On some platforms the Desktop API may not be
291
* supported; use the {@link #isDesktopSupported} method to
292
* determine if the current desktop is supported.
293
* @return the Desktop instance
294
* @throws HeadlessException if {@link
295
* GraphicsEnvironment#isHeadless()} returns {@code true}
296
* @throws UnsupportedOperationException if this class is not
297
* supported on the current platform
298
* @see #isDesktopSupported()
299
* @see java.awt.GraphicsEnvironment#isHeadless
300
*/
301
public static synchronized Desktop getDesktop(){
302
if (GraphicsEnvironment.isHeadless()) throw new HeadlessException();
303
if (!Desktop.isDesktopSupported()) {
304
throw new UnsupportedOperationException("Desktop API is not " +
305
"supported on the current platform");
306
}
307
308
sun.awt.AppContext context = sun.awt.AppContext.getAppContext();
309
Desktop desktop = (Desktop)context.get(Desktop.class);
310
311
if (desktop == null) {
312
desktop = new Desktop();
313
context.put(Desktop.class, desktop);
314
}
315
316
return desktop;
317
}
318
319
/**
320
* Tests whether this class is supported on the current platform.
321
* If it's supported, use {@link #getDesktop()} to retrieve an
322
* instance.
323
*
324
* @return {@code true} if this class is supported on the
325
* current platform; {@code false} otherwise
326
* @see #getDesktop()
327
*/
328
public static boolean isDesktopSupported(){
329
Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
330
if (defaultToolkit instanceof SunToolkit) {
331
return ((SunToolkit)defaultToolkit).isDesktopSupported();
332
}
333
return false;
334
}
335
336
/**
337
* Tests whether an action is supported on the current platform.
338
*
339
* <p>Even when the platform supports an action, a file or URI may
340
* not have a registered application for the action. For example,
341
* most of the platforms support the {@link Desktop.Action#OPEN}
342
* action. But for a specific file, there may not be an
343
* application registered to open it. In this case, {@link
344
* #isSupported(Action)} may return {@code true}, but the corresponding
345
* action method will throw an {@link IOException}.
346
*
347
* @param action the specified {@link Action}
348
* @return {@code true} if the specified action is supported on
349
* the current platform; {@code false} otherwise
350
* @see Desktop.Action
351
*/
352
public boolean isSupported(Action action) {
353
return peer.isSupported(action);
354
}
355
356
/**
357
* Checks if the file is a valid file and readable.
358
*
359
* @throws SecurityException If a security manager exists and its
360
* {@link SecurityManager#checkRead(java.lang.String)} method
361
* denies read access to the file
362
* @throws NullPointerException if file is null
363
* @throws IllegalArgumentException if file doesn't exist
364
*/
365
private static void checkFileValidation(File file) {
366
if (!file.exists()) {
367
throw new IllegalArgumentException("The file: "
368
+ file.getPath() + " doesn't exist.");
369
}
370
}
371
372
/**
373
* Checks if the action type is supported.
374
*
375
* @param actionType the action type in question
376
* @throws UnsupportedOperationException if the specified action type is not
377
* supported on the current platform
378
*/
379
private void checkActionSupport(Action actionType){
380
if (!isSupported(actionType)) {
381
throw new UnsupportedOperationException("The " + actionType.name()
382
+ " action is not supported on the current platform!");
383
}
384
}
385
386
387
/**
388
* Calls to the security manager's {@code checkPermission} method with an
389
* {@code AWTPermission("showWindowWithoutWarningBanner")} permission. This
390
* permission is needed, because we cannot add a security warning icon to
391
* the windows of the external native application.
392
*/
393
private void checkAWTPermission() {
394
@SuppressWarnings("removal")
395
SecurityManager sm = System.getSecurityManager();
396
if (sm != null) {
397
sm.checkPermission(new AWTPermission(
398
"showWindowWithoutWarningBanner"));
399
}
400
}
401
402
/**
403
* Launches the associated application to open the file.
404
*
405
* <p> If the specified file is a directory, the file manager of
406
* the current platform is launched to open it.
407
*
408
* @param file the file to be opened with the associated application
409
* @throws NullPointerException if {@code file} is {@code null}
410
* @throws IllegalArgumentException if the specified file doesn't
411
* exist
412
* @throws UnsupportedOperationException if the current platform
413
* does not support the {@link Desktop.Action#OPEN} action
414
* @throws IOException if the specified file has no associated
415
* application or the associated application fails to be launched
416
* @throws SecurityException if a security manager exists and its
417
* {@link java.lang.SecurityManager#checkRead(java.lang.String)}
418
* method denies read access to the file, or it denies the
419
* {@code AWTPermission("showWindowWithoutWarningBanner")}
420
* permission, or the calling thread is not allowed to create a
421
* subprocess
422
* @see java.awt.AWTPermission
423
*/
424
public void open(File file) throws IOException {
425
file = new File(file.getPath());
426
checkAWTPermission();
427
checkExec();
428
checkActionSupport(Action.OPEN);
429
checkFileValidation(file);
430
431
peer.open(file);
432
}
433
434
/**
435
* Launches the associated editor application and opens a file for
436
* editing.
437
*
438
* @param file the file to be opened for editing
439
* @throws NullPointerException if the specified file is {@code null}
440
* @throws IllegalArgumentException if the specified file doesn't
441
* exist
442
* @throws UnsupportedOperationException if the current platform
443
* does not support the {@link Desktop.Action#EDIT} action
444
* @throws IOException if the specified file has no associated
445
* editor, or the associated application fails to be launched
446
* @throws SecurityException if a security manager exists and its
447
* {@link java.lang.SecurityManager#checkRead(java.lang.String)}
448
* method denies read access to the file, or {@link
449
* java.lang.SecurityManager#checkWrite(java.lang.String)} method
450
* denies write access to the file, or it denies the
451
* {@code AWTPermission("showWindowWithoutWarningBanner")}
452
* permission, or the calling thread is not allowed to create a
453
* subprocess
454
* @see java.awt.AWTPermission
455
*/
456
public void edit(File file) throws IOException {
457
file = new File(file.getPath());
458
checkAWTPermission();
459
checkExec();
460
checkActionSupport(Action.EDIT);
461
file.canWrite();
462
checkFileValidation(file);
463
if (file.isDirectory()) {
464
throw new IOException(file.getPath() + " is a directory");
465
}
466
peer.edit(file);
467
}
468
469
/**
470
* Prints a file with the native desktop printing facility, using
471
* the associated application's print command.
472
*
473
* @param file the file to be printed
474
* @throws NullPointerException if the specified file is {@code
475
* null}
476
* @throws IllegalArgumentException if the specified file doesn't
477
* exist
478
* @throws UnsupportedOperationException if the current platform
479
* does not support the {@link Desktop.Action#PRINT} action
480
* @throws IOException if the specified file has no associated
481
* application that can be used to print it
482
* @throws SecurityException if a security manager exists and its
483
* {@link java.lang.SecurityManager#checkRead(java.lang.String)}
484
* method denies read access to the file, or its {@link
485
* java.lang.SecurityManager#checkPrintJobAccess()} method denies
486
* the permission to print the file, or the calling thread is not
487
* allowed to create a subprocess
488
*/
489
public void print(File file) throws IOException {
490
file = new File(file.getPath());
491
checkExec();
492
@SuppressWarnings("removal")
493
SecurityManager sm = System.getSecurityManager();
494
if (sm != null) {
495
sm.checkPrintJobAccess();
496
}
497
checkActionSupport(Action.PRINT);
498
checkFileValidation(file);
499
if (file.isDirectory()) {
500
throw new IOException(file.getPath() + " is a directory");
501
}
502
peer.print(file);
503
}
504
505
/**
506
* Launches the default browser to display a {@code URI}.
507
* If the default browser is not able to handle the specified
508
* {@code URI}, the application registered for handling
509
* {@code URIs} of the specified type is invoked. The application
510
* is determined from the protocol and path of the {@code URI}, as
511
* defined by the {@code URI} class.
512
*
513
* @param uri the URI to be displayed in the user default browser
514
* @throws NullPointerException if {@code uri} is {@code null}
515
* @throws UnsupportedOperationException if the current platform
516
* does not support the {@link Desktop.Action#BROWSE} action
517
* @throws IOException if the user default browser is not found,
518
* or it fails to be launched, or the default handler application
519
* failed to be launched
520
* @throws SecurityException if a security manager exists and it
521
* denies the
522
* {@code AWTPermission("showWindowWithoutWarningBanner")}
523
* permission, or the calling thread is not allowed to create a
524
* subprocess
525
* @see java.net.URI
526
* @see java.awt.AWTPermission
527
*/
528
public void browse(URI uri) throws IOException {
529
checkAWTPermission();
530
checkExec();
531
checkActionSupport(Action.BROWSE);
532
Objects.requireNonNull(uri);
533
peer.browse(uri);
534
}
535
536
/**
537
* Launches the mail composing window of the user default mail
538
* client.
539
*
540
* @throws UnsupportedOperationException if the current platform
541
* does not support the {@link Desktop.Action#MAIL} action
542
* @throws IOException if the user default mail client is not
543
* found, or it fails to be launched
544
* @throws SecurityException if a security manager exists and it
545
* denies the
546
* {@code AWTPermission("showWindowWithoutWarningBanner")}
547
* permission, or the calling thread is not allowed to create a
548
* subprocess
549
* @see java.awt.AWTPermission
550
*/
551
public void mail() throws IOException {
552
checkAWTPermission();
553
checkExec();
554
checkActionSupport(Action.MAIL);
555
URI mailtoURI = null;
556
try{
557
mailtoURI = new URI("mailto:?");
558
peer.mail(mailtoURI);
559
} catch (URISyntaxException e){
560
// won't reach here.
561
}
562
}
563
564
/**
565
* Launches the mail composing window of the user default mail
566
* client, filling the message fields specified by a {@code
567
* mailto:} URI.
568
*
569
* <p> A {@code mailto:} URI can specify message fields
570
* including <i>"to"</i>, <i>"cc"</i>, <i>"subject"</i>,
571
* <i>"body"</i>, etc. See <a
572
* href="http://www.ietf.org/rfc/rfc2368.txt">The mailto URL
573
* scheme (RFC 2368)</a> for the {@code mailto:} URI specification
574
* details.
575
*
576
* @param mailtoURI the specified {@code mailto:} URI
577
* @throws NullPointerException if the specified URI is {@code
578
* null}
579
* @throws IllegalArgumentException if the URI scheme is not
580
* {@code "mailto"}
581
* @throws UnsupportedOperationException if the current platform
582
* does not support the {@link Desktop.Action#MAIL} action
583
* @throws IOException if the user default mail client is not
584
* found or fails to be launched
585
* @throws SecurityException if a security manager exists and it
586
* denies the
587
* {@code AWTPermission("showWindowWithoutWarningBanner")}
588
* permission, or the calling thread is not allowed to create a
589
* subprocess
590
* @see java.net.URI
591
* @see java.awt.AWTPermission
592
*/
593
public void mail(URI mailtoURI) throws IOException {
594
checkAWTPermission();
595
checkExec();
596
checkActionSupport(Action.MAIL);
597
if (mailtoURI == null) throw new NullPointerException();
598
599
if (!"mailto".equalsIgnoreCase(mailtoURI.getScheme())) {
600
throw new IllegalArgumentException("URI scheme is not \"mailto\"");
601
}
602
603
peer.mail(mailtoURI);
604
}
605
606
private void checkExec() throws SecurityException {
607
@SuppressWarnings("removal")
608
SecurityManager sm = System.getSecurityManager();
609
if (sm != null) {
610
sm.checkPermission(new FilePermission("<<ALL FILES>>",
611
SecurityConstants.FILE_EXECUTE_ACTION));
612
}
613
}
614
615
private void checkRead() throws SecurityException {
616
@SuppressWarnings("removal")
617
SecurityManager sm = System.getSecurityManager();
618
if (sm != null) {
619
sm.checkPermission(new FilePermission("<<ALL FILES>>",
620
SecurityConstants.FILE_READ_ACTION));
621
}
622
}
623
624
private void checkQuitPermission() {
625
@SuppressWarnings("removal")
626
SecurityManager sm = System.getSecurityManager();
627
if (sm != null) {
628
sm.checkExit(0);
629
}
630
}
631
632
/**
633
* Adds sub-types of {@link SystemEventListener} to listen for notifications
634
* from the native system.
635
*
636
* Has no effect if SystemEventListener's sub-type is unsupported on the current
637
* platform.
638
*
639
* @param listener listener
640
*
641
* @throws SecurityException if a security manager exists and it
642
* denies the
643
* {@code RuntimePermission("canProcessApplicationEvents")}
644
* permission
645
*
646
* @see java.awt.desktop.AppForegroundListener
647
* @see java.awt.desktop.AppHiddenListener
648
* @see java.awt.desktop.AppReopenedListener
649
* @see java.awt.desktop.ScreenSleepListener
650
* @see java.awt.desktop.SystemSleepListener
651
* @see java.awt.desktop.UserSessionListener
652
* @since 9
653
*/
654
public void addAppEventListener(final SystemEventListener listener) {
655
checkEventsProcessingPermission();
656
peer.addAppEventListener(listener);
657
}
658
659
/**
660
* Removes sub-types of {@link SystemEventListener} to listen for notifications
661
* from the native system.
662
*
663
* Has no effect if SystemEventListener's sub-type is unsupported on the current
664
* platform.
665
*
666
* @param listener listener
667
*
668
* @throws SecurityException if a security manager exists and it
669
* denies the
670
* {@code RuntimePermission("canProcessApplicationEvents")}
671
* permission
672
*
673
* @see java.awt.desktop.AppForegroundListener
674
* @see java.awt.desktop.AppHiddenListener
675
* @see java.awt.desktop.AppReopenedListener
676
* @see java.awt.desktop.ScreenSleepListener
677
* @see java.awt.desktop.SystemSleepListener
678
* @see java.awt.desktop.UserSessionListener
679
* @since 9
680
*/
681
public void removeAppEventListener(final SystemEventListener listener) {
682
checkEventsProcessingPermission();
683
peer.removeAppEventListener(listener);
684
}
685
686
/**
687
* Installs a handler to show a custom About window for your application.
688
* <p>
689
* Setting the {@link java.awt.desktop.AboutHandler} to {@code null} reverts it to the
690
* default behavior.
691
*
692
* @param aboutHandler the handler to respond to the
693
* {@link java.awt.desktop.AboutHandler#handleAbout(AboutEvent)} message
694
*
695
* @throws SecurityException if a security manager exists and it
696
* denies the
697
* {@code RuntimePermission("canProcessApplicationEvents")}
698
* permission
699
* @throws UnsupportedOperationException if the current platform
700
* does not support the {@link Desktop.Action#APP_ABOUT} action
701
*
702
* @since 9
703
*/
704
public void setAboutHandler(final AboutHandler aboutHandler) {
705
checkEventsProcessingPermission();
706
checkActionSupport(Action.APP_ABOUT);
707
peer.setAboutHandler(aboutHandler);
708
}
709
710
/**
711
* Installs a handler to show a custom Preferences window for your
712
* application.
713
* <p>
714
* Setting the {@link PreferencesHandler} to {@code null} reverts it to
715
* the default behavior
716
*
717
* @param preferencesHandler the handler to respond to the
718
* {@link PreferencesHandler#handlePreferences(PreferencesEvent)}
719
*
720
* @throws SecurityException if a security manager exists and it
721
* denies the
722
* {@code RuntimePermission("canProcessApplicationEvents")} permission
723
* @throws UnsupportedOperationException if the current platform
724
* does not support the {@link Desktop.Action#APP_PREFERENCES} action
725
* @since 9
726
*/
727
public void setPreferencesHandler(final PreferencesHandler preferencesHandler) {
728
checkEventsProcessingPermission();
729
checkActionSupport(Action.APP_PREFERENCES);
730
peer.setPreferencesHandler(preferencesHandler);
731
}
732
733
/**
734
* Installs the handler which is notified when the application is asked to
735
* open a list of files.
736
*
737
* @implNote Please note that for macOS, notifications
738
* are only sent if the Java app is a bundled application,
739
* with a {@code CFBundleDocumentTypes} array present in its
740
* {@code Info.plist}. Check the
741
* <a href="https://developer.apple.com/documentation">
742
* Apple Developer Documentation</a> for more information about
743
* {@code Info.plist}.
744
*
745
* @param openFileHandler handler
746
*
747
* @throws SecurityException if a security manager exists and its
748
* {@link java.lang.SecurityManager#checkRead(java.lang.String)}
749
* method denies read access to the files, or it denies the
750
* {@code RuntimePermission("canProcessApplicationEvents")}
751
* permission, or the calling thread is not allowed to create a
752
* subprocess
753
* @throws UnsupportedOperationException if the current platform
754
* does not support the {@link Desktop.Action#APP_OPEN_FILE} action
755
* @since 9
756
*/
757
public void setOpenFileHandler(final OpenFilesHandler openFileHandler) {
758
checkEventsProcessingPermission();
759
checkExec();
760
checkRead();
761
checkActionSupport(Action.APP_OPEN_FILE);
762
peer.setOpenFileHandler(openFileHandler);
763
}
764
765
/**
766
* Installs the handler which is notified when the application is asked to
767
* print a list of files.
768
*
769
* @implNote Please note that for macOS, notifications
770
* are only sent if the Java app is a bundled application,
771
* with a {@code CFBundleDocumentTypes} array present in its
772
* {@code Info.plist}. Check the
773
* <a href="https://developer.apple.com/documentation">
774
* Apple Developer Documentation</a> for more information about
775
* {@code Info.plist}.
776
*
777
* @param printFileHandler handler
778
* @throws SecurityException if a security manager exists and its
779
* {@link java.lang.SecurityManager#checkPrintJobAccess()} method denies
780
* the permission to print or it denies the
781
* {@code RuntimePermission("canProcessApplicationEvents")} permission
782
* @throws UnsupportedOperationException if the current platform
783
* does not support the {@link Desktop.Action#APP_PRINT_FILE} action
784
* @since 9
785
*/
786
public void setPrintFileHandler(final PrintFilesHandler printFileHandler) {
787
checkEventsProcessingPermission();
788
@SuppressWarnings("removal")
789
SecurityManager sm = System.getSecurityManager();
790
if (sm != null) {
791
sm.checkPrintJobAccess();
792
}
793
checkActionSupport(Action.APP_PRINT_FILE);
794
peer.setPrintFileHandler(printFileHandler);
795
}
796
797
/**
798
* Installs the handler which is notified when the application is asked to
799
* open a URL.
800
*
801
* Setting the handler to {@code null} causes all
802
* {@link OpenURIHandler#openURI(OpenURIEvent)} requests to be
803
* enqueued until another handler is set.
804
*
805
* @implNote Please note that for macOS, notifications
806
* are only sent if the Java app is a bundled application,
807
* with a {@code CFBundleDocumentTypes} array present in its
808
* {@code Info.plist}. Check the
809
* <a href="https://developer.apple.com/documentation">
810
* Apple Developer Documentation</a> for more information about
811
* {@code Info.plist}.
812
*
813
* @param openURIHandler handler
814
*
815
* {@code RuntimePermission("canProcessApplicationEvents")}
816
* permission, or the calling thread is not allowed to create a
817
* subprocess
818
* @throws UnsupportedOperationException if the current platform
819
* does not support the {@link Desktop.Action#APP_OPEN_URI} action
820
* @since 9
821
*/
822
public void setOpenURIHandler(final OpenURIHandler openURIHandler) {
823
checkEventsProcessingPermission();
824
checkExec();
825
checkActionSupport(Action.APP_OPEN_URI);
826
peer.setOpenURIHandler(openURIHandler);
827
}
828
829
/**
830
* Installs the handler which determines if the application should quit. The
831
* handler is passed a one-shot {@link java.awt.desktop.QuitResponse} which can cancel or
832
* proceed with the quit. Setting the handler to {@code null} causes
833
* all quit requests to directly perform the default {@link QuitStrategy}.
834
*
835
* @param quitHandler the handler that is called when the application is
836
* asked to quit
837
*
838
* @throws SecurityException if a security manager exists and it
839
* will not allow the caller to invoke {@code System.exit} or it denies the
840
* {@code RuntimePermission("canProcessApplicationEvents")} permission
841
* @throws UnsupportedOperationException if the current platform
842
* does not support the {@link Desktop.Action#APP_QUIT_HANDLER} action
843
* @since 9
844
*/
845
public void setQuitHandler(final QuitHandler quitHandler) {
846
checkEventsProcessingPermission();
847
checkQuitPermission();
848
checkActionSupport(Action.APP_QUIT_HANDLER);
849
peer.setQuitHandler(quitHandler);
850
}
851
852
/**
853
* Sets the default strategy used to quit this application. The default is
854
* calling SYSTEM_EXIT_0.
855
*
856
* @param strategy the way this application should be shutdown
857
*
858
* @throws SecurityException if a security manager exists and it
859
* will not allow the caller to invoke {@code System.exit} or it denies the
860
* {@code RuntimePermission("canProcessApplicationEvents")} permission
861
* @throws UnsupportedOperationException if the current platform
862
* does not support the {@link Desktop.Action#APP_QUIT_STRATEGY} action
863
* @see QuitStrategy
864
* @since 9
865
*/
866
public void setQuitStrategy(final QuitStrategy strategy) {
867
checkEventsProcessingPermission();
868
checkQuitPermission();
869
checkActionSupport(Action.APP_QUIT_STRATEGY);
870
peer.setQuitStrategy(strategy);
871
}
872
873
/**
874
* Enables this application to be suddenly terminated.
875
*
876
* Call this method to indicate your application's state is saved, and
877
* requires no notification to be terminated. Letting your application
878
* remain terminatable improves the user experience by avoiding re-paging in
879
* your application when it's asked to quit.
880
*
881
* <b>Note: enabling sudden termination will allow your application to be
882
* quit without notifying your QuitHandler, or running any shutdown
883
* hooks.</b>
884
* E.g. user-initiated Cmd-Q, logout, restart, or shutdown requests will
885
* effectively "kill -KILL" your application.
886
*
887
* @throws SecurityException if a security manager exists and it
888
* will not allow the caller to invoke {@code System.exit} or it denies the
889
* {@code RuntimePermission("canProcessApplicationEvents")} permission
890
* @throws UnsupportedOperationException if the current platform
891
* does not support the {@link Desktop.Action#APP_SUDDEN_TERMINATION} action
892
* @see #disableSuddenTermination()
893
* @since 9
894
*/
895
public void enableSuddenTermination() {
896
checkEventsProcessingPermission();
897
checkQuitPermission();
898
checkActionSupport(Action.APP_SUDDEN_TERMINATION);
899
peer.enableSuddenTermination();
900
}
901
902
/**
903
* Prevents this application from being suddenly terminated.
904
*
905
* Call this method to indicate that your application has unsaved state, and
906
* may not be terminated without notification.
907
*
908
* @throws SecurityException if a security manager exists and it
909
* will not allow the caller to invoke {@code System.exit} or it denies the
910
* {@code RuntimePermission("canProcessApplicationEvents")} permission
911
* @throws UnsupportedOperationException if the current platform
912
* does not support the {@link Desktop.Action#APP_SUDDEN_TERMINATION} action
913
* @see #enableSuddenTermination()
914
* @since 9
915
*/
916
public void disableSuddenTermination() {
917
checkEventsProcessingPermission();
918
checkQuitPermission();
919
checkActionSupport(Action.APP_SUDDEN_TERMINATION);
920
peer.disableSuddenTermination();
921
}
922
923
/**
924
* Requests this application to move to the foreground.
925
*
926
* @param allWindows if all windows of this application should be moved to
927
* the foreground, or only the foremost one
928
* @throws SecurityException if a security manager exists and it denies the
929
* {@code RuntimePermission("canProcessApplicationEvents")} permission.
930
* @throws UnsupportedOperationException if the current platform
931
* does not support the {@link Desktop.Action#APP_REQUEST_FOREGROUND} action
932
* @since 9
933
*/
934
public void requestForeground(final boolean allWindows) {
935
checkEventsProcessingPermission();
936
checkActionSupport(Action.APP_REQUEST_FOREGROUND);
937
peer.requestForeground(allWindows);
938
}
939
940
/**
941
* Opens the native help viewer application.
942
*
943
* @implNote Please note that for Mac OS, it opens the native help viewer
944
* application if a Help Book has been added to the application bundler
945
* and registered in the Info.plist with CFBundleHelpBookFolder
946
*
947
* @throws SecurityException if a security manager exists and it denies the
948
* {@code RuntimePermission("canProcessApplicationEvents")}
949
* permission, or it denies the
950
* {@code AWTPermission("showWindowWithoutWarningBanner")}
951
* permission, or the calling thread is not allowed to create a
952
* subprocess
953
* @throws UnsupportedOperationException if the current platform
954
* does not support the {@link Desktop.Action#APP_HELP_VIEWER} action
955
* @since 9
956
*/
957
public void openHelpViewer() {
958
checkAWTPermission();
959
checkExec();
960
checkEventsProcessingPermission();
961
checkActionSupport(Action.APP_HELP_VIEWER);
962
peer.openHelpViewer();
963
}
964
965
/**
966
* Sets the default menu bar to use when there are no active frames.
967
*
968
* @param menuBar to use when no other frames are active
969
* @throws SecurityException if a security manager exists and it denies the
970
* {@code RuntimePermission("canProcessApplicationEvents")} permission.
971
* @throws UnsupportedOperationException if the current platform
972
* does not support the {@link Desktop.Action#APP_MENU_BAR} action
973
* @since 9
974
*/
975
public void setDefaultMenuBar(final JMenuBar menuBar) {
976
checkEventsProcessingPermission();
977
checkActionSupport(Action.APP_MENU_BAR);
978
979
if (menuBar != null) {
980
Container parent = menuBar.getParent();
981
if (parent != null) {
982
parent.remove(menuBar);
983
menuBar.updateUI();
984
}
985
}
986
987
peer.setDefaultMenuBar(menuBar);
988
}
989
990
/**
991
* Opens a folder containing the {@code file} and selects it
992
* in a default system file manager.
993
* @param file the file
994
* @throws SecurityException If a security manager exists and its
995
* {@link SecurityManager#checkRead(java.lang.String)} method
996
* denies read access to the file or to its parent, or it denies the
997
* {@code AWTPermission("showWindowWithoutWarningBanner")}
998
* permission, or the calling thread is not allowed to create a
999
* subprocess
1000
* @throws UnsupportedOperationException if the current platform
1001
* does not support the {@link Desktop.Action#BROWSE_FILE_DIR} action
1002
* @throws NullPointerException if {@code file} is {@code null}
1003
* @throws IllegalArgumentException if the specified file or its parent
1004
* doesn't exist
1005
* @since 9
1006
*/
1007
public void browseFileDirectory(File file) {
1008
file = new File(file.getPath());
1009
checkAWTPermission();
1010
checkExec();
1011
checkActionSupport(Action.BROWSE_FILE_DIR);
1012
checkFileValidation(file);
1013
File parentFile = file.getParentFile();
1014
if (parentFile == null || !parentFile.exists()) {
1015
throw new IllegalArgumentException("Parent folder doesn't exist");
1016
}
1017
peer.browseFileDirectory(file);
1018
}
1019
1020
/**
1021
* Moves the specified file to the trash.
1022
*
1023
* @param file the file
1024
* @return returns true if successfully moved the file to the trash.
1025
* @throws SecurityException If a security manager exists and its
1026
* {@link SecurityManager#checkDelete(java.lang.String)} method
1027
* denies deletion of the file
1028
* @throws UnsupportedOperationException if the current platform
1029
* does not support the {@link Desktop.Action#MOVE_TO_TRASH} action
1030
* @throws NullPointerException if {@code file} is {@code null}
1031
* @throws IllegalArgumentException if the specified file doesn't exist
1032
*
1033
* @since 9
1034
*/
1035
@SuppressWarnings("removal")
1036
public boolean moveToTrash(File file) {
1037
file = new File(file.getPath());
1038
SecurityManager sm = System.getSecurityManager();
1039
if (sm != null) {
1040
sm.checkDelete(file.getPath());
1041
}
1042
checkActionSupport(Action.MOVE_TO_TRASH);
1043
final File finalFile = file;
1044
AccessController.doPrivileged((PrivilegedAction<?>) () -> {
1045
checkFileValidation(finalFile);
1046
return null;
1047
});
1048
return peer.moveToTrash(file);
1049
}
1050
}
1051
1052