Taskbar.java revision 14044:7d9ef221ddc7
1/*
2 * Copyright (c) 2016, 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
26package java.awt;
27
28import java.awt.peer.TaskbarPeer;
29import sun.awt.SunToolkit;
30
31/**
32 * The {@code Taskbar} class allows a Java application to interact with
33 * the system task area (taskbar, Dock, etc.).
34 *
35 * <p>
36 * There are a variety of interactions depending on the current platform such as
37 * displaying progress of some task, appending user-specified menu to the application
38 * icon context menu, etc.
39 *
40 * @implNote Linux support is currently limited to Unity. However to make these
41 * features work on Unity, the app should be run from a .desktop file with
42 * specified {@code java.desktop.appName} system property set to this .desktop
43 * file name:
44 * {@code Exec=java -Djava.desktop.appName=MyApp.desktop -jar /path/to/myapp.jar}
45 * see <a href="https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles">
46 * https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles</a>
47 *
48 * @since 9
49 */
50
51public class Taskbar {
52
53    /**
54     * List of provided features. Each platform supports a different
55     * set of features.  You may use the {@link Taskbar#isSupported}
56     * method to determine if the given feature is supported by the
57     * current platform.
58     */
59    public static enum Feature {
60
61        /**
62         * Represents a textual icon badge feature.
63         * @see #setIconBadge(java.lang.String)
64         */
65        ICON_BADGE_TEXT,
66
67        /**
68         * Represents a numerical icon badge feature.
69         * @see #setIconBadge(java.lang.String)
70         */
71        ICON_BADGE_NUMBER,
72
73        /**
74         * Represents a graphical icon badge feature for a window.
75         * @see #setWindowIconBadge(java.awt.Window, java.awt.Image)
76         */
77        ICON_BADGE_IMAGE_WINDOW,
78
79        /**
80         * Represents an icon feature.
81         * @see #setIconImage(java.awt.Image)
82         */
83        ICON_IMAGE,
84
85        /**
86         * Represents a menu feature.
87         * @see #setMenu(java.awt.PopupMenu)
88         * @see #getMenu()
89         */
90        MENU,
91
92        /**
93         * Represents a progress state feature for a specified window.
94         * @see #setWindowProgressState(java.awt.Window, State)
95         */
96        PROGRESS_STATE_WINDOW,
97
98        /**
99         * Represents a progress value feature.
100         * @see #setProgressValue(int)
101         */
102        PROGRESS_VALUE,
103
104        /**
105         * Represents a progress value feature for a specified window.
106         * @see #setWindowProgressValue(java.awt.Window, int)
107         */
108        PROGRESS_VALUE_WINDOW,
109
110        /**
111         * Represents a user attention request feature.
112         * @see #requestUserAttention(boolean, boolean)
113         */
114        USER_ATTENTION,
115
116        /**
117         * Represents a user attention request feature for a specified window.
118         * @see #requestWindowUserAttention(java.awt.Window)
119         */
120        USER_ATTENTION_WINDOW
121    }
122
123    /**
124     * Kinds of available window progress states.
125     *
126     * @see #setWindowProgressState(java.awt.Window, java.awt.Taskbar.State)
127     */
128    public static enum State {
129        /**
130         * Stops displaying the progress.
131         */
132        OFF,
133        /**
134         * The progress indicator displays with normal color and determinate
135         * mode.
136         */
137        NORMAL,
138        /**
139         * Shows progress as paused, progress can be resumed by the user.
140         * Switches to the determinate display.
141         */
142        PAUSED,
143        /**
144         * The progress indicator displays activity without specifying what
145         * proportion of the progress is complete.
146         */
147        INDETERMINATE,
148        /**
149         * Shows that an error has occurred. Switches to the determinate
150         * display.
151         */
152        ERROR
153    }
154
155    private TaskbarPeer peer;
156
157    /**
158     * Tests whether a {@code Feature} is supported on the current platform.
159     * @param feature the specified {@link Feature}
160     * @return true if the specified feature is supported on the current platform
161     */
162    public boolean isSupported(Feature feature) {
163        return peer.isSupported(feature);
164    }
165
166    /**
167     * Checks if the feature type is supported.
168     *
169     * @param featureType the action type in question
170     * @throws UnsupportedOperationException if the specified action type is not
171     *         supported on the current platform
172     */
173    private void checkFeatureSupport(Feature featureType){
174        if (!isSupported(featureType)) {
175            throw new UnsupportedOperationException("The " + featureType.name()
176                    + " feature is not supported on the current platform!");
177        }
178    }
179
180    /**
181     *  Calls to the security manager's {@code checkPermission} method with
182     *  an {@code AWTPermission("showWindowWithoutWarningBanner")}
183     *  permission.
184     */
185    private void checkAWTPermission(){
186        SecurityManager sm = System.getSecurityManager();
187        if (sm != null) {
188            sm.checkPermission(new AWTPermission(
189                    "showWindowWithoutWarningBanner"));
190        }
191    }
192
193    private Taskbar() {
194        Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
195        if (defaultToolkit instanceof SunToolkit) {
196            peer = ((SunToolkit) defaultToolkit).createTaskbarPeer(this);
197        }
198    }
199
200    /**
201     * Returns the {@code Taskbar} instance of the current
202     * taskbar context.  On some platforms the Taskbar API may not be
203     * supported; use the {@link #isTaskbarSupported} method to
204     * determine if the current taskbar is supported.
205     * @return the Taskbar instance
206     * @throws HeadlessException if {@link
207     * GraphicsEnvironment#isHeadless()} returns {@code true}
208     * @throws UnsupportedOperationException if this class is not
209     * supported on the current platform
210     * @see #isTaskbarSupported()
211     * @see java.awt.GraphicsEnvironment#isHeadless
212     */
213    public static synchronized Taskbar getTaskbar(){
214        if (GraphicsEnvironment.isHeadless()) throw new HeadlessException();
215
216        if (!Taskbar.isTaskbarSupported()) {
217            throw new UnsupportedOperationException("Taskbar API is not " +
218                                                    "supported on the current platform");
219        }
220
221        sun.awt.AppContext context = sun.awt.AppContext.getAppContext();
222        Taskbar taskbar = (Taskbar)context.get(Taskbar.class);
223
224        if (taskbar == null) {
225            taskbar = new Taskbar();
226            context.put(Taskbar.class, taskbar);
227        }
228
229        return taskbar;
230    }
231
232    /**
233     * Tests whether this class is supported on the current platform.
234     * If it's supported, use {@link #getTaskbar()} to retrieve an
235     * instance.
236     *
237     * @return {@code true} if this class is supported on the
238     *         current platform; {@code false} otherwise
239     * @see #getTaskbar()
240     */
241    public static boolean isTaskbarSupported(){
242        Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
243        if (defaultToolkit instanceof SunToolkit) {
244            return ((SunToolkit)defaultToolkit).isTaskbarSupported();
245        }
246        return false;
247    }
248
249    /**
250     * Requests user attention to this application.
251     *
252     * Depending on the platform, this may be visually indicated by a bouncing
253     * or flashing icon in the task area. It may have no effect on an already active
254     * application.
255     *
256     * On some platforms (e.g. Mac OS) this effect may disappear upon app activation
257     * and cannot be dismissed by setting {@code enabled} to false.
258     * Other platforms may require an additional call
259     * {@link #requestUserAttention} to dismiss this request
260     * with {@code enabled} parameter set to false.
261     *
262     * @param enabled disables this request if false
263     * @param critical if this is an important request
264     * @throws SecurityException if a security manager exists and it denies the
265     * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
266     * @throws UnsupportedOperationException if the current platform
267     * does not support the {@link Taskbar.Feature#USER_ATTENTION} feature
268     */
269    public void requestUserAttention(final boolean enabled, final boolean critical) {
270        checkAWTPermission();
271        checkFeatureSupport(Feature.USER_ATTENTION);
272        peer.requestUserAttention(enabled, critical);
273    }
274
275    /**
276     * Requests user attention to the specified window until it is activated.
277     *
278     * On an already active window requesting attention does nothing.
279     *
280     * @param w window
281     * @throws SecurityException if a security manager exists and it denies the
282     * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
283     * @throws UnsupportedOperationException if the current platform
284     * does not support the {@link Taskbar.Feature#USER_ATTENTION_WINDOW} feature
285     */
286    public void requestWindowUserAttention(Window w) {
287        checkAWTPermission();
288        checkFeatureSupport(Feature.USER_ATTENTION_WINDOW);
289        peer.requestWindowUserAttention(w);
290    }
291
292    /**
293     * Attaches the contents of the provided PopupMenu to the application icon
294     * in the task area.
295     *
296     * @param menu the PopupMenu to attach to this application
297     * @throws SecurityException if a security manager exists and it denies the
298     * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
299     * @throws UnsupportedOperationException if the current platform
300     * does not support the {@link Taskbar.Feature#MENU} feature
301     */
302    public void setMenu(final PopupMenu menu) {
303        checkAWTPermission();
304        checkFeatureSupport(Feature.MENU);
305        peer.setMenu(menu);
306    }
307
308    /**
309     * Gets PopupMenu used to add items to this application's icon in system task area.
310     *
311     * @return the PopupMenu
312     * @throws SecurityException if a security manager exists and it denies the
313     * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
314     * @throws UnsupportedOperationException if the current platform
315     * does not support the {@link Taskbar.Feature#MENU} feature
316     */
317    public PopupMenu getMenu() {
318        checkAWTPermission();
319        checkFeatureSupport(Feature.MENU);
320        return peer.getMenu();
321    }
322
323    /**
324     * Changes this application's icon to the provided image.
325     *
326     * @param image to change
327     * @throws SecurityException if a security manager exists and it denies the
328     * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
329     * @throws UnsupportedOperationException if the current platform
330     * does not support the {@link Taskbar.Feature#ICON_IMAGE} feature
331     */
332    public void setIconImage(final Image image) {
333        checkAWTPermission();
334        checkFeatureSupport(Feature.ICON_IMAGE);
335        peer.setIconImage(image);
336    }
337
338    /**
339     * Obtains an image of this application's icon.
340     *
341     * @return an image of this application's icon
342     * @throws SecurityException if a security manager exists and it denies the
343     * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
344     * @throws UnsupportedOperationException if the current platform
345     * does not support the {@link Taskbar.Feature#ICON_IMAGE} feature
346     */
347    public Image getIconImage() {
348        checkAWTPermission();
349        checkFeatureSupport(Feature.ICON_IMAGE);
350        return peer.getIconImage();
351    }
352
353    /**
354     * Affixes a small system-provided badge to this application's icon.
355     * Usually a number.
356     *
357     * Some platforms do not support string values and accept only integer
358     * values. In this case, pass an integer represented as a string as parameter.
359     * This can be tested by {@code Feature.ICON_BADGE_STRING} and
360     * {@code Feature.ICON_BADGE_NUMBER}.
361     *
362     * Passing {@code null} as parameter hides the badge.
363     * @param badge label to affix to the icon
364     * @throws SecurityException if a security manager exists and it denies the
365     * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
366     * @throws UnsupportedOperationException if the current platform
367     * does not support the {@link Taskbar.Feature#ICON_BADGE_NUMBER} feature
368     */
369    public void setIconBadge(final String badge) {
370        checkAWTPermission();
371        checkFeatureSupport(Feature.ICON_BADGE_NUMBER);
372        peer.setIconBadge(badge);
373    }
374
375    /**
376     * Affixes a small badge to this application's icon in the task area
377     * for the specified window.
378     * It may be disabled by system settings.
379     *
380     * @param w window to update
381     * @param badge image to affix to the icon
382     * @throws SecurityException if a security manager exists and it denies the
383     * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
384     * @throws UnsupportedOperationException if the current platform
385     * does not support the {@link Taskbar.Feature#ICON_BADGE_IMAGE_WINDOW} feature
386     */
387    public void setWindowIconBadge(Window w, final Image badge) {
388        checkAWTPermission();
389        checkFeatureSupport(Feature.ICON_BADGE_IMAGE_WINDOW);
390        if (w != null) {
391            peer.setWindowIconBadge(w, badge);
392        }
393    }
394
395
396    /**
397     * Affixes a small system-provided progress bar to this application's icon.
398     *
399     * @param value from 0 to 100, other to disable progress indication
400     * @throws UnsupportedOperationException if the current platform
401     * does not support the {@link Taskbar.Feature#PROGRESS_VALUE} feature
402     */
403    public void setProgressValue(int value) {
404        checkAWTPermission();
405        checkFeatureSupport(Feature.PROGRESS_VALUE);
406        peer.setProgressValue(value);
407    }
408
409    /**
410     * Displays progress for specified window.
411     *
412     * @param w window to update
413     * @param value from 0 to 100, other to disable progress indication
414     * @throws SecurityException if a security manager exists and it denies the
415     * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
416     * @throws UnsupportedOperationException if the current platform
417     * does not support the {@link Taskbar.Feature#PROGRESS_VALUE_WINDOW} feature
418     */
419    public void setWindowProgressValue(Window w, int value) {
420        checkAWTPermission();
421        checkFeatureSupport(Feature.PROGRESS_VALUE_WINDOW);
422        if (w != null) {
423            peer.setWindowProgressValue(w, value);
424        }
425    }
426
427    /**
428     * Sets a progress state for a specified window.
429     *
430     * @param w window
431     * @param state to change to
432     * @see State#OFF
433     * @see State#NORMAL
434     * @see State#PAUSED
435     * @see State#INDETERMINATE
436     * @see State#ERROR
437     * @throws SecurityException if a security manager exists and it denies the
438     * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
439     * @throws UnsupportedOperationException if the current platform
440     * does not support the {@link Taskbar.Feature#PROGRESS_STATE_WINDOW} feature
441     */
442    public void setWindowProgressState(Window w, State state) {
443        checkAWTPermission();
444        checkFeatureSupport(Feature.PROGRESS_STATE_WINDOW);
445        if (w != null) {
446            peer.setWindowProgressState(w, state);
447        }
448    }
449}
450