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