1 /* 2 * Copyright (c) 1995, 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 java.awt.datatransfer.Clipboard; 29 import java.awt.dnd.DragGestureListener; 30 import java.awt.dnd.DragGestureRecognizer; 31 import java.awt.dnd.DragSource; 32 import java.awt.event.*; 33 import java.awt.im.InputMethodHighlight; 34 import java.awt.image.ColorModel; 35 import java.awt.image.ImageObserver; 36 import java.awt.image.ImageProducer; 37 import java.beans.PropertyChangeEvent; 38 import java.beans.PropertyChangeListener; 39 import java.beans.PropertyChangeSupport; 40 import java.io.File; 41 import java.io.FileInputStream; 42 import java.net.URL; 43 import java.util.ArrayList; 44 import java.util.EventListener; 45 import java.util.HashMap; 46 import java.util.Map; 47 import java.util.MissingResourceException; 48 import java.util.Properties; 49 import java.util.ResourceBundle; 50 import java.util.StringTokenizer; 51 import java.util.WeakHashMap; 52 53 import sun.awt.AWTAccessor; 54 import sun.awt.AWTPermissions; 55 import sun.awt.AppContext; 56 import sun.awt.HeadlessToolkit; 57 import sun.awt.PeerEvent; 58 import sun.awt.SunToolkit; 59 import sun.util.CoreResourceBundleControl; 60 61 /** 62 * This class is the abstract superclass of all actual 63 * implementations of the Abstract Window Toolkit. Subclasses of 64 * the <code>Toolkit</code> class are used to bind the various components 65 * to particular native toolkit implementations. 66 * <p> 67 * Many GUI events may be delivered to user 68 * asynchronously, if the opposite is not specified explicitly. 69 * As well as 70 * many GUI operations may be performed asynchronously. 71 * This fact means that if the state of a component is set, and then 72 * the state immediately queried, the returned value may not yet 73 * reflect the requested change. This behavior includes, but is not 74 * limited to: 75 * <ul> 76 * <li>Scrolling to a specified position. 77 * <br>For example, calling <code>ScrollPane.setScrollPosition</code> 78 * and then <code>getScrollPosition</code> may return an incorrect 79 * value if the original request has not yet been processed. 80 * 81 * <li>Moving the focus from one component to another. 82 * <br>For more information, see 83 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html#transferTiming">Timing 84 * Focus Transfers</a>, a section in 85 * <a href="http://java.sun.com/docs/books/tutorial/uiswing/">The Swing 86 * Tutorial</a>. 87 * 88 * <li>Making a top-level container visible. 89 * <br>Calling <code>setVisible(true)</code> on a <code>Window</code>, 90 * <code>Frame</code> or <code>Dialog</code> may occur 91 * asynchronously. 92 * 93 * <li>Setting the size or location of a top-level container. 94 * <br>Calls to <code>setSize</code>, <code>setBounds</code> or 95 * <code>setLocation</code> on a <code>Window</code>, 96 * <code>Frame</code> or <code>Dialog</code> are forwarded 97 * to the underlying window management system and may be 98 * ignored or modified. See {@link java.awt.Window} for 99 * more information. 100 * </ul> 101 * <p> 102 * Most applications should not call any of the methods in this 103 * class directly. The methods defined by <code>Toolkit</code> are 104 * the "glue" that joins the platform-independent classes in the 105 * <code>java.awt</code> package with their counterparts in 106 * <code>java.awt.peer</code>. Some methods defined by 107 * <code>Toolkit</code> query the native operating system directly. 108 * 109 * @author Sami Shaio 110 * @author Arthur van Hoff 111 * @author Fred Ecks 112 * @since 1.0 113 */ 114 public abstract class Toolkit { 115 116 // The following method is called by the private method 117 // <code>updateSystemColors</code> in <code>SystemColor</code>. 118 119 /** 120 * Fills in the integer array that is supplied as an argument 121 * with the current system color values. 122 * 123 * @param systemColors an integer array. 124 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 125 * returns true 126 * @see java.awt.GraphicsEnvironment#isHeadless 127 * @since 1.1 128 */ 129 protected void loadSystemColors(int[] systemColors) 130 throws HeadlessException { 131 GraphicsEnvironment.checkHeadless(); 132 } 133 134 /** 135 * Controls whether the layout of Containers is validated dynamically 136 * during resizing, or statically, after resizing is complete. 137 * Use {@code isDynamicLayoutActive()} to detect if this feature enabled 138 * in this program and is supported by this operating system 139 * and/or window manager. 140 * Note that this feature is supported not on all platforms, and 141 * conversely, that this feature cannot be turned off on some platforms. 142 * On these platforms where dynamic layout during resizing is not supported 143 * (or is always supported), setting this property has no effect. 144 * Note that this feature can be set or unset as a property of the 145 * operating system or window manager on some platforms. On such 146 * platforms, the dynamic resize property must be set at the operating 147 * system or window manager level before this method can take effect. 148 * This method does not change support or settings of the underlying 149 * operating system or 150 * window manager. The OS/WM support can be 151 * queried using getDesktopProperty("awt.dynamicLayoutSupported") method. 152 * 153 * @param dynamic If true, Containers should re-layout their 154 * components as the Container is being resized. If false, 155 * the layout will be validated after resizing is completed. 156 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 157 * returns true 158 * @see #isDynamicLayoutSet() 159 * @see #isDynamicLayoutActive() 160 * @see #getDesktopProperty(String propertyName) 161 * @see java.awt.GraphicsEnvironment#isHeadless 162 * @since 1.4 163 */ 164 public void setDynamicLayout(final boolean dynamic) 165 throws HeadlessException { 166 GraphicsEnvironment.checkHeadless(); 167 if (this != getDefaultToolkit()) { 168 getDefaultToolkit().setDynamicLayout(dynamic); 169 } 170 } 171 172 /** 173 * Returns whether the layout of Containers is validated dynamically 174 * during resizing, or statically, after resizing is complete. 175 * Note: this method returns the value that was set programmatically; 176 * it does not reflect support at the level of the operating system 177 * or window manager for dynamic layout on resizing, or the current 178 * operating system or window manager settings. The OS/WM support can 179 * be queried using getDesktopProperty("awt.dynamicLayoutSupported"). 180 * 181 * @return true if validation of Containers is done dynamically, 182 * false if validation is done after resizing is finished. 183 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 184 * returns true 185 * @see #setDynamicLayout(boolean dynamic) 186 * @see #isDynamicLayoutActive() 187 * @see #getDesktopProperty(String propertyName) 188 * @see java.awt.GraphicsEnvironment#isHeadless 189 * @since 1.4 190 */ 191 protected boolean isDynamicLayoutSet() 192 throws HeadlessException { 193 GraphicsEnvironment.checkHeadless(); 194 195 if (this != Toolkit.getDefaultToolkit()) { 196 return Toolkit.getDefaultToolkit().isDynamicLayoutSet(); 197 } else { 198 return false; 199 } 200 } 201 202 /** 203 * Returns whether dynamic layout of Containers on resize is 204 * currently active (both set in program 205 *( {@code isDynamicLayoutSet()} ) 206 *, and supported 207 * by the underlying operating system and/or window manager). 208 * If dynamic layout is currently inactive then Containers 209 * re-layout their components when resizing is completed. As a result 210 * the {@code Component.validate()} method will be invoked only 211 * once per resize. 212 * If dynamic layout is currently active then Containers 213 * re-layout their components on every native resize event and 214 * the {@code validate()} method will be invoked each time. 215 * The OS/WM support can be queried using 216 * the getDesktopProperty("awt.dynamicLayoutSupported") method. 217 * 218 * @return true if dynamic layout of Containers on resize is 219 * currently active, false otherwise. 220 * @exception HeadlessException if the GraphicsEnvironment.isHeadless() 221 * method returns true 222 * @see #setDynamicLayout(boolean dynamic) 223 * @see #isDynamicLayoutSet() 224 * @see #getDesktopProperty(String propertyName) 225 * @see java.awt.GraphicsEnvironment#isHeadless 226 * @since 1.4 227 */ 228 public boolean isDynamicLayoutActive() 229 throws HeadlessException { 230 GraphicsEnvironment.checkHeadless(); 231 232 if (this != Toolkit.getDefaultToolkit()) { 233 return Toolkit.getDefaultToolkit().isDynamicLayoutActive(); 234 } else { 235 return false; 236 } 237 } 238 239 /** 240 * Gets the size of the screen. On systems with multiple displays, the 241 * primary display is used. Multi-screen aware display dimensions are 242 * available from <code>GraphicsConfiguration</code> and 243 * <code>GraphicsDevice</code>. 244 * @return the size of this toolkit's screen, in pixels. 245 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 246 * returns true 247 * @see java.awt.GraphicsConfiguration#getBounds 248 * @see java.awt.GraphicsDevice#getDisplayMode 249 * @see java.awt.GraphicsEnvironment#isHeadless 250 */ 251 public abstract Dimension getScreenSize() 252 throws HeadlessException; 253 254 /** 255 * Returns the screen resolution in dots-per-inch. 256 * @return this toolkit's screen resolution, in dots-per-inch. 257 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 258 * returns true 259 * @see java.awt.GraphicsEnvironment#isHeadless 260 */ 261 public abstract int getScreenResolution() 262 throws HeadlessException; 263 264 /** 265 * Gets the insets of the screen. 266 * @param gc a <code>GraphicsConfiguration</code> 267 * @return the insets of this toolkit's screen, in pixels. 268 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 269 * returns true 270 * @see java.awt.GraphicsEnvironment#isHeadless 271 * @since 1.4 272 */ 273 public Insets getScreenInsets(GraphicsConfiguration gc) 274 throws HeadlessException { 275 GraphicsEnvironment.checkHeadless(); 276 if (this != Toolkit.getDefaultToolkit()) { 277 return Toolkit.getDefaultToolkit().getScreenInsets(gc); 278 } else { 279 return new Insets(0, 0, 0, 0); 280 } 281 } 282 283 /** 284 * Determines the color model of this toolkit's screen. 285 * <p> 286 * <code>ColorModel</code> is an abstract class that 287 * encapsulates the ability to translate between the 288 * pixel values of an image and its red, green, blue, 289 * and alpha components. 290 * <p> 291 * This toolkit method is called by the 292 * <code>getColorModel</code> method 293 * of the <code>Component</code> class. 294 * @return the color model of this toolkit's screen. 295 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 296 * returns true 297 * @see java.awt.GraphicsEnvironment#isHeadless 298 * @see java.awt.image.ColorModel 299 * @see java.awt.Component#getColorModel 300 */ 301 public abstract ColorModel getColorModel() 302 throws HeadlessException; 303 304 /** 305 * Returns the names of the available fonts in this toolkit.<p> 306 * For 1.1, the following font names are deprecated (the replacement 307 * name follows): 308 * <ul> 309 * <li>TimesRoman (use Serif) 310 * <li>Helvetica (use SansSerif) 311 * <li>Courier (use Monospaced) 312 * </ul><p> 313 * The ZapfDingbats fontname is also deprecated in 1.1 but the characters 314 * are defined in Unicode starting at 0x2700, and as of 1.1 Java supports 315 * those characters. 316 * @return the names of the available fonts in this toolkit. 317 * @deprecated see {@link java.awt.GraphicsEnvironment#getAvailableFontFamilyNames()} 318 * @see java.awt.GraphicsEnvironment#getAvailableFontFamilyNames() 319 */ 320 @Deprecated 321 public abstract String[] getFontList(); 322 323 /** 324 * Gets the screen device metrics for rendering of the font. 325 * @param font a font 326 * @return the screen metrics of the specified font in this toolkit 327 * @deprecated As of JDK version 1.2, replaced by the <code>Font</code> 328 * method <code>getLineMetrics</code>. 329 * @see java.awt.font.LineMetrics 330 * @see java.awt.Font#getLineMetrics 331 * @see java.awt.GraphicsEnvironment#getScreenDevices 332 */ 333 @Deprecated 334 public abstract FontMetrics getFontMetrics(Font font); 335 336 /** 337 * Synchronizes this toolkit's graphics state. Some window systems 338 * may do buffering of graphics events. 339 * <p> 340 * This method ensures that the display is up-to-date. It is useful 341 * for animation. 342 */ 343 public abstract void sync(); 344 345 /** 346 * The default toolkit. 347 */ 348 private static Toolkit toolkit; 349 350 /** 351 * Used internally by the assistive technologies functions; set at 352 * init time and used at load time 353 */ 354 private static String atNames; 355 356 /** 357 * Initializes properties related to assistive technologies. 358 * These properties are used both in the loadAssistiveProperties() 359 * function below, as well as other classes in the jdk that depend 360 * on the properties (such as the use of the screen_magnifier_present 361 * property in Java2D hardware acceleration initialization). The 362 * initialization of the properties must be done before the platform- 363 * specific Toolkit class is instantiated so that all necessary 364 * properties are set up properly before any classes dependent upon them 365 * are initialized. 366 */ 367 private static void initAssistiveTechnologies() { 368 369 // Get accessibility properties 370 final String sep = File.separator; 371 final Properties properties = new Properties(); 372 373 374 atNames = java.security.AccessController.doPrivileged( 375 new java.security.PrivilegedAction<String>() { 376 public String run() { 377 378 // Try loading the per-user accessibility properties file. 379 try { 380 File propsFile = new File( 381 System.getProperty("user.home") + 382 sep + ".accessibility.properties"); 383 FileInputStream in = 384 new FileInputStream(propsFile); 385 386 // Inputstream has been buffered in Properties class 387 properties.load(in); 388 in.close(); 389 } catch (Exception e) { 390 // Per-user accessibility properties file does not exist 391 } 392 393 // Try loading the system-wide accessibility properties 394 // file only if a per-user accessibility properties 395 // file does not exist or is empty. 396 if (properties.size() == 0) { 397 try { 398 File propsFile = new File( 399 System.getProperty("java.home") + sep + "conf" + 400 sep + "accessibility.properties"); 401 FileInputStream in = 402 new FileInputStream(propsFile); 403 404 // Inputstream has been buffered in Properties class 405 properties.load(in); 406 in.close(); 407 } catch (Exception e) { 408 // System-wide accessibility properties file does 409 // not exist; 410 } 411 } 412 413 // Get whether a screen magnifier is present. First check 414 // the system property and then check the properties file. 415 String magPresent = System.getProperty("javax.accessibility.screen_magnifier_present"); 416 if (magPresent == null) { 417 magPresent = properties.getProperty("screen_magnifier_present", null); 418 if (magPresent != null) { 419 System.setProperty("javax.accessibility.screen_magnifier_present", magPresent); 420 } 421 } 422 423 // Get the names of any assistive technolgies to load. First 424 // check the system property and then check the properties 425 // file. 426 String classNames = System.getProperty("javax.accessibility.assistive_technologies"); 427 if (classNames == null) { 428 classNames = properties.getProperty("assistive_technologies", null); 429 if (classNames != null) { 430 System.setProperty("javax.accessibility.assistive_technologies", classNames); 431 } 432 } 433 return classNames; 434 } 435 }); 436 } 437 438 /** 439 * Loads additional classes into the VM, using the property 440 * 'assistive_technologies' specified in the Sun reference 441 * implementation by a line in the 'accessibility.properties' 442 * file. The form is "assistive_technologies=..." where 443 * the "..." is a comma-separated list of assistive technology 444 * classes to load. Each class is loaded in the order given 445 * and a single instance of each is created using 446 * Class.forName(class).newInstance(). All errors are handled 447 * via an AWTError exception. 448 * 449 * <p>The assumption is made that assistive technology classes are supplied 450 * as part of INSTALLED (as opposed to: BUNDLED) extensions or specified 451 * on the class path 452 * (and therefore can be loaded using the class loader returned by 453 * a call to <code>ClassLoader.getSystemClassLoader</code>, whose 454 * delegation parent is the extension class loader for installed 455 * extensions). 456 */ 457 private static void loadAssistiveTechnologies() { 458 // Load any assistive technologies 459 if (atNames != null) { 460 ClassLoader cl = ClassLoader.getSystemClassLoader(); 461 StringTokenizer parser = new StringTokenizer(atNames," ,"); 462 String atName; 463 while (parser.hasMoreTokens()) { 464 atName = parser.nextToken(); 465 try { 466 Class<?> clazz; 467 if (cl != null) { 468 clazz = cl.loadClass(atName); 469 } else { 470 clazz = Class.forName(atName); 471 } 472 clazz.newInstance(); 473 } catch (ClassNotFoundException e) { 474 throw new AWTError("Assistive Technology not found: " 475 + atName); 476 } catch (InstantiationException e) { 477 throw new AWTError("Could not instantiate Assistive" 478 + " Technology: " + atName); 479 } catch (IllegalAccessException e) { 480 throw new AWTError("Could not access Assistive" 481 + " Technology: " + atName); 482 } catch (Exception e) { 483 throw new AWTError("Error trying to install Assistive" 484 + " Technology: " + atName + " " + e); 485 } 486 } 487 } 488 } 489 490 /** 491 * Gets the default toolkit. 492 * <p> 493 * If a system property named <code>"java.awt.headless"</code> is set 494 * to <code>true</code> then the headless implementation 495 * of <code>Toolkit</code> is used. 496 * <p> 497 * If there is no <code>"java.awt.headless"</code> or it is set to 498 * <code>false</code> and there is a system property named 499 * <code>"awt.toolkit"</code>, 500 * that property is treated as the name of a class that is a subclass 501 * of <code>Toolkit</code>; 502 * otherwise the default platform-specific implementation of 503 * <code>Toolkit</code> is used. 504 * <p> 505 * Also loads additional classes into the VM, using the property 506 * 'assistive_technologies' specified in the Sun reference 507 * implementation by a line in the 'accessibility.properties' 508 * file. The form is "assistive_technologies=..." where 509 * the "..." is a comma-separated list of assistive technology 510 * classes to load. Each class is loaded in the order given 511 * and a single instance of each is created using 512 * Class.forName(class).newInstance(). This is done just after 513 * the AWT toolkit is created. All errors are handled via an 514 * AWTError exception. 515 * @return the default toolkit. 516 * @exception AWTError if a toolkit could not be found, or 517 * if one could not be accessed or instantiated. 518 */ 519 public static synchronized Toolkit getDefaultToolkit() { 520 if (toolkit == null) { 521 java.security.AccessController.doPrivileged( 522 new java.security.PrivilegedAction<Void>() { 523 public Void run() { 524 Class<?> cls = null; 525 String nm = System.getProperty("awt.toolkit"); 526 try { 527 cls = Class.forName(nm); 528 } catch (ClassNotFoundException e) { 529 ClassLoader cl = ClassLoader.getSystemClassLoader(); 530 if (cl != null) { 531 try { 532 cls = cl.loadClass(nm); 533 } catch (final ClassNotFoundException ignored) { 534 throw new AWTError("Toolkit not found: " + nm); 535 } 536 } 537 } 538 try { 539 if (cls != null) { 540 toolkit = (Toolkit)cls.newInstance(); 541 if (GraphicsEnvironment.isHeadless()) { 542 toolkit = new HeadlessToolkit(toolkit); 543 } 544 } 545 } catch (final InstantiationException ignored) { 546 throw new AWTError("Could not instantiate Toolkit: " + nm); 547 } catch (final IllegalAccessException ignored) { 548 throw new AWTError("Could not access Toolkit: " + nm); 549 } 550 return null; 551 } 552 }); 553 loadAssistiveTechnologies(); 554 } 555 return toolkit; 556 } 557 558 /** 559 * Returns an image which gets pixel data from the specified file, 560 * whose format can be either GIF, JPEG or PNG. 561 * The underlying toolkit attempts to resolve multiple requests 562 * with the same filename to the same returned Image. 563 * <p> 564 * Since the mechanism required to facilitate this sharing of 565 * <code>Image</code> objects may continue to hold onto images 566 * that are no longer in use for an indefinite period of time, 567 * developers are encouraged to implement their own caching of 568 * images by using the {@link #createImage(java.lang.String) createImage} 569 * variant wherever available. 570 * If the image data contained in the specified file changes, 571 * the <code>Image</code> object returned from this method may 572 * still contain stale information which was loaded from the 573 * file after a prior call. 574 * Previously loaded image data can be manually discarded by 575 * calling the {@link Image#flush flush} method on the 576 * returned <code>Image</code>. 577 * <p> 578 * This method first checks if there is a security manager installed. 579 * If so, the method calls the security manager's 580 * <code>checkRead</code> method with the file specified to ensure 581 * that the access to the image is allowed. 582 * @param filename the name of a file containing pixel data 583 * in a recognized file format. 584 * @return an image which gets its pixel data from 585 * the specified file. 586 * @throws SecurityException if a security manager exists and its 587 * checkRead method doesn't allow the operation. 588 * @see #createImage(java.lang.String) 589 */ 590 public abstract Image getImage(String filename); 591 592 /** 593 * Returns an image which gets pixel data from the specified URL. 594 * The pixel data referenced by the specified URL must be in one 595 * of the following formats: GIF, JPEG or PNG. 596 * The underlying toolkit attempts to resolve multiple requests 597 * with the same URL to the same returned Image. 598 * <p> 599 * Since the mechanism required to facilitate this sharing of 600 * <code>Image</code> objects may continue to hold onto images 601 * that are no longer in use for an indefinite period of time, 602 * developers are encouraged to implement their own caching of 603 * images by using the {@link #createImage(java.net.URL) createImage} 604 * variant wherever available. 605 * If the image data stored at the specified URL changes, 606 * the <code>Image</code> object returned from this method may 607 * still contain stale information which was fetched from the 608 * URL after a prior call. 609 * Previously loaded image data can be manually discarded by 610 * calling the {@link Image#flush flush} method on the 611 * returned <code>Image</code>. 612 * <p> 613 * This method first checks if there is a security manager installed. 614 * If so, the method calls the security manager's 615 * <code>checkPermission</code> method with the 616 * url.openConnection().getPermission() permission to ensure 617 * that the access to the image is allowed. For compatibility 618 * with pre-1.2 security managers, if the access is denied with 619 * <code>FilePermission</code> or <code>SocketPermission</code>, 620 * the method throws the <code>SecurityException</code> 621 * if the corresponding 1.1-style SecurityManager.checkXXX method 622 * also denies permission. 623 * @param url the URL to use in fetching the pixel data. 624 * @return an image which gets its pixel data from 625 * the specified URL. 626 * @throws SecurityException if a security manager exists and its 627 * checkPermission method doesn't allow 628 * the operation. 629 * @see #createImage(java.net.URL) 630 */ 631 public abstract Image getImage(URL url); 632 633 /** 634 * Returns an image which gets pixel data from the specified file. 635 * The returned Image is a new object which will not be shared 636 * with any other caller of this method or its getImage variant. 637 * <p> 638 * This method first checks if there is a security manager installed. 639 * If so, the method calls the security manager's 640 * <code>checkRead</code> method with the specified file to ensure 641 * that the image creation is allowed. 642 * @param filename the name of a file containing pixel data 643 * in a recognized file format. 644 * @return an image which gets its pixel data from 645 * the specified file. 646 * @throws SecurityException if a security manager exists and its 647 * checkRead method doesn't allow the operation. 648 * @see #getImage(java.lang.String) 649 */ 650 public abstract Image createImage(String filename); 651 652 /** 653 * Returns an image which gets pixel data from the specified URL. 654 * The returned Image is a new object which will not be shared 655 * with any other caller of this method or its getImage variant. 656 * <p> 657 * This method first checks if there is a security manager installed. 658 * If so, the method calls the security manager's 659 * <code>checkPermission</code> method with the 660 * url.openConnection().getPermission() permission to ensure 661 * that the image creation is allowed. For compatibility 662 * with pre-1.2 security managers, if the access is denied with 663 * <code>FilePermission</code> or <code>SocketPermission</code>, 664 * the method throws <code>SecurityException</code> 665 * if the corresponding 1.1-style SecurityManager.checkXXX method 666 * also denies permission. 667 * @param url the URL to use in fetching the pixel data. 668 * @return an image which gets its pixel data from 669 * the specified URL. 670 * @throws SecurityException if a security manager exists and its 671 * checkPermission method doesn't allow 672 * the operation. 673 * @see #getImage(java.net.URL) 674 */ 675 public abstract Image createImage(URL url); 676 677 /** 678 * Prepares an image for rendering. 679 * <p> 680 * If the values of the width and height arguments are both 681 * <code>-1</code>, this method prepares the image for rendering 682 * on the default screen; otherwise, this method prepares an image 683 * for rendering on the default screen at the specified width and height. 684 * <p> 685 * The image data is downloaded asynchronously in another thread, 686 * and an appropriately scaled screen representation of the image is 687 * generated. 688 * <p> 689 * This method is called by components <code>prepareImage</code> 690 * methods. 691 * <p> 692 * Information on the flags returned by this method can be found 693 * with the definition of the <code>ImageObserver</code> interface. 694 695 * @param image the image for which to prepare a 696 * screen representation. 697 * @param width the width of the desired screen 698 * representation, or <code>-1</code>. 699 * @param height the height of the desired screen 700 * representation, or <code>-1</code>. 701 * @param observer the <code>ImageObserver</code> 702 * object to be notified as the 703 * image is being prepared. 704 * @return <code>true</code> if the image has already been 705 * fully prepared; <code>false</code> otherwise. 706 * @see java.awt.Component#prepareImage(java.awt.Image, 707 * java.awt.image.ImageObserver) 708 * @see java.awt.Component#prepareImage(java.awt.Image, 709 * int, int, java.awt.image.ImageObserver) 710 * @see java.awt.image.ImageObserver 711 */ 712 public abstract boolean prepareImage(Image image, int width, int height, 713 ImageObserver observer); 714 715 /** 716 * Indicates the construction status of a specified image that is 717 * being prepared for display. 718 * <p> 719 * If the values of the width and height arguments are both 720 * <code>-1</code>, this method returns the construction status of 721 * a screen representation of the specified image in this toolkit. 722 * Otherwise, this method returns the construction status of a 723 * scaled representation of the image at the specified width 724 * and height. 725 * <p> 726 * This method does not cause the image to begin loading. 727 * An application must call <code>prepareImage</code> to force 728 * the loading of an image. 729 * <p> 730 * This method is called by the component's <code>checkImage</code> 731 * methods. 732 * <p> 733 * Information on the flags returned by this method can be found 734 * with the definition of the <code>ImageObserver</code> interface. 735 * @param image the image whose status is being checked. 736 * @param width the width of the scaled version whose status is 737 * being checked, or <code>-1</code>. 738 * @param height the height of the scaled version whose status 739 * is being checked, or <code>-1</code>. 740 * @param observer the <code>ImageObserver</code> object to be 741 * notified as the image is being prepared. 742 * @return the bitwise inclusive <strong>OR</strong> of the 743 * <code>ImageObserver</code> flags for the 744 * image data that is currently available. 745 * @see java.awt.Toolkit#prepareImage(java.awt.Image, 746 * int, int, java.awt.image.ImageObserver) 747 * @see java.awt.Component#checkImage(java.awt.Image, 748 * java.awt.image.ImageObserver) 749 * @see java.awt.Component#checkImage(java.awt.Image, 750 * int, int, java.awt.image.ImageObserver) 751 * @see java.awt.image.ImageObserver 752 */ 753 public abstract int checkImage(Image image, int width, int height, 754 ImageObserver observer); 755 756 /** 757 * Creates an image with the specified image producer. 758 * @param producer the image producer to be used. 759 * @return an image with the specified image producer. 760 * @see java.awt.Image 761 * @see java.awt.image.ImageProducer 762 * @see java.awt.Component#createImage(java.awt.image.ImageProducer) 763 */ 764 public abstract Image createImage(ImageProducer producer); 765 766 /** 767 * Creates an image which decodes the image stored in the specified 768 * byte array. 769 * <p> 770 * The data must be in some image format, such as GIF or JPEG, 771 * that is supported by this toolkit. 772 * @param imagedata an array of bytes, representing 773 * image data in a supported image format. 774 * @return an image. 775 * @since 1.1 776 */ 777 public Image createImage(byte[] imagedata) { 778 return createImage(imagedata, 0, imagedata.length); 779 } 780 781 /** 782 * Creates an image which decodes the image stored in the specified 783 * byte array, and at the specified offset and length. 784 * The data must be in some image format, such as GIF or JPEG, 785 * that is supported by this toolkit. 786 * @param imagedata an array of bytes, representing 787 * image data in a supported image format. 788 * @param imageoffset the offset of the beginning 789 * of the data in the array. 790 * @param imagelength the length of the data in the array. 791 * @return an image. 792 * @since 1.1 793 */ 794 public abstract Image createImage(byte[] imagedata, 795 int imageoffset, 796 int imagelength); 797 798 /** 799 * Gets a <code>PrintJob</code> object which is the result of initiating 800 * a print operation on the toolkit's platform. 801 * <p> 802 * Each actual implementation of this method should first check if there 803 * is a security manager installed. If there is, the method should call 804 * the security manager's <code>checkPrintJobAccess</code> method to 805 * ensure initiation of a print operation is allowed. If the default 806 * implementation of <code>checkPrintJobAccess</code> is used (that is, 807 * that method is not overriden), then this results in a call to the 808 * security manager's <code>checkPermission</code> method with a <code> 809 * RuntimePermission("queuePrintJob")</code> permission. 810 * 811 * @param frame the parent of the print dialog. May not be null. 812 * @param jobtitle the title of the PrintJob. A null title is equivalent 813 * to "". 814 * @param props a Properties object containing zero or more properties. 815 * Properties are not standardized and are not consistent across 816 * implementations. Because of this, PrintJobs which require job 817 * and page control should use the version of this function which 818 * takes JobAttributes and PageAttributes objects. This object 819 * may be updated to reflect the user's job choices on exit. May 820 * be null. 821 * @return a <code>PrintJob</code> object, or <code>null</code> if the 822 * user cancelled the print job. 823 * @throws NullPointerException if frame is null 824 * @throws SecurityException if this thread is not allowed to initiate a 825 * print job request 826 * @see java.awt.GraphicsEnvironment#isHeadless 827 * @see java.awt.PrintJob 828 * @see java.lang.RuntimePermission 829 * @since 1.1 830 */ 831 public abstract PrintJob getPrintJob(Frame frame, String jobtitle, 832 Properties props); 833 834 /** 835 * Gets a <code>PrintJob</code> object which is the result of initiating 836 * a print operation on the toolkit's platform. 837 * <p> 838 * Each actual implementation of this method should first check if there 839 * is a security manager installed. If there is, the method should call 840 * the security manager's <code>checkPrintJobAccess</code> method to 841 * ensure initiation of a print operation is allowed. If the default 842 * implementation of <code>checkPrintJobAccess</code> is used (that is, 843 * that method is not overriden), then this results in a call to the 844 * security manager's <code>checkPermission</code> method with a <code> 845 * RuntimePermission("queuePrintJob")</code> permission. 846 * 847 * @param frame the parent of the print dialog. May not be null. 848 * @param jobtitle the title of the PrintJob. A null title is equivalent 849 * to "". 850 * @param jobAttributes a set of job attributes which will control the 851 * PrintJob. The attributes will be updated to reflect the user's 852 * choices as outlined in the JobAttributes documentation. May be 853 * null. 854 * @param pageAttributes a set of page attributes which will control the 855 * PrintJob. The attributes will be applied to every page in the 856 * job. The attributes will be updated to reflect the user's 857 * choices as outlined in the PageAttributes documentation. May be 858 * null. 859 * @return a <code>PrintJob</code> object, or <code>null</code> if the 860 * user cancelled the print job. 861 * @throws NullPointerException if frame is null 862 * @throws IllegalArgumentException if pageAttributes specifies differing 863 * cross feed and feed resolutions. Also if this thread has 864 * access to the file system and jobAttributes specifies 865 * print to file, and the specified destination file exists but 866 * is a directory rather than a regular file, does not exist but 867 * cannot be created, or cannot be opened for any other reason. 868 * However in the case of print to file, if a dialog is also 869 * requested to be displayed then the user will be given an 870 * opportunity to select a file and proceed with printing. 871 * The dialog will ensure that the selected output file 872 * is valid before returning from this method. 873 * @throws SecurityException if this thread is not allowed to initiate a 874 * print job request, or if jobAttributes specifies print to file, 875 * and this thread is not allowed to access the file system 876 * @see java.awt.PrintJob 877 * @see java.awt.GraphicsEnvironment#isHeadless 878 * @see java.lang.RuntimePermission 879 * @see java.awt.JobAttributes 880 * @see java.awt.PageAttributes 881 * @since 1.3 882 */ 883 public PrintJob getPrintJob(Frame frame, String jobtitle, 884 JobAttributes jobAttributes, 885 PageAttributes pageAttributes) { 886 // Override to add printing support with new job/page control classes 887 888 if (this != Toolkit.getDefaultToolkit()) { 889 return Toolkit.getDefaultToolkit().getPrintJob(frame, jobtitle, 890 jobAttributes, 891 pageAttributes); 892 } else { 893 return getPrintJob(frame, jobtitle, null); 894 } 895 } 896 897 /** 898 * Emits an audio beep depending on native system settings and hardware 899 * capabilities. 900 * @since 1.1 901 */ 902 public abstract void beep(); 903 904 /** 905 * Gets the singleton instance of the system Clipboard which interfaces 906 * with clipboard facilities provided by the native platform. This 907 * clipboard enables data transfer between Java programs and native 908 * applications which use native clipboard facilities. 909 * <p> 910 * In addition to any and all default formats text returned by the system 911 * Clipboard's <code>getTransferData()</code> method is available in the 912 * following flavors: 913 * <ul> 914 * <li>DataFlavor.stringFlavor</li> 915 * <li>DataFlavor.plainTextFlavor (<b>deprecated</b>)</li> 916 * </ul> 917 * As with <code>java.awt.datatransfer.StringSelection</code>, if the 918 * requested flavor is <code>DataFlavor.plainTextFlavor</code>, or an 919 * equivalent flavor, a Reader is returned. <b>Note:</b> The behavior of 920 * the system Clipboard's <code>getTransferData()</code> method for <code> 921 * DataFlavor.plainTextFlavor</code>, and equivalent DataFlavors, is 922 * inconsistent with the definition of <code>DataFlavor.plainTextFlavor 923 * </code>. Because of this, support for <code> 924 * DataFlavor.plainTextFlavor</code>, and equivalent flavors, is 925 * <b>deprecated</b>. 926 * <p> 927 * Each actual implementation of this method should first check if there 928 * is a security manager installed. If there is, the method should call 929 * the security manager's {@link SecurityManager#checkPermission 930 * checkPermission} method to check {@code AWTPermission("accessClipboard")}. 931 * 932 * @return the system Clipboard 933 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 934 * returns true 935 * @see java.awt.GraphicsEnvironment#isHeadless 936 * @see java.awt.datatransfer.Clipboard 937 * @see java.awt.datatransfer.StringSelection 938 * @see java.awt.datatransfer.DataFlavor#stringFlavor 939 * @see java.awt.datatransfer.DataFlavor#plainTextFlavor 940 * @see java.io.Reader 941 * @see java.awt.AWTPermission 942 * @since 1.1 943 */ 944 public abstract Clipboard getSystemClipboard() 945 throws HeadlessException; 946 947 /** 948 * Gets the singleton instance of the system selection as a 949 * <code>Clipboard</code> object. This allows an application to read and 950 * modify the current, system-wide selection. 951 * <p> 952 * An application is responsible for updating the system selection whenever 953 * the user selects text, using either the mouse or the keyboard. 954 * Typically, this is implemented by installing a 955 * <code>FocusListener</code> on all <code>Component</code>s which support 956 * text selection, and, between <code>FOCUS_GAINED</code> and 957 * <code>FOCUS_LOST</code> events delivered to that <code>Component</code>, 958 * updating the system selection <code>Clipboard</code> when the selection 959 * changes inside the <code>Component</code>. Properly updating the system 960 * selection ensures that a Java application will interact correctly with 961 * native applications and other Java applications running simultaneously 962 * on the system. Note that <code>java.awt.TextComponent</code> and 963 * <code>javax.swing.text.JTextComponent</code> already adhere to this 964 * policy. When using these classes, and their subclasses, developers need 965 * not write any additional code. 966 * <p> 967 * Some platforms do not support a system selection <code>Clipboard</code>. 968 * On those platforms, this method will return <code>null</code>. In such a 969 * case, an application is absolved from its responsibility to update the 970 * system selection <code>Clipboard</code> as described above. 971 * <p> 972 * Each actual implementation of this method should first check if there 973 * is a security manager installed. If there is, the method should call 974 * the security manager's {@link SecurityManager#checkPermission 975 * checkPermission} method to check {@code AWTPermission("accessClipboard")}. 976 * 977 * @return the system selection as a <code>Clipboard</code>, or 978 * <code>null</code> if the native platform does not support a 979 * system selection <code>Clipboard</code> 980 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 981 * returns true 982 * 983 * @see java.awt.datatransfer.Clipboard 984 * @see java.awt.event.FocusListener 985 * @see java.awt.event.FocusEvent#FOCUS_GAINED 986 * @see java.awt.event.FocusEvent#FOCUS_LOST 987 * @see TextComponent 988 * @see javax.swing.text.JTextComponent 989 * @see AWTPermission 990 * @see GraphicsEnvironment#isHeadless 991 * @since 1.4 992 */ 993 public Clipboard getSystemSelection() throws HeadlessException { 994 GraphicsEnvironment.checkHeadless(); 995 996 if (this != Toolkit.getDefaultToolkit()) { 997 return Toolkit.getDefaultToolkit().getSystemSelection(); 998 } else { 999 GraphicsEnvironment.checkHeadless(); 1000 return null; 1001 } 1002 } 1003 1004 /** 1005 * Determines which modifier key is the appropriate accelerator 1006 * key for menu shortcuts. 1007 * <p> 1008 * Menu shortcuts, which are embodied in the 1009 * <code>MenuShortcut</code> class, are handled by the 1010 * <code>MenuBar</code> class. 1011 * <p> 1012 * By default, this method returns <code>Event.CTRL_MASK</code>. 1013 * Toolkit implementations should override this method if the 1014 * <b>Control</b> key isn't the correct key for accelerators. 1015 * @return the modifier mask on the <code>Event</code> class 1016 * that is used for menu shortcuts on this toolkit. 1017 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 1018 * returns true 1019 * @see java.awt.GraphicsEnvironment#isHeadless 1020 * @see java.awt.MenuBar 1021 * @see java.awt.MenuShortcut 1022 * @since 1.1 1023 */ 1024 public int getMenuShortcutKeyMask() throws HeadlessException { 1025 GraphicsEnvironment.checkHeadless(); 1026 1027 return Event.CTRL_MASK; 1028 } 1029 1030 /** 1031 * Returns whether the given locking key on the keyboard is currently in 1032 * its "on" state. 1033 * Valid key codes are 1034 * {@link java.awt.event.KeyEvent#VK_CAPS_LOCK VK_CAPS_LOCK}, 1035 * {@link java.awt.event.KeyEvent#VK_NUM_LOCK VK_NUM_LOCK}, 1036 * {@link java.awt.event.KeyEvent#VK_SCROLL_LOCK VK_SCROLL_LOCK}, and 1037 * {@link java.awt.event.KeyEvent#VK_KANA_LOCK VK_KANA_LOCK}. 1038 * 1039 * @param keyCode the key code 1040 * @return {@code true} if the given key is currently in its "on" state; 1041 * otherwise {@code false} 1042 * @exception java.lang.IllegalArgumentException if <code>keyCode</code> 1043 * is not one of the valid key codes 1044 * @exception java.lang.UnsupportedOperationException if the host system doesn't 1045 * allow getting the state of this key programmatically, or if the keyboard 1046 * doesn't have this key 1047 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 1048 * returns true 1049 * @see java.awt.GraphicsEnvironment#isHeadless 1050 * @since 1.3 1051 */ 1052 public boolean getLockingKeyState(int keyCode) 1053 throws UnsupportedOperationException 1054 { 1055 GraphicsEnvironment.checkHeadless(); 1056 1057 if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK || 1058 keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) { 1059 throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState"); 1060 } 1061 throw new UnsupportedOperationException("Toolkit.getLockingKeyState"); 1062 } 1063 1064 /** 1065 * Sets the state of the given locking key on the keyboard. 1066 * Valid key codes are 1067 * {@link java.awt.event.KeyEvent#VK_CAPS_LOCK VK_CAPS_LOCK}, 1068 * {@link java.awt.event.KeyEvent#VK_NUM_LOCK VK_NUM_LOCK}, 1069 * {@link java.awt.event.KeyEvent#VK_SCROLL_LOCK VK_SCROLL_LOCK}, and 1070 * {@link java.awt.event.KeyEvent#VK_KANA_LOCK VK_KANA_LOCK}. 1071 * <p> 1072 * Depending on the platform, setting the state of a locking key may 1073 * involve event processing and therefore may not be immediately 1074 * observable through getLockingKeyState. 1075 * 1076 * @param keyCode the key code 1077 * @param on the state of the key 1078 * @exception java.lang.IllegalArgumentException if <code>keyCode</code> 1079 * is not one of the valid key codes 1080 * @exception java.lang.UnsupportedOperationException if the host system doesn't 1081 * allow setting the state of this key programmatically, or if the keyboard 1082 * doesn't have this key 1083 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 1084 * returns true 1085 * @see java.awt.GraphicsEnvironment#isHeadless 1086 * @since 1.3 1087 */ 1088 public void setLockingKeyState(int keyCode, boolean on) 1089 throws UnsupportedOperationException 1090 { 1091 GraphicsEnvironment.checkHeadless(); 1092 1093 if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK || 1094 keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) { 1095 throw new IllegalArgumentException("invalid key for Toolkit.setLockingKeyState"); 1096 } 1097 throw new UnsupportedOperationException("Toolkit.setLockingKeyState"); 1098 } 1099 1100 /** 1101 * Give native peers the ability to query the native container 1102 * given a native component (eg the direct parent may be lightweight). 1103 * 1104 * @param c the component to fetch the container for 1105 * @return the native container object for the component 1106 */ 1107 protected static Container getNativeContainer(Component c) { 1108 return c.getNativeContainer(); 1109 } 1110 1111 /** 1112 * Creates a new custom cursor object. 1113 * If the image to display is invalid, the cursor will be hidden (made 1114 * completely transparent), and the hotspot will be set to (0, 0). 1115 * 1116 * <p>Note that multi-frame images are invalid and may cause this 1117 * method to hang. 1118 * 1119 * @param cursor the image to display when the cursor is activated 1120 * @param hotSpot the X and Y of the large cursor's hot spot; the 1121 * hotSpot values must be less than the Dimension returned by 1122 * <code>getBestCursorSize</code> 1123 * @param name a localized description of the cursor, for Java Accessibility use 1124 * @exception IndexOutOfBoundsException if the hotSpot values are outside 1125 * the bounds of the cursor 1126 * @return the cursor created 1127 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 1128 * returns true 1129 * @see java.awt.GraphicsEnvironment#isHeadless 1130 * @since 1.2 1131 */ 1132 public Cursor createCustomCursor(Image cursor, Point hotSpot, String name) 1133 throws IndexOutOfBoundsException, HeadlessException 1134 { 1135 // Override to implement custom cursor support. 1136 if (this != Toolkit.getDefaultToolkit()) { 1137 return Toolkit.getDefaultToolkit(). 1138 createCustomCursor(cursor, hotSpot, name); 1139 } else { 1140 return new Cursor(Cursor.DEFAULT_CURSOR); 1141 } 1142 } 1143 1144 /** 1145 * Returns the supported cursor dimension which is closest to the desired 1146 * sizes. Systems which only support a single cursor size will return that 1147 * size regardless of the desired sizes. Systems which don't support custom 1148 * cursors will return a dimension of 0, 0. <p> 1149 * Note: if an image is used whose dimensions don't match a supported size 1150 * (as returned by this method), the Toolkit implementation will attempt to 1151 * resize the image to a supported size. 1152 * Since converting low-resolution images is difficult, 1153 * no guarantees are made as to the quality of a cursor image which isn't a 1154 * supported size. It is therefore recommended that this method 1155 * be called and an appropriate image used so no image conversion is made. 1156 * 1157 * @param preferredWidth the preferred cursor width the component would like 1158 * to use. 1159 * @param preferredHeight the preferred cursor height the component would like 1160 * to use. 1161 * @return the closest matching supported cursor size, or a dimension of 0,0 if 1162 * the Toolkit implementation doesn't support custom cursors. 1163 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 1164 * returns true 1165 * @see java.awt.GraphicsEnvironment#isHeadless 1166 * @since 1.2 1167 */ 1168 public Dimension getBestCursorSize(int preferredWidth, 1169 int preferredHeight) throws HeadlessException { 1170 GraphicsEnvironment.checkHeadless(); 1171 1172 // Override to implement custom cursor support. 1173 if (this != Toolkit.getDefaultToolkit()) { 1174 return Toolkit.getDefaultToolkit(). 1175 getBestCursorSize(preferredWidth, preferredHeight); 1176 } else { 1177 return new Dimension(0, 0); 1178 } 1179 } 1180 1181 /** 1182 * Returns the maximum number of colors the Toolkit supports in a custom cursor 1183 * palette.<p> 1184 * Note: if an image is used which has more colors in its palette than 1185 * the supported maximum, the Toolkit implementation will attempt to flatten the 1186 * palette to the maximum. Since converting low-resolution images is difficult, 1187 * no guarantees are made as to the quality of a cursor image which has more 1188 * colors than the system supports. It is therefore recommended that this method 1189 * be called and an appropriate image used so no image conversion is made. 1190 * 1191 * @return the maximum number of colors, or zero if custom cursors are not 1192 * supported by this Toolkit implementation. 1193 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 1194 * returns true 1195 * @see java.awt.GraphicsEnvironment#isHeadless 1196 * @since 1.2 1197 */ 1198 public int getMaximumCursorColors() throws HeadlessException { 1199 GraphicsEnvironment.checkHeadless(); 1200 1201 // Override to implement custom cursor support. 1202 if (this != Toolkit.getDefaultToolkit()) { 1203 return Toolkit.getDefaultToolkit().getMaximumCursorColors(); 1204 } else { 1205 return 0; 1206 } 1207 } 1208 1209 /** 1210 * Returns whether Toolkit supports this state for 1211 * <code>Frame</code>s. This method tells whether the <em>UI 1212 * concept</em> of, say, maximization or iconification is 1213 * supported. It will always return false for "compound" states 1214 * like <code>Frame.ICONIFIED|Frame.MAXIMIZED_VERT</code>. 1215 * In other words, the rule of thumb is that only queries with a 1216 * single frame state constant as an argument are meaningful. 1217 * <p>Note that supporting a given concept is a platform- 1218 * dependent feature. Due to native limitations the Toolkit 1219 * object may report a particular state as supported, however at 1220 * the same time the Toolkit object will be unable to apply the 1221 * state to a given frame. This circumstance has two following 1222 * consequences: 1223 * <ul> 1224 * <li>Only the return value of {@code false} for the present 1225 * method actually indicates that the given state is not 1226 * supported. If the method returns {@code true} the given state 1227 * may still be unsupported and/or unavailable for a particular 1228 * frame. 1229 * <li>The developer should consider examining the value of the 1230 * {@link java.awt.event.WindowEvent#getNewState} method of the 1231 * {@code WindowEvent} received through the {@link 1232 * java.awt.event.WindowStateListener}, rather than assuming 1233 * that the state given to the {@code setExtendedState()} method 1234 * will be definitely applied. For more information see the 1235 * documentation for the {@link Frame#setExtendedState} method. 1236 * </ul> 1237 * 1238 * @param state one of named frame state constants. 1239 * @return <code>true</code> is this frame state is supported by 1240 * this Toolkit implementation, <code>false</code> otherwise. 1241 * @exception HeadlessException 1242 * if <code>GraphicsEnvironment.isHeadless()</code> 1243 * returns <code>true</code>. 1244 * @see java.awt.Window#addWindowStateListener 1245 * @since 1.4 1246 */ 1247 public boolean isFrameStateSupported(int state) 1248 throws HeadlessException 1249 { 1250 GraphicsEnvironment.checkHeadless(); 1251 1252 if (this != Toolkit.getDefaultToolkit()) { 1253 return Toolkit.getDefaultToolkit(). 1254 isFrameStateSupported(state); 1255 } else { 1256 return (state == Frame.NORMAL); // others are not guaranteed 1257 } 1258 } 1259 1260 /** 1261 * Support for I18N: any visible strings should be stored in 1262 * sun.awt.resources.awt.properties. The ResourceBundle is stored 1263 * here, so that only one copy is maintained. 1264 */ 1265 private static ResourceBundle resources; 1266 private static ResourceBundle platformResources; 1267 1268 // called by platform toolkit 1269 private static void setPlatformResources(ResourceBundle bundle) { 1270 platformResources = bundle; 1271 } 1272 1273 /** 1274 * Initialize JNI field and method ids 1275 */ 1276 private static native void initIDs(); 1277 1278 /** 1279 * WARNING: This is a temporary workaround for a problem in the 1280 * way the AWT loads native libraries. A number of classes in the 1281 * AWT package have a native method, initIDs(), which initializes 1282 * the JNI field and method ids used in the native portion of 1283 * their implementation. 1284 * 1285 * Since the use and storage of these ids is done by the 1286 * implementation libraries, the implementation of these method is 1287 * provided by the particular AWT implementations (for example, 1288 * "Toolkit"s/Peer), such as Motif, Microsoft Windows, or Tiny. The 1289 * problem is that this means that the native libraries must be 1290 * loaded by the java.* classes, which do not necessarily know the 1291 * names of the libraries to load. A better way of doing this 1292 * would be to provide a separate library which defines java.awt.* 1293 * initIDs, and exports the relevant symbols out to the 1294 * implementation libraries. 1295 * 1296 * For now, we know it's done by the implementation, and we assume 1297 * that the name of the library is "awt". -br. 1298 * 1299 * If you change loadLibraries(), please add the change to 1300 * java.awt.image.ColorModel.loadLibraries(). Unfortunately, 1301 * classes can be loaded in java.awt.image that depend on 1302 * libawt and there is no way to call Toolkit.loadLibraries() 1303 * directly. -hung 1304 */ 1305 private static boolean loaded = false; 1306 static void loadLibraries() { 1307 if (!loaded) { 1308 java.security.AccessController.doPrivileged( 1309 new java.security.PrivilegedAction<Void>() { 1310 public Void run() { 1311 System.loadLibrary("awt"); 1312 return null; 1313 } 1314 }); 1315 loaded = true; 1316 } 1317 } 1318 1319 static { 1320 AWTAccessor.setToolkitAccessor( 1321 new AWTAccessor.ToolkitAccessor() { 1322 @Override 1323 public void setPlatformResources(ResourceBundle bundle) { 1324 Toolkit.setPlatformResources(bundle); 1325 } 1326 }); 1327 1328 java.security.AccessController.doPrivileged( 1329 new java.security.PrivilegedAction<Void>() { 1330 public Void run() { 1331 try { 1332 resources = 1333 ResourceBundle.getBundle("sun.awt.resources.awt", 1334 CoreResourceBundleControl.getRBControlInstance()); 1335 } catch (MissingResourceException e) { 1336 // No resource file; defaults will be used. 1337 } 1338 return null; 1339 } 1340 }); 1341 1342 // ensure that the proper libraries are loaded 1343 loadLibraries(); 1344 initAssistiveTechnologies(); 1345 if (!GraphicsEnvironment.isHeadless()) { 1346 initIDs(); 1347 } 1348 } 1349 1350 /** 1351 * Gets a property with the specified key and default. 1352 * This method returns defaultValue if the property is not found. 1353 * 1354 * @param key the key 1355 * @param defaultValue the default value 1356 * @return the value of the property or the default value 1357 * if the property was not found 1358 */ 1359 public static String getProperty(String key, String defaultValue) { 1360 // first try platform specific bundle 1361 if (platformResources != null) { 1362 try { 1363 return platformResources.getString(key); 1364 } 1365 catch (MissingResourceException e) {} 1366 } 1367 1368 // then shared one 1369 if (resources != null) { 1370 try { 1371 return resources.getString(key); 1372 } 1373 catch (MissingResourceException e) {} 1374 } 1375 1376 return defaultValue; 1377 } 1378 1379 /** 1380 * Get the application's or applet's EventQueue instance. 1381 * Depending on the Toolkit implementation, different EventQueues 1382 * may be returned for different applets. Applets should 1383 * therefore not assume that the EventQueue instance returned 1384 * by this method will be shared by other applets or the system. 1385 * 1386 * <p> If there is a security manager then its 1387 * {@link SecurityManager#checkPermission checkPermission} method 1388 * is called to check {@code AWTPermission("accessEventQueue")}. 1389 * 1390 * @return the <code>EventQueue</code> object 1391 * @throws SecurityException 1392 * if a security manager is set and it denies access to 1393 * the {@code EventQueue} 1394 * @see java.awt.AWTPermission 1395 */ 1396 public final EventQueue getSystemEventQueue() { 1397 SecurityManager security = System.getSecurityManager(); 1398 if (security != null) { 1399 security.checkPermission(AWTPermissions.CHECK_AWT_EVENTQUEUE_PERMISSION); 1400 } 1401 return getSystemEventQueueImpl(); 1402 } 1403 1404 /** 1405 * Gets the application's or applet's <code>EventQueue</code> 1406 * instance, without checking access. For security reasons, 1407 * this can only be called from a <code>Toolkit</code> subclass. 1408 * @return the <code>EventQueue</code> object 1409 */ 1410 protected abstract EventQueue getSystemEventQueueImpl(); 1411 1412 /* Accessor method for use by AWT package routines. */ 1413 static EventQueue getEventQueue() { 1414 return getDefaultToolkit().getSystemEventQueueImpl(); 1415 } 1416 1417 /** 1418 * Creates a concrete, platform dependent, subclass of the abstract 1419 * DragGestureRecognizer class requested, and associates it with the 1420 * DragSource, Component and DragGestureListener specified. 1421 * 1422 * subclasses should override this to provide their own implementation 1423 * 1424 * @param <T> the type of DragGestureRecognizer to create 1425 * @param abstractRecognizerClass The abstract class of the required recognizer 1426 * @param ds The DragSource 1427 * @param c The Component target for the DragGestureRecognizer 1428 * @param srcActions The actions permitted for the gesture 1429 * @param dgl The DragGestureListener 1430 * 1431 * @return the new object or null. Always returns null if 1432 * GraphicsEnvironment.isHeadless() returns true. 1433 * @see java.awt.GraphicsEnvironment#isHeadless 1434 */ 1435 public <T extends DragGestureRecognizer> T 1436 createDragGestureRecognizer(Class<T> abstractRecognizerClass, 1437 DragSource ds, Component c, int srcActions, 1438 DragGestureListener dgl) 1439 { 1440 return null; 1441 } 1442 1443 /** 1444 * Obtains a value for the specified desktop property. 1445 * 1446 * A desktop property is a uniquely named value for a resource that 1447 * is Toolkit global in nature. Usually it also is an abstract 1448 * representation for an underlying platform dependent desktop setting. 1449 * For more information on desktop properties supported by the AWT see 1450 * <a href="doc-files/DesktopProperties.html">AWT Desktop Properties</a>. 1451 * 1452 * @param propertyName the property name 1453 * @return the value for the specified desktop property 1454 */ 1455 public final synchronized Object getDesktopProperty(String propertyName) { 1456 // This is a workaround for headless toolkits. It would be 1457 // better to override this method but it is declared final. 1458 // "this instanceof" syntax defeats polymorphism. 1459 // --mm, 03/03/00 1460 if (this instanceof HeadlessToolkit) { 1461 return ((HeadlessToolkit)this).getUnderlyingToolkit() 1462 .getDesktopProperty(propertyName); 1463 } 1464 1465 if (desktopProperties.isEmpty()) { 1466 initializeDesktopProperties(); 1467 } 1468 1469 Object value; 1470 1471 // This property should never be cached 1472 if (propertyName.equals("awt.dynamicLayoutSupported")) { 1473 return getDefaultToolkit().lazilyLoadDesktopProperty(propertyName); 1474 } 1475 1476 value = desktopProperties.get(propertyName); 1477 1478 if (value == null) { 1479 value = lazilyLoadDesktopProperty(propertyName); 1480 1481 if (value != null) { 1482 setDesktopProperty(propertyName, value); 1483 } 1484 } 1485 1486 /* for property "awt.font.desktophints" */ 1487 if (value instanceof RenderingHints) { 1488 value = ((RenderingHints)value).clone(); 1489 } 1490 1491 return value; 1492 } 1493 1494 /** 1495 * Sets the named desktop property to the specified value and fires a 1496 * property change event to notify any listeners that the value has changed. 1497 * 1498 * @param name the property name 1499 * @param newValue the new property value 1500 */ 1501 protected final void setDesktopProperty(String name, Object newValue) { 1502 // This is a workaround for headless toolkits. It would be 1503 // better to override this method but it is declared final. 1504 // "this instanceof" syntax defeats polymorphism. 1505 // --mm, 03/03/00 1506 if (this instanceof HeadlessToolkit) { 1507 ((HeadlessToolkit)this).getUnderlyingToolkit() 1508 .setDesktopProperty(name, newValue); 1509 return; 1510 } 1511 Object oldValue; 1512 1513 synchronized (this) { 1514 oldValue = desktopProperties.get(name); 1515 desktopProperties.put(name, newValue); 1516 } 1517 1518 // Don't fire change event if old and new values are null. 1519 // It helps to avoid recursive resending of WM_THEMECHANGED 1520 if (oldValue != null || newValue != null) { 1521 desktopPropsSupport.firePropertyChange(name, oldValue, newValue); 1522 } 1523 } 1524 1525 /** 1526 * An opportunity to lazily evaluate desktop property values. 1527 * @return the desktop property or null 1528 * @param name the name 1529 */ 1530 protected Object lazilyLoadDesktopProperty(String name) { 1531 return null; 1532 } 1533 1534 /** 1535 * initializeDesktopProperties 1536 */ 1537 protected void initializeDesktopProperties() { 1538 } 1539 1540 /** 1541 * Adds the specified property change listener for the named desktop 1542 * property. When a {@link java.beans.PropertyChangeListenerProxy} object is added, 1543 * its property name is ignored, and the wrapped listener is added. 1544 * If {@code name} is {@code null} or {@code pcl} is {@code null}, 1545 * no exception is thrown and no action is performed. 1546 * 1547 * @param name The name of the property to listen for 1548 * @param pcl The property change listener 1549 * @see PropertyChangeSupport#addPropertyChangeListener(String, 1550 PropertyChangeListener) 1551 * @since 1.2 1552 */ 1553 public void addPropertyChangeListener(String name, PropertyChangeListener pcl) { 1554 desktopPropsSupport.addPropertyChangeListener(name, pcl); 1555 } 1556 1557 /** 1558 * Removes the specified property change listener for the named 1559 * desktop property. When a {@link java.beans.PropertyChangeListenerProxy} object 1560 * is removed, its property name is ignored, and 1561 * the wrapped listener is removed. 1562 * If {@code name} is {@code null} or {@code pcl} is {@code null}, 1563 * no exception is thrown and no action is performed. 1564 * 1565 * @param name The name of the property to remove 1566 * @param pcl The property change listener 1567 * @see PropertyChangeSupport#removePropertyChangeListener(String, 1568 PropertyChangeListener) 1569 * @since 1.2 1570 */ 1571 public void removePropertyChangeListener(String name, PropertyChangeListener pcl) { 1572 desktopPropsSupport.removePropertyChangeListener(name, pcl); 1573 } 1574 1575 /** 1576 * Returns an array of all the property change listeners 1577 * registered on this toolkit. The returned array 1578 * contains {@link java.beans.PropertyChangeListenerProxy} objects 1579 * that associate listeners with the names of desktop properties. 1580 * 1581 * @return all of this toolkit's {@link PropertyChangeListener} 1582 * objects wrapped in {@code java.beans.PropertyChangeListenerProxy} objects 1583 * or an empty array if no listeners are added 1584 * 1585 * @see PropertyChangeSupport#getPropertyChangeListeners() 1586 * @since 1.4 1587 */ 1588 public PropertyChangeListener[] getPropertyChangeListeners() { 1589 return desktopPropsSupport.getPropertyChangeListeners(); 1590 } 1591 1592 /** 1593 * Returns an array of all property change listeners 1594 * associated with the specified name of a desktop property. 1595 * 1596 * @param propertyName the named property 1597 * @return all of the {@code PropertyChangeListener} objects 1598 * associated with the specified name of a desktop property 1599 * or an empty array if no such listeners are added 1600 * 1601 * @see PropertyChangeSupport#getPropertyChangeListeners(String) 1602 * @since 1.4 1603 */ 1604 public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) { 1605 return desktopPropsSupport.getPropertyChangeListeners(propertyName); 1606 } 1607 1608 /** 1609 * The desktop properties. 1610 */ 1611 protected final Map<String,Object> desktopProperties = 1612 new HashMap<String,Object>(); 1613 /** 1614 * The desktop properties change support. 1615 */ 1616 protected final PropertyChangeSupport desktopPropsSupport = 1617 Toolkit.createPropertyChangeSupport(this); 1618 1619 /** 1620 * Returns whether the always-on-top mode is supported by this toolkit. 1621 * To detect whether the always-on-top mode is supported for a 1622 * particular Window, use {@link Window#isAlwaysOnTopSupported}. 1623 * @return <code>true</code>, if current toolkit supports the always-on-top mode, 1624 * otherwise returns <code>false</code> 1625 * @see Window#isAlwaysOnTopSupported 1626 * @see Window#setAlwaysOnTop(boolean) 1627 * @since 1.6 1628 */ 1629 public boolean isAlwaysOnTopSupported() { 1630 return true; 1631 } 1632 1633 /** 1634 * Returns whether the given modality type is supported by this toolkit. If 1635 * a dialog with unsupported modality type is created, then 1636 * <code>Dialog.ModalityType.MODELESS</code> is used instead. 1637 * 1638 * @param modalityType modality type to be checked for support by this toolkit 1639 * 1640 * @return <code>true</code>, if current toolkit supports given modality 1641 * type, <code>false</code> otherwise 1642 * 1643 * @see java.awt.Dialog.ModalityType 1644 * @see java.awt.Dialog#getModalityType 1645 * @see java.awt.Dialog#setModalityType 1646 * 1647 * @since 1.6 1648 */ 1649 public abstract boolean isModalityTypeSupported(Dialog.ModalityType modalityType); 1650 1651 /** 1652 * Returns whether the given modal exclusion type is supported by this 1653 * toolkit. If an unsupported modal exclusion type property is set on a window, 1654 * then <code>Dialog.ModalExclusionType.NO_EXCLUDE</code> is used instead. 1655 * 1656 * @param modalExclusionType modal exclusion type to be checked for support by this toolkit 1657 * 1658 * @return <code>true</code>, if current toolkit supports given modal exclusion 1659 * type, <code>false</code> otherwise 1660 * 1661 * @see java.awt.Dialog.ModalExclusionType 1662 * @see java.awt.Window#getModalExclusionType 1663 * @see java.awt.Window#setModalExclusionType 1664 * 1665 * @since 1.6 1666 */ 1667 public abstract boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType modalExclusionType); 1668 1669 // 8014718: logging has been removed from SunToolkit 1670 1671 private static final int LONG_BITS = 64; 1672 private int[] calls = new int[LONG_BITS]; 1673 private static volatile long enabledOnToolkitMask; 1674 private AWTEventListener eventListener = null; 1675 private WeakHashMap<AWTEventListener, SelectiveAWTEventListener> listener2SelectiveListener = new WeakHashMap<>(); 1676 1677 /* 1678 * Extracts a "pure" AWTEventListener from a AWTEventListenerProxy, 1679 * if the listener is proxied. 1680 */ 1681 static private AWTEventListener deProxyAWTEventListener(AWTEventListener l) 1682 { 1683 AWTEventListener localL = l; 1684 1685 if (localL == null) { 1686 return null; 1687 } 1688 // if user passed in a AWTEventListenerProxy object, extract 1689 // the listener 1690 if (l instanceof AWTEventListenerProxy) { 1691 localL = ((AWTEventListenerProxy)l).getListener(); 1692 } 1693 return localL; 1694 } 1695 1696 /** 1697 * Adds an AWTEventListener to receive all AWTEvents dispatched 1698 * system-wide that conform to the given <code>eventMask</code>. 1699 * <p> 1700 * First, if there is a security manager, its <code>checkPermission</code> 1701 * method is called with an 1702 * <code>AWTPermission("listenToAllAWTEvents")</code> permission. 1703 * This may result in a SecurityException. 1704 * <p> 1705 * <code>eventMask</code> is a bitmask of event types to receive. 1706 * It is constructed by bitwise OR-ing together the event masks 1707 * defined in <code>AWTEvent</code>. 1708 * <p> 1709 * Note: event listener use is not recommended for normal 1710 * application use, but are intended solely to support special 1711 * purpose facilities including support for accessibility, 1712 * event record/playback, and diagnostic tracing. 1713 * 1714 * If listener is null, no exception is thrown and no action is performed. 1715 * 1716 * @param listener the event listener. 1717 * @param eventMask the bitmask of event types to receive 1718 * @throws SecurityException 1719 * if a security manager exists and its 1720 * <code>checkPermission</code> method doesn't allow the operation. 1721 * @see #removeAWTEventListener 1722 * @see #getAWTEventListeners 1723 * @see SecurityManager#checkPermission 1724 * @see java.awt.AWTEvent 1725 * @see java.awt.AWTPermission 1726 * @see java.awt.event.AWTEventListener 1727 * @see java.awt.event.AWTEventListenerProxy 1728 * @since 1.2 1729 */ 1730 public void addAWTEventListener(AWTEventListener listener, long eventMask) { 1731 AWTEventListener localL = deProxyAWTEventListener(listener); 1732 1733 if (localL == null) { 1734 return; 1735 } 1736 SecurityManager security = System.getSecurityManager(); 1737 if (security != null) { 1738 security.checkPermission(AWTPermissions.ALL_AWT_EVENTS_PERMISSION); 1739 } 1740 synchronized (this) { 1741 SelectiveAWTEventListener selectiveListener = 1742 listener2SelectiveListener.get(localL); 1743 1744 if (selectiveListener == null) { 1745 // Create a new selectiveListener. 1746 selectiveListener = new SelectiveAWTEventListener(localL, 1747 eventMask); 1748 listener2SelectiveListener.put(localL, selectiveListener); 1749 eventListener = ToolkitEventMulticaster.add(eventListener, 1750 selectiveListener); 1751 } 1752 // OR the eventMask into the selectiveListener's event mask. 1753 selectiveListener.orEventMasks(eventMask); 1754 1755 enabledOnToolkitMask |= eventMask; 1756 1757 long mask = eventMask; 1758 for (int i=0; i<LONG_BITS; i++) { 1759 // If no bits are set, break out of loop. 1760 if (mask == 0) { 1761 break; 1762 } 1763 if ((mask & 1L) != 0) { // Always test bit 0. 1764 calls[i]++; 1765 } 1766 mask >>>= 1; // Right shift, fill with zeros on left. 1767 } 1768 } 1769 } 1770 1771 /** 1772 * Removes an AWTEventListener from receiving dispatched AWTEvents. 1773 * <p> 1774 * First, if there is a security manager, its <code>checkPermission</code> 1775 * method is called with an 1776 * <code>AWTPermission("listenToAllAWTEvents")</code> permission. 1777 * This may result in a SecurityException. 1778 * <p> 1779 * Note: event listener use is not recommended for normal 1780 * application use, but are intended solely to support special 1781 * purpose facilities including support for accessibility, 1782 * event record/playback, and diagnostic tracing. 1783 * 1784 * If listener is null, no exception is thrown and no action is performed. 1785 * 1786 * @param listener the event listener. 1787 * @throws SecurityException 1788 * if a security manager exists and its 1789 * <code>checkPermission</code> method doesn't allow the operation. 1790 * @see #addAWTEventListener 1791 * @see #getAWTEventListeners 1792 * @see SecurityManager#checkPermission 1793 * @see java.awt.AWTEvent 1794 * @see java.awt.AWTPermission 1795 * @see java.awt.event.AWTEventListener 1796 * @see java.awt.event.AWTEventListenerProxy 1797 * @since 1.2 1798 */ 1799 public void removeAWTEventListener(AWTEventListener listener) { 1800 AWTEventListener localL = deProxyAWTEventListener(listener); 1801 1802 if (listener == null) { 1803 return; 1804 } 1805 SecurityManager security = System.getSecurityManager(); 1806 if (security != null) { 1807 security.checkPermission(AWTPermissions.ALL_AWT_EVENTS_PERMISSION); 1808 } 1809 1810 synchronized (this) { 1811 SelectiveAWTEventListener selectiveListener = 1812 listener2SelectiveListener.get(localL); 1813 1814 if (selectiveListener != null) { 1815 listener2SelectiveListener.remove(localL); 1816 int[] listenerCalls = selectiveListener.getCalls(); 1817 for (int i=0; i<LONG_BITS; i++) { 1818 calls[i] -= listenerCalls[i]; 1819 assert calls[i] >= 0: "Negative Listeners count"; 1820 1821 if (calls[i] == 0) { 1822 enabledOnToolkitMask &= ~(1L<<i); 1823 } 1824 } 1825 } 1826 eventListener = ToolkitEventMulticaster.remove(eventListener, 1827 (selectiveListener == null) ? localL : selectiveListener); 1828 } 1829 } 1830 1831 static boolean enabledOnToolkit(long eventMask) { 1832 return (enabledOnToolkitMask & eventMask) != 0; 1833 } 1834 1835 synchronized int countAWTEventListeners(long eventMask) { 1836 int ci = 0; 1837 for (; eventMask != 0; eventMask >>>= 1, ci++) { 1838 } 1839 ci--; 1840 return calls[ci]; 1841 } 1842 /** 1843 * Returns an array of all the <code>AWTEventListener</code>s 1844 * registered on this toolkit. 1845 * If there is a security manager, its {@code checkPermission} 1846 * method is called with an 1847 * {@code AWTPermission("listenToAllAWTEvents")} permission. 1848 * This may result in a SecurityException. 1849 * Listeners can be returned 1850 * within <code>AWTEventListenerProxy</code> objects, which also contain 1851 * the event mask for the given listener. 1852 * Note that listener objects 1853 * added multiple times appear only once in the returned array. 1854 * 1855 * @return all of the <code>AWTEventListener</code>s or an empty 1856 * array if no listeners are currently registered 1857 * @throws SecurityException 1858 * if a security manager exists and its 1859 * <code>checkPermission</code> method doesn't allow the operation. 1860 * @see #addAWTEventListener 1861 * @see #removeAWTEventListener 1862 * @see SecurityManager#checkPermission 1863 * @see java.awt.AWTEvent 1864 * @see java.awt.AWTPermission 1865 * @see java.awt.event.AWTEventListener 1866 * @see java.awt.event.AWTEventListenerProxy 1867 * @since 1.4 1868 */ 1869 public AWTEventListener[] getAWTEventListeners() { 1870 SecurityManager security = System.getSecurityManager(); 1871 if (security != null) { 1872 security.checkPermission(AWTPermissions.ALL_AWT_EVENTS_PERMISSION); 1873 } 1874 synchronized (this) { 1875 EventListener[] la = ToolkitEventMulticaster.getListeners(eventListener,AWTEventListener.class); 1876 1877 AWTEventListener[] ret = new AWTEventListener[la.length]; 1878 for (int i = 0; i < la.length; i++) { 1879 SelectiveAWTEventListener sael = (SelectiveAWTEventListener)la[i]; 1880 AWTEventListener tempL = sael.getListener(); 1881 //assert tempL is not an AWTEventListenerProxy - we should 1882 // have weeded them all out 1883 // don't want to wrap a proxy inside a proxy 1884 ret[i] = new AWTEventListenerProxy(sael.getEventMask(), tempL); 1885 } 1886 return ret; 1887 } 1888 } 1889 1890 /** 1891 * Returns an array of all the <code>AWTEventListener</code>s 1892 * registered on this toolkit which listen to all of the event 1893 * types specified in the {@code eventMask} argument. 1894 * If there is a security manager, its {@code checkPermission} 1895 * method is called with an 1896 * {@code AWTPermission("listenToAllAWTEvents")} permission. 1897 * This may result in a SecurityException. 1898 * Listeners can be returned 1899 * within <code>AWTEventListenerProxy</code> objects, which also contain 1900 * the event mask for the given listener. 1901 * Note that listener objects 1902 * added multiple times appear only once in the returned array. 1903 * 1904 * @param eventMask the bitmask of event types to listen for 1905 * @return all of the <code>AWTEventListener</code>s registered 1906 * on this toolkit for the specified 1907 * event types, or an empty array if no such listeners 1908 * are currently registered 1909 * @throws SecurityException 1910 * if a security manager exists and its 1911 * <code>checkPermission</code> method doesn't allow the operation. 1912 * @see #addAWTEventListener 1913 * @see #removeAWTEventListener 1914 * @see SecurityManager#checkPermission 1915 * @see java.awt.AWTEvent 1916 * @see java.awt.AWTPermission 1917 * @see java.awt.event.AWTEventListener 1918 * @see java.awt.event.AWTEventListenerProxy 1919 * @since 1.4 1920 */ 1921 public AWTEventListener[] getAWTEventListeners(long eventMask) { 1922 SecurityManager security = System.getSecurityManager(); 1923 if (security != null) { 1924 security.checkPermission(AWTPermissions.ALL_AWT_EVENTS_PERMISSION); 1925 } 1926 synchronized (this) { 1927 EventListener[] la = ToolkitEventMulticaster.getListeners(eventListener,AWTEventListener.class); 1928 1929 java.util.List<AWTEventListenerProxy> list = new ArrayList<>(la.length); 1930 1931 for (int i = 0; i < la.length; i++) { 1932 SelectiveAWTEventListener sael = (SelectiveAWTEventListener)la[i]; 1933 if ((sael.getEventMask() & eventMask) == eventMask) { 1934 //AWTEventListener tempL = sael.getListener(); 1935 list.add(new AWTEventListenerProxy(sael.getEventMask(), 1936 sael.getListener())); 1937 } 1938 } 1939 return list.toArray(new AWTEventListener[0]); 1940 } 1941 } 1942 1943 /* 1944 * This method notifies any AWTEventListeners that an event 1945 * is about to be dispatched. 1946 * 1947 * @param theEvent the event which will be dispatched. 1948 */ 1949 void notifyAWTEventListeners(AWTEvent theEvent) { 1950 // This is a workaround for headless toolkits. It would be 1951 // better to override this method but it is declared package private. 1952 // "this instanceof" syntax defeats polymorphism. 1953 // --mm, 03/03/00 1954 if (this instanceof HeadlessToolkit) { 1955 ((HeadlessToolkit)this).getUnderlyingToolkit() 1956 .notifyAWTEventListeners(theEvent); 1957 return; 1958 } 1959 1960 AWTEventListener eventListener = this.eventListener; 1961 if (eventListener != null) { 1962 eventListener.eventDispatched(theEvent); 1963 } 1964 } 1965 1966 static private class ToolkitEventMulticaster extends AWTEventMulticaster 1967 implements AWTEventListener { 1968 // Implementation cloned from AWTEventMulticaster. 1969 1970 ToolkitEventMulticaster(AWTEventListener a, AWTEventListener b) { 1971 super(a, b); 1972 } 1973 1974 @SuppressWarnings("overloads") 1975 static AWTEventListener add(AWTEventListener a, 1976 AWTEventListener b) { 1977 if (a == null) return b; 1978 if (b == null) return a; 1979 return new ToolkitEventMulticaster(a, b); 1980 } 1981 1982 @SuppressWarnings("overloads") 1983 static AWTEventListener remove(AWTEventListener l, 1984 AWTEventListener oldl) { 1985 return (AWTEventListener) removeInternal(l, oldl); 1986 } 1987 1988 // #4178589: must overload remove(EventListener) to call our add() 1989 // instead of the static addInternal() so we allocate a 1990 // ToolkitEventMulticaster instead of an AWTEventMulticaster. 1991 // Note: this method is called by AWTEventListener.removeInternal(), 1992 // so its method signature must match AWTEventListener.remove(). 1993 protected EventListener remove(EventListener oldl) { 1994 if (oldl == a) return b; 1995 if (oldl == b) return a; 1996 AWTEventListener a2 = (AWTEventListener)removeInternal(a, oldl); 1997 AWTEventListener b2 = (AWTEventListener)removeInternal(b, oldl); 1998 if (a2 == a && b2 == b) { 1999 return this; // it's not here 2000 } 2001 return add(a2, b2); 2002 } 2003 2004 public void eventDispatched(AWTEvent event) { 2005 ((AWTEventListener)a).eventDispatched(event); 2006 ((AWTEventListener)b).eventDispatched(event); 2007 } 2008 } 2009 2010 private class SelectiveAWTEventListener implements AWTEventListener { 2011 AWTEventListener listener; 2012 private long eventMask; 2013 // This array contains the number of times to call the eventlistener 2014 // for each event type. 2015 int[] calls = new int[Toolkit.LONG_BITS]; 2016 2017 public AWTEventListener getListener() {return listener;} 2018 public long getEventMask() {return eventMask;} 2019 public int[] getCalls() {return calls;} 2020 2021 public void orEventMasks(long mask) { 2022 eventMask |= mask; 2023 // For each event bit set in mask, increment its call count. 2024 for (int i=0; i<Toolkit.LONG_BITS; i++) { 2025 // If no bits are set, break out of loop. 2026 if (mask == 0) { 2027 break; 2028 } 2029 if ((mask & 1L) != 0) { // Always test bit 0. 2030 calls[i]++; 2031 } 2032 mask >>>= 1; // Right shift, fill with zeros on left. 2033 } 2034 } 2035 2036 SelectiveAWTEventListener(AWTEventListener l, long mask) { 2037 listener = l; 2038 eventMask = mask; 2039 } 2040 2041 public void eventDispatched(AWTEvent event) { 2042 long eventBit = 0; // Used to save the bit of the event type. 2043 if (((eventBit = eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 && 2044 event.id >= ComponentEvent.COMPONENT_FIRST && 2045 event.id <= ComponentEvent.COMPONENT_LAST) 2046 || ((eventBit = eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 && 2047 event.id >= ContainerEvent.CONTAINER_FIRST && 2048 event.id <= ContainerEvent.CONTAINER_LAST) 2049 || ((eventBit = eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 && 2050 event.id >= FocusEvent.FOCUS_FIRST && 2051 event.id <= FocusEvent.FOCUS_LAST) 2052 || ((eventBit = eventMask & AWTEvent.KEY_EVENT_MASK) != 0 && 2053 event.id >= KeyEvent.KEY_FIRST && 2054 event.id <= KeyEvent.KEY_LAST) 2055 || ((eventBit = eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 && 2056 event.id == MouseEvent.MOUSE_WHEEL) 2057 || ((eventBit = eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 && 2058 (event.id == MouseEvent.MOUSE_MOVED || 2059 event.id == MouseEvent.MOUSE_DRAGGED)) 2060 || ((eventBit = eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 && 2061 event.id != MouseEvent.MOUSE_MOVED && 2062 event.id != MouseEvent.MOUSE_DRAGGED && 2063 event.id != MouseEvent.MOUSE_WHEEL && 2064 event.id >= MouseEvent.MOUSE_FIRST && 2065 event.id <= MouseEvent.MOUSE_LAST) 2066 || ((eventBit = eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 && 2067 (event.id >= WindowEvent.WINDOW_FIRST && 2068 event.id <= WindowEvent.WINDOW_LAST)) 2069 || ((eventBit = eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 && 2070 event.id >= ActionEvent.ACTION_FIRST && 2071 event.id <= ActionEvent.ACTION_LAST) 2072 || ((eventBit = eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0 && 2073 event.id >= AdjustmentEvent.ADJUSTMENT_FIRST && 2074 event.id <= AdjustmentEvent.ADJUSTMENT_LAST) 2075 || ((eventBit = eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 && 2076 event.id >= ItemEvent.ITEM_FIRST && 2077 event.id <= ItemEvent.ITEM_LAST) 2078 || ((eventBit = eventMask & AWTEvent.TEXT_EVENT_MASK) != 0 && 2079 event.id >= TextEvent.TEXT_FIRST && 2080 event.id <= TextEvent.TEXT_LAST) 2081 || ((eventBit = eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 && 2082 event.id >= InputMethodEvent.INPUT_METHOD_FIRST && 2083 event.id <= InputMethodEvent.INPUT_METHOD_LAST) 2084 || ((eventBit = eventMask & AWTEvent.PAINT_EVENT_MASK) != 0 && 2085 event.id >= PaintEvent.PAINT_FIRST && 2086 event.id <= PaintEvent.PAINT_LAST) 2087 || ((eventBit = eventMask & AWTEvent.INVOCATION_EVENT_MASK) != 0 && 2088 event.id >= InvocationEvent.INVOCATION_FIRST && 2089 event.id <= InvocationEvent.INVOCATION_LAST) 2090 || ((eventBit = eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 && 2091 event.id == HierarchyEvent.HIERARCHY_CHANGED) 2092 || ((eventBit = eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 && 2093 (event.id == HierarchyEvent.ANCESTOR_MOVED || 2094 event.id == HierarchyEvent.ANCESTOR_RESIZED)) 2095 || ((eventBit = eventMask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0 && 2096 event.id == WindowEvent.WINDOW_STATE_CHANGED) 2097 || ((eventBit = eventMask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0 && 2098 (event.id == WindowEvent.WINDOW_GAINED_FOCUS || 2099 event.id == WindowEvent.WINDOW_LOST_FOCUS)) 2100 || ((eventBit = eventMask & sun.awt.SunToolkit.GRAB_EVENT_MASK) != 0 && 2101 (event instanceof sun.awt.UngrabEvent))) { 2102 // Get the index of the call count for this event type. 2103 // Instead of using Math.log(...) we will calculate it with 2104 // bit shifts. That's what previous implementation looked like: 2105 // 2106 // int ci = (int) (Math.log(eventBit)/Math.log(2)); 2107 int ci = 0; 2108 for (long eMask = eventBit; eMask != 0; eMask >>>= 1, ci++) { 2109 } 2110 ci--; 2111 // Call the listener as many times as it was added for this 2112 // event type. 2113 for (int i=0; i<calls[ci]; i++) { 2114 listener.eventDispatched(event); 2115 } 2116 } 2117 } 2118 } 2119 2120 /** 2121 * Returns a map of visual attributes for the abstract level description 2122 * of the given input method highlight, or null if no mapping is found. 2123 * The style field of the input method highlight is ignored. The map 2124 * returned is unmodifiable. 2125 * @param highlight input method highlight 2126 * @return style attribute map, or <code>null</code> 2127 * @exception HeadlessException if 2128 * <code>GraphicsEnvironment.isHeadless</code> returns true 2129 * @see java.awt.GraphicsEnvironment#isHeadless 2130 * @since 1.3 2131 */ 2132 public abstract Map<java.awt.font.TextAttribute,?> 2133 mapInputMethodHighlight(InputMethodHighlight highlight) 2134 throws HeadlessException; 2135 2136 private static PropertyChangeSupport createPropertyChangeSupport(Toolkit toolkit) { 2137 if (toolkit instanceof SunToolkit || toolkit instanceof HeadlessToolkit) { 2138 return new DesktopPropertyChangeSupport(toolkit); 2139 } else { 2140 return new PropertyChangeSupport(toolkit); 2141 } 2142 } 2143 2144 @SuppressWarnings("serial") 2145 private static class DesktopPropertyChangeSupport extends PropertyChangeSupport { 2146 2147 private static final StringBuilder PROP_CHANGE_SUPPORT_KEY = 2148 new StringBuilder("desktop property change support key"); 2149 private final Object source; 2150 2151 public DesktopPropertyChangeSupport(Object sourceBean) { 2152 super(sourceBean); 2153 source = sourceBean; 2154 } 2155 2156 @Override 2157 public synchronized void addPropertyChangeListener( 2158 String propertyName, 2159 PropertyChangeListener listener) 2160 { 2161 PropertyChangeSupport pcs = (PropertyChangeSupport) 2162 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY); 2163 if (null == pcs) { 2164 pcs = new PropertyChangeSupport(source); 2165 AppContext.getAppContext().put(PROP_CHANGE_SUPPORT_KEY, pcs); 2166 } 2167 pcs.addPropertyChangeListener(propertyName, listener); 2168 } 2169 2170 @Override 2171 public synchronized void removePropertyChangeListener( 2172 String propertyName, 2173 PropertyChangeListener listener) 2174 { 2175 PropertyChangeSupport pcs = (PropertyChangeSupport) 2176 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY); 2177 if (null != pcs) { 2178 pcs.removePropertyChangeListener(propertyName, listener); 2179 } 2180 } 2181 2182 @Override 2183 public synchronized PropertyChangeListener[] getPropertyChangeListeners() 2184 { 2185 PropertyChangeSupport pcs = (PropertyChangeSupport) 2186 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY); 2187 if (null != pcs) { 2188 return pcs.getPropertyChangeListeners(); 2189 } else { 2190 return new PropertyChangeListener[0]; 2191 } 2192 } 2193 2194 @Override 2195 public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) 2196 { 2197 PropertyChangeSupport pcs = (PropertyChangeSupport) 2198 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY); 2199 if (null != pcs) { 2200 return pcs.getPropertyChangeListeners(propertyName); 2201 } else { 2202 return new PropertyChangeListener[0]; 2203 } 2204 } 2205 2206 @Override 2207 public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { 2208 PropertyChangeSupport pcs = (PropertyChangeSupport) 2209 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY); 2210 if (null == pcs) { 2211 pcs = new PropertyChangeSupport(source); 2212 AppContext.getAppContext().put(PROP_CHANGE_SUPPORT_KEY, pcs); 2213 } 2214 pcs.addPropertyChangeListener(listener); 2215 } 2216 2217 @Override 2218 public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { 2219 PropertyChangeSupport pcs = (PropertyChangeSupport) 2220 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY); 2221 if (null != pcs) { 2222 pcs.removePropertyChangeListener(listener); 2223 } 2224 } 2225 2226 /* 2227 * we do expect that all other fireXXX() methods of java.beans.PropertyChangeSupport 2228 * use this method. If this will be changed we will need to change this class. 2229 */ 2230 @Override 2231 public void firePropertyChange(final PropertyChangeEvent evt) { 2232 Object oldValue = evt.getOldValue(); 2233 Object newValue = evt.getNewValue(); 2234 String propertyName = evt.getPropertyName(); 2235 if (oldValue != null && newValue != null && oldValue.equals(newValue)) { 2236 return; 2237 } 2238 Runnable updater = new Runnable() { 2239 public void run() { 2240 PropertyChangeSupport pcs = (PropertyChangeSupport) 2241 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY); 2242 if (null != pcs) { 2243 pcs.firePropertyChange(evt); 2244 } 2245 } 2246 }; 2247 final AppContext currentAppContext = AppContext.getAppContext(); 2248 for (AppContext appContext : AppContext.getAppContexts()) { 2249 if (null == appContext || appContext.isDisposed()) { 2250 continue; 2251 } 2252 if (currentAppContext == appContext) { 2253 updater.run(); 2254 } else { 2255 final PeerEvent e = new PeerEvent(source, updater, PeerEvent.ULTIMATE_PRIORITY_EVENT); 2256 SunToolkit.postEvent(appContext, e); 2257 } 2258 } 2259 } 2260 } 2261 2262 /** 2263 * Reports whether events from extra mouse buttons are allowed to be processed and posted into 2264 * {@code EventQueue}. 2265 * <br> 2266 * To change the returned value it is necessary to set the {@code sun.awt.enableExtraMouseButtons} 2267 * property before the {@code Toolkit} class initialization. This setting could be done on the application 2268 * startup by the following command: 2269 * <pre> 2270 * java -Dsun.awt.enableExtraMouseButtons=false Application 2271 * </pre> 2272 * Alternatively, the property could be set in the application by using the following code: 2273 * <pre> 2274 * System.setProperty("sun.awt.enableExtraMouseButtons", "true"); 2275 * </pre> 2276 * before the {@code Toolkit} class initialization. 2277 * If not set by the time of the {@code Toolkit} class initialization, this property will be 2278 * initialized with {@code true}. 2279 * Changing this value after the {@code Toolkit} class initialization will have no effect. 2280 * 2281 * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true 2282 * @return {@code true} if events from extra mouse buttons are allowed to be processed and posted; 2283 * {@code false} otherwise 2284 * @see System#getProperty(String propertyName) 2285 * @see System#setProperty(String propertyName, String value) 2286 * @see java.awt.EventQueue 2287 * @since 1.7 2288 */ 2289 public boolean areExtraMouseButtonsEnabled() throws HeadlessException { 2290 GraphicsEnvironment.checkHeadless(); 2291 2292 return Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled(); 2293 } 2294 }