1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt; 27 28 import sun.awt.SunToolkit; 29 30 /** 31 * The {@code Taskbar} class allows a Java application to interact with 32 * system task area(Taskbar, Dock, etc.). 33 * 34 * There are a variety of interactions depending on running platform such as 35 * displaying progress of some task, appending user specified menu to application 36 * icon context menu, etc. 37 * 38 * Linux support is limited to Unity, however to make this features work on Unity 39 * the app should be run from a .desktop file with specified java.desktop.appName 40 * system property set to this .desktop file name: 41 * Exec=java -Djava.desktop.appName=MyApp.desktop -jar /path/to/myapp.jar 42 * see https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles 43 */ 44 45 public class Taskbar { 46 47 /** 48 * List of provided features. 49 */ 50 public static enum Feature { 51 52 /** 53 * @see #setIconBadge(java.lang.String) 54 */ 55 ICON_BADGE_TEXT, 56 57 /** 58 * @see #setIconBadge(java.lang.String) 59 */ 60 ICON_BADGE_NUMBER, 61 62 /** 63 * @see #setWindowIconBadge(java.awt.Window, java.awt.Image) 64 */ 65 ICON_BADGE_IMAGE_WINDOW, 66 67 /** 68 * @see #setIconImage(java.awt.Image) 69 */ 70 ICON_IMAGE, 71 72 /** 73 * @see #setMenu(java.awt.PopupMenu) 74 * @see #getMenu() 75 */ 76 MENU, 77 78 /** 79 * @see #setWindowProgressState(java.awt.Window, int) 80 */ 81 PROGRESS_STATE_WINDOW, 82 83 /** 84 * @see #setProgressValue(int) 85 */ 86 PROGRESS_VALUE, 87 88 /** 89 * @see #setWindowProgressValue(java.awt.Window, int) 90 */ 91 PROGRESS_VALUE_WINDOW, 92 93 /** 94 * @see #requestUserAttention(boolean, boolean) 95 */ 96 USER_ATTENTION, 97 98 /** 99 * @see #requestWindowUserAttention(java.awt.Window) 100 */ 101 USER_ATTENTION_WINDOW 102 } 103 104 /** 105 * Stops displaying the progress. 106 */ 107 public static final int STATE_OFF = 0x0; 108 109 /** 110 * The progress indicator displays with normal color and determinate mode. 111 */ 112 public static final int STATE_NORMAL = 0x1; 113 114 /** 115 * Shows progress as paused, progress can be resumed by user. 116 * Switches to the determinate display. 117 */ 118 public static final int STATE_PAUSED = 0x2; 119 120 /** 121 * The progress indicator displays activity without specifying what 122 * proportion of the progress is complete. 123 */ 124 public static final int STATE_INDETERMINATE = 0x3; 125 126 /** 127 * Shows that an error has occurred. 128 * Switches to the determinate display. 129 */ 130 public static final int STATE_ERROR = 0x4; 131 132 private TaskbarPeer peer; 133 134 /** 135 * Tests whether a {@code Feature} is supported on the current platform. 136 * @param feature the specified {@link Feature} 137 * @return true if the specified feature is supported on the current platform 138 */ 139 public boolean isSupported(Feature feature) { 140 return peer.isSupported(feature); 141 } 142 143 /** 144 * Checks if the feature type is supported. 145 * 146 * @param featureType the action type in question 147 * @throws UnsupportedOperationException if the specified action type is not 148 * supported on the current platform 149 */ 150 private void checkFeatureSupport(Feature featureType){ 151 if (!isSupported(featureType)) { 152 throw new UnsupportedOperationException("The " + featureType.name() 153 + " feature is not supported on the current platform!"); 154 } 155 } 156 private Taskbar() { 157 Toolkit defaultToolkit = Toolkit.getDefaultToolkit(); 158 if (defaultToolkit instanceof SunToolkit) { 159 peer = ((SunToolkit) defaultToolkit).createTaskbarPeer(this); 160 } 161 } 162 163 /** 164 * Returns the <code>Taskbar</code> instance of the current 165 * browser context. On some platforms the Taskbar API may not be 166 * supported; use the {@link #isTaskbarSupported} method to 167 * determine if the current taskbar is supported. 168 * @return the Taskbar instance of the current browser context 169 * @throws HeadlessException if {@link 170 * GraphicsEnvironment#isHeadless()} returns {@code true} 171 * @throws UnsupportedOperationException if this class is not 172 * supported on the current platform 173 * @see #isTaskbarSupported() 174 * @see java.awt.GraphicsEnvironment#isHeadless 175 */ 176 public static synchronized Taskbar getTaskbar(){ 177 if (GraphicsEnvironment.isHeadless()) throw new HeadlessException(); 178 179 if (!Taskbar.isTaskbarSupported()) { 180 throw new UnsupportedOperationException("Taskbar API is not " + 181 "supported on the current platform"); 182 } 183 184 sun.awt.AppContext context = sun.awt.AppContext.getAppContext(); 185 Taskbar taskbar = (Taskbar)context.get(Taskbar.class); 186 187 if (taskbar == null) { 188 taskbar = new Taskbar(); 189 context.put(Taskbar.class, taskbar); 190 } 191 192 return taskbar; 193 } 194 195 /** 196 * Tests whether this class is supported on the current platform. 197 * If it's supported, use {@link #getTaskbar()} to retrieve an 198 * instance. 199 * 200 * @return <code>true</code> if this class is supported on the 201 * current platform; <code>false</code> otherwise 202 * @see #getTaskbar() 203 */ 204 public static boolean isTaskbarSupported(){ 205 Toolkit defaultToolkit = Toolkit.getDefaultToolkit(); 206 if (defaultToolkit instanceof SunToolkit) { 207 return ((SunToolkit)defaultToolkit).isTaskbarSupported(); 208 } 209 return false; 210 } 211 212 /** 213 * Requests user attention to this application. 214 * 215 * Depending on platform, this may be visually indicated by bouncing 216 * or flashing icon in task area. It may has no effect on an already active 217 * application. 218 * 219 * On some platforms(e.g. Mac OS) this effect may disappear upon app activation 220 * and cannot be dismissed by setting {@code enabled} to false. 221 * On other platforms may require additional call to 222 * {@link #requestUserAttention} to dismiss this request 223 * with {@code enabled} parameter set to false. 224 * 225 * @param enabled disables this request if false 226 * @param critical if this is an important request 227 */ 228 public void requestUserAttention(final boolean enabled, final boolean critical) { 229 checkFeatureSupport(Feature.USER_ATTENTION); 230 peer.requestUserAttention(enabled, critical); 231 } 232 233 /** 234 * Requests user attention to the specified window until it is activated. 235 * 236 * On an already active window requesting attention does nothing. 237 * 238 * @param w window 239 */ 240 public void requestWindowUserAttention(Window w) { 241 checkFeatureSupport(Feature.USER_ATTENTION_WINDOW); 242 peer.requestWindowUserAttention(w); 243 } 244 245 /** 246 * Attaches the contents of the provided PopupMenu to the application icon 247 * in system task area. 248 * 249 * @param menu the PopupMenu to attach to this application 250 */ 251 public void setMenu(final PopupMenu menu) { 252 checkFeatureSupport(Feature.MENU); 253 peer.setMenu(menu); 254 } 255 256 /** 257 * Gets PopupMenu used to add items to this application's icon in system task area. 258 * 259 * @return the PopupMenu 260 */ 261 public PopupMenu getMenu() { 262 checkFeatureSupport(Feature.MENU); 263 return peer.getMenu(); 264 } 265 266 /** 267 * Changes this application's icon to the provided image. 268 * 269 * @param image to change 270 */ 271 public void setIconImage(final Image image) { 272 checkFeatureSupport(Feature.ICON_IMAGE); 273 peer.setIconImage(image); 274 } 275 276 /** 277 * Obtains an image of this application's icon. 278 * 279 * @return an image of this application's icon 280 */ 281 public Image getIconImage() { 282 checkFeatureSupport(Feature.ICON_IMAGE); 283 return peer.getIconImage(); 284 } 285 286 /** 287 * Affixes a small system provided badge to this application's icon. 288 * Usually a number. 289 * 290 * Some platforms does not support string values and accepts only integer 291 * values. In this case pass an integer represented as string as a parameter. 292 * This can be tested by {@code Feature.ICON_BADGE_STRING} and 293 * {@code Feature.ICON_BADGE_NUMBER}. 294 * 295 * Passing {@code null} as parameter hides the badge. 296 * @param badge label to affix to the icon 297 */ 298 public void setIconBadge(final String badge) { 299 checkFeatureSupport(Feature.ICON_BADGE_NUMBER); 300 peer.setIconBadge(badge); 301 } 302 303 /** 304 * Affixes a small badge to this application's icon in task area 305 * for the specified window. 306 * It may be disabled by system settings. 307 * 308 * @param w window to update 309 * @param badge image to affix to the icon 310 */ 311 public void setWindowIconBadge(Window w, final Image badge) { 312 checkFeatureSupport(Feature.ICON_BADGE_IMAGE_WINDOW); 313 if (w != null) { 314 peer.setWindowIconBadge(w, badge); 315 } 316 } 317 318 319 /** 320 * Affixes a small system provided progress bar to this application's icon. 321 * 322 * @param value from 0 to 100, other to disable progress indication 323 */ 324 public void setProgressValue(int value) { 325 checkFeatureSupport(Feature.PROGRESS_VALUE); 326 peer.setProgressValue(value); 327 } 328 329 /** 330 * Displays progress for specified window. 331 * 332 * @param w window to update 333 * @param value from 0 to 100, other to disable progress indication 334 */ 335 public void setWindowProgressValue(Window w, int value) { 336 checkFeatureSupport(Feature.PROGRESS_VALUE_WINDOW); 337 if (w != null) { 338 peer.setWindowProgressValue(w, value); 339 } 340 } 341 342 /** 343 * Sets a progress state for a specified window. 344 * 345 * @param w window 346 * @param state to change to 347 * @see #STATE_OFF 348 * @see #STATE_NORMAL 349 * @see #STATE_PAUSED 350 * @see #STATE_INDETERMINATE 351 * @see #STATE_ERROR 352 */ 353 public void setWindowProgressState(Window w, int state) { 354 checkFeatureSupport(Feature.PROGRESS_STATE_WINDOW); 355 if (state < STATE_OFF && state > STATE_ERROR) { 356 throw new IllegalArgumentException("Invalid state value"); 357 } 358 if (w != null) { 359 peer.setWindowProgressState(w, state); 360 } 361 } 362 363 private native void initIDs(); 364 365 }