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