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