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