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 = (String)java.security.AccessController.doPrivileged(
710 new java.security.PrivilegedAction() {
711 public Object 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() {
864 public Object 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 sun.security.action.LoadLibraryAction("awt"));
1650 loaded = true;
1651 }
1652 }
1653
1654 static {
1655 java.security.AccessController.doPrivileged(
1656 new java.security.PrivilegedAction() {
1657 public Object run() {
1658 try {
1659 resources =
1660 ResourceBundle.getBundle("sun.awt.resources.awt",
1661 CoreResourceBundleControl.getRBControlInstance());
1662 } catch (MissingResourceException e) {
1663 // No resource file; defaults will be used.
1664 }
1665 return null;
1666 }
1667 });
1668
1669 // ensure that the proper libraries are loaded
1670 loadLibraries();
1671 initAssistiveTechnologies();
1672 if (!GraphicsEnvironment.isHeadless()) {
1673 initIDs();
1674 }
1675 }
1676
1677 /**
1678 * Gets a property with the specified key and default.
1679 * This method returns defaultValue if the property is not found.
1680 */
1681 public static String getProperty(String key, String defaultValue) {
1682 if (resources != null) {
1683 try {
1684 return resources.getString(key);
1685 }
1686 catch (MissingResourceException e) {}
1687 }
1688
1689 return defaultValue;
1690 }
1691
1692 /**
1693 * Get the application's or applet's EventQueue instance.
1694 * Depending on the Toolkit implementation, different EventQueues
1695 * may be returned for different applets. Applets should
1696 * therefore not assume that the EventQueue instance returned
1697 * by this method will be shared by other applets or the system.
1698 *
1699 * <p>First, if there is a security manager, its
1700 * <code>checkAwtEventQueueAccess</code>
1701 * method is called.
1702 * If the default implementation of <code>checkAwtEventQueueAccess</code>
1703 * is used (that is, that method is not overriden), then this results in
1704 * a call to the security manager's <code>checkPermission</code> method
1705 * with an <code>AWTPermission("accessEventQueue")</code> permission.
1706 *
1707 * @return the <code>EventQueue</code> object
1708 * @throws SecurityException
1709 * if a security manager exists and its <code>{@link
1710 * java.lang.SecurityManager#checkAwtEventQueueAccess}</code>
1711 * method denies access to the <code>EventQueue</code>
1712 * @see java.awt.AWTPermission
1713 */
1714 public final EventQueue getSystemEventQueue() {
1715 SecurityManager security = System.getSecurityManager();
1716 if (security != null) {
1717 security.checkAwtEventQueueAccess();
1718 }
1719 return getSystemEventQueueImpl();
1720 }
1721
1722 /**
1723 * Gets the application's or applet's <code>EventQueue</code>
1724 * instance, without checking access. For security reasons,
1725 * this can only be called from a <code>Toolkit</code> subclass.
1726 * @return the <code>EventQueue</code> object
1727 */
1728 protected abstract EventQueue getSystemEventQueueImpl();
1729
1730 /* Accessor method for use by AWT package routines. */
1731 static EventQueue getEventQueue() {
1732 return getDefaultToolkit().getSystemEventQueueImpl();
1733 }
1734
1735 /**
1736 * Creates the peer for a DragSourceContext.
1737 * Always throws InvalidDndOperationException if
1738 * GraphicsEnvironment.isHeadless() returns true.
1739 * @see java.awt.GraphicsEnvironment#isHeadless
1740 */
1741 public abstract DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException;
1742
1743 /**
1744 * Creates a concrete, platform dependent, subclass of the abstract
1745 * DragGestureRecognizer class requested, and associates it with the
1746 * DragSource, Component and DragGestureListener specified.
1747 *
1748 * subclasses should override this to provide their own implementation
1749 *
1750 * @param abstractRecognizerClass The abstract class of the required recognizer
1751 * @param ds The DragSource
1752 * @param c The Component target for the DragGestureRecognizer
1753 * @param srcActions The actions permitted for the gesture
1754 * @param dgl The DragGestureListener
1755 *
1756 * @return the new object or null. Always returns null if
1757 * GraphicsEnvironment.isHeadless() returns true.
1758 * @see java.awt.GraphicsEnvironment#isHeadless
1759 */
1760 public <T extends DragGestureRecognizer> T
1761 createDragGestureRecognizer(Class<T> abstractRecognizerClass,
1762 DragSource ds, Component c, int srcActions,
1763 DragGestureListener dgl)
1764 {
1765 return null;
1766 }
1767
1768 /**
1769 * Obtains a value for the specified desktop property.
1770 *
1771 * A desktop property is a uniquely named value for a resource that
1772 * is Toolkit global in nature. Usually it also is an abstract
1773 * representation for an underlying platform dependent desktop setting.
1774 * For more information on desktop properties supported by the AWT see
1775 * <a href="doc-files/DesktopProperties.html">AWT Desktop Properties</a>.
1776 */
1777 public final synchronized Object getDesktopProperty(String propertyName) {
1778 // This is a workaround for headless toolkits. It would be
1779 // better to override this method but it is declared final.
1780 // "this instanceof" syntax defeats polymorphism.
1781 // --mm, 03/03/00
1782 if (this instanceof HeadlessToolkit) {
1783 return ((HeadlessToolkit)this).getUnderlyingToolkit()
1784 .getDesktopProperty(propertyName);
1785 }
1786
1787 if (desktopProperties.isEmpty()) {
1788 initializeDesktopProperties();
1789 }
1790
1791 Object value;
1792
1793 // This property should never be cached
1794 if (propertyName.equals("awt.dynamicLayoutSupported")) {
1795 value = lazilyLoadDesktopProperty(propertyName);
1796 return value;
1797 }
1798
1799 value = desktopProperties.get(propertyName);
1800
1801 if (value == null) {
1802 value = lazilyLoadDesktopProperty(propertyName);
1803
1804 if (value != null) {
1805 setDesktopProperty(propertyName, value);
1806 }
1807 }
1808
1809 /* for property "awt.font.desktophints" */
1810 if (value instanceof RenderingHints) {
1811 value = ((RenderingHints)value).clone();
1812 }
1813
1814 return value;
1815 }
1816
1817 /**
1818 * Sets the named desktop property to the specified value and fires a
1819 * property change event to notify any listeners that the value has changed.
1820 */
1821 protected final void setDesktopProperty(String name, Object newValue) {
1822 // This is a workaround for headless toolkits. It would be
1823 // better to override this method but it is declared final.
1824 // "this instanceof" syntax defeats polymorphism.
1825 // --mm, 03/03/00
1826 if (this instanceof HeadlessToolkit) {
1827 ((HeadlessToolkit)this).getUnderlyingToolkit()
1828 .setDesktopProperty(name, newValue);
1829 return;
1830 }
1831 Object oldValue;
1832
1833 synchronized (this) {
1834 oldValue = desktopProperties.get(name);
1835 desktopProperties.put(name, newValue);
1836 }
1837
1838 // Don't fire change event if old and new values are null.
1839 // It helps to avoid recursive resending of WM_THEMECHANGED
1840 if (oldValue != null || newValue != null) {
1841 desktopPropsSupport.firePropertyChange(name, oldValue, newValue);
1842 }
1843 }
1844
1845 /**
1846 * an opportunity to lazily evaluate desktop property values.
1847 */
1848 protected Object lazilyLoadDesktopProperty(String name) {
1849 return null;
1850 }
1851
1852 /**
1853 * initializeDesktopProperties
1854 */
1855 protected void initializeDesktopProperties() {
1856 }
1857
1858 /**
1859 * Adds the specified property change listener for the named desktop
1860 * property. When a {@link java.beans.PropertyChangeListenerProxy} object is added,
1861 * its property name is ignored, and the wrapped listener is added.
1862 * If {@code name} is {@code null} or {@code pcl} is {@code null},
1863 * no exception is thrown and no action is performed.
1864 *
1865 * @param name The name of the property to listen for
1866 * @param pcl The property change listener
1867 * @see PropertyChangeSupport#addPropertyChangeListener(String,
1868 PropertyChangeListener)
1869 * @since 1.2
1870 */
1871 public void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
1872 desktopPropsSupport.addPropertyChangeListener(name, pcl);
1873 }
1874
1875 /**
1876 * Removes the specified property change listener for the named
1877 * desktop property. When a {@link java.beans.PropertyChangeListenerProxy} object
1878 * is removed, its property name is ignored, and
1879 * the wrapped listener is removed.
1880 * If {@code name} is {@code null} or {@code pcl} is {@code null},
1881 * no exception is thrown and no action is performed.
1882 *
1883 * @param name The name of the property to remove
1884 * @param pcl The property change listener
1885 * @see PropertyChangeSupport#removePropertyChangeListener(String,
1886 PropertyChangeListener)
1887 * @since 1.2
1888 */
1889 public void removePropertyChangeListener(String name, PropertyChangeListener pcl) {
1890 desktopPropsSupport.removePropertyChangeListener(name, pcl);
1891 }
1892
1893 /**
1894 * Returns an array of all the property change listeners
1895 * registered on this toolkit. The returned array
1896 * contains {@link java.beans.PropertyChangeListenerProxy} objects
1897 * that associate listeners with the names of desktop properties.
1898 *
1899 * @return all of this toolkit's {@link PropertyChangeListener}
1900 * objects wrapped in {@code java.beans.PropertyChangeListenerProxy} objects
1901 * or an empty array if no listeners are added
1902 *
1903 * @see PropertyChangeSupport#getPropertyChangeListeners()
1904 * @since 1.4
1905 */
1906 public PropertyChangeListener[] getPropertyChangeListeners() {
1907 return desktopPropsSupport.getPropertyChangeListeners();
1908 }
1909
1910 /**
1911 * Returns an array of all property change listeners
1912 * associated with the specified name of a desktop property.
1913 *
1914 * @param propertyName the named property
1915 * @return all of the {@code PropertyChangeListener} objects
1916 * associated with the specified name of a desktop property
1917 * or an empty array if no such listeners are added
1918 *
1919 * @see PropertyChangeSupport#getPropertyChangeListeners(String)
1920 * @since 1.4
1921 */
1922 public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
1923 return desktopPropsSupport.getPropertyChangeListeners(propertyName);
1924 }
1925
1926 protected final Map<String,Object> desktopProperties =
1927 new HashMap<String,Object>();
1928 protected final PropertyChangeSupport desktopPropsSupport =
1929 Toolkit.createPropertyChangeSupport(this);
1930
1931 /**
1932 * Returns whether the always-on-top mode is supported by this toolkit.
1933 * To detect whether the always-on-top mode is supported for a
1934 * particular Window, use {@link Window#isAlwaysOnTopSupported}.
1935 * @return <code>true</code>, if current toolkit supports the always-on-top mode,
1936 * otherwise returns <code>false</code>
1937 * @see Window#isAlwaysOnTopSupported
1938 * @see Window#setAlwaysOnTop(boolean)
1939 * @since 1.6
1940 */
1941 public boolean isAlwaysOnTopSupported() {
1942 return true;
1943 }
1944
1945 /**
1946 * Returns whether the given modality type is supported by this toolkit. If
1947 * a dialog with unsupported modality type is created, then
1948 * <code>Dialog.ModalityType.MODELESS</code> is used instead.
1949 *
1950 * @param modalityType modality type to be checked for support by this toolkit
1951 *
1952 * @return <code>true</code>, if current toolkit supports given modality
1953 * type, <code>false</code> otherwise
1954 *
1955 * @see java.awt.Dialog.ModalityType
1956 * @see java.awt.Dialog#getModalityType
1957 * @see java.awt.Dialog#setModalityType
1958 *
1959 * @since 1.6
1960 */
1961 public abstract boolean isModalityTypeSupported(Dialog.ModalityType modalityType);
1962
1963 /**
1964 * Returns whether the given modal exclusion type is supported by this
1965 * toolkit. If an unsupported modal exclusion type property is set on a window,
1966 * then <code>Dialog.ModalExclusionType.NO_EXCLUDE</code> is used instead.
1967 *
1968 * @param modalExclusionType modal exclusion type to be checked for support by this toolkit
1969 *
1970 * @return <code>true</code>, if current toolkit supports given modal exclusion
1971 * type, <code>false</code> otherwise
1972 *
1973 * @see java.awt.Dialog.ModalExclusionType
1974 * @see java.awt.Window#getModalExclusionType
1975 * @see java.awt.Window#setModalExclusionType
1976 *
1977 * @since 1.6
1978 */
1979 public abstract boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType modalExclusionType);
1980
1981 private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Toolkit");
1982
1983 private static final int LONG_BITS = 64;
1984 private int[] calls = new int[LONG_BITS];
1985 private static volatile long enabledOnToolkitMask;
1986 private AWTEventListener eventListener = null;
1987 private WeakHashMap listener2SelectiveListener = new WeakHashMap();
1988
1989 /*
1990 * Extracts a "pure" AWTEventListener from a AWTEventListenerProxy,
1991 * if the listener is proxied.
1992 */
1993 static private AWTEventListener deProxyAWTEventListener(AWTEventListener l)
1994 {
1995 AWTEventListener localL = l;
1996
1997 if (localL == null) {
1998 return null;
1999 }
2000 // if user passed in a AWTEventListenerProxy object, extract
2001 // the listener
2002 if (l instanceof AWTEventListenerProxy) {
2003 localL = ((AWTEventListenerProxy)l).getListener();
2004 }
2005 return localL;
2006 }
2007
2008 /**
2009 * Adds an AWTEventListener to receive all AWTEvents dispatched
2010 * system-wide that conform to the given <code>eventMask</code>.
2011 * <p>
2012 * First, if there is a security manager, its <code>checkPermission</code>
2013 * method is called with an
2014 * <code>AWTPermission("listenToAllAWTEvents")</code> permission.
2015 * This may result in a SecurityException.
2016 * <p>
2017 * <code>eventMask</code> is a bitmask of event types to receive.
2018 * It is constructed by bitwise OR-ing together the event masks
2019 * defined in <code>AWTEvent</code>.
2020 * <p>
2021 * Note: event listener use is not recommended for normal
2022 * application use, but are intended solely to support special
2023 * purpose facilities including support for accessibility,
2024 * event record/playback, and diagnostic tracing.
2025 *
2026 * If listener is null, no exception is thrown and no action is performed.
2027 *
2028 * @param listener the event listener.
2029 * @param eventMask the bitmask of event types to receive
2030 * @throws SecurityException
2031 * if a security manager exists and its
2032 * <code>checkPermission</code> method doesn't allow the operation.
2033 * @see #removeAWTEventListener
2034 * @see #getAWTEventListeners
2035 * @see SecurityManager#checkPermission
2036 * @see java.awt.AWTEvent
2037 * @see java.awt.AWTPermission
2038 * @see java.awt.event.AWTEventListener
2039 * @see java.awt.event.AWTEventListenerProxy
2040 * @since 1.2
2041 */
2042 public void addAWTEventListener(AWTEventListener listener, long eventMask) {
2043 AWTEventListener localL = deProxyAWTEventListener(listener);
2044
2045 if (localL == null) {
2046 return;
2047 }
2048 SecurityManager security = System.getSecurityManager();
2049 if (security != null) {
2050 security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION);
2051 }
2052 synchronized (this) {
2053 SelectiveAWTEventListener selectiveListener =
2054 (SelectiveAWTEventListener)listener2SelectiveListener.get(localL);
2055
2056 if (selectiveListener == null) {
2057 // Create a new selectiveListener.
2058 selectiveListener = new SelectiveAWTEventListener(localL,
2059 eventMask);
2060 listener2SelectiveListener.put(localL, selectiveListener);
2061 eventListener = ToolkitEventMulticaster.add(eventListener,
2062 selectiveListener);
2063 }
2064 // OR the eventMask into the selectiveListener's event mask.
2065 selectiveListener.orEventMasks(eventMask);
2066
2067 enabledOnToolkitMask |= eventMask;
2068
2069 long mask = eventMask;
2070 for (int i=0; i<LONG_BITS; i++) {
2071 // If no bits are set, break out of loop.
2072 if (mask == 0) {
2073 break;
2074 }
2075 if ((mask & 1L) != 0) { // Always test bit 0.
2076 calls[i]++;
2077 }
2078 mask >>>= 1; // Right shift, fill with zeros on left.
2079 }
2080 }
2081 }
2082
2083 /**
2084 * Removes an AWTEventListener from receiving dispatched AWTEvents.
2085 * <p>
2086 * First, if there is a security manager, its <code>checkPermission</code>
2087 * method is called with an
2088 * <code>AWTPermission("listenToAllAWTEvents")</code> permission.
2089 * This may result in a SecurityException.
2090 * <p>
2091 * Note: event listener use is not recommended for normal
2092 * application use, but are intended solely to support special
2093 * purpose facilities including support for accessibility,
2094 * event record/playback, and diagnostic tracing.
2095 *
2096 * If listener is null, no exception is thrown and no action is performed.
2097 *
2098 * @param listener the event listener.
2099 * @throws SecurityException
2100 * if a security manager exists and its
2101 * <code>checkPermission</code> method doesn't allow the operation.
2102 * @see #addAWTEventListener
2103 * @see #getAWTEventListeners
2104 * @see SecurityManager#checkPermission
2105 * @see java.awt.AWTEvent
2106 * @see java.awt.AWTPermission
2107 * @see java.awt.event.AWTEventListener
2108 * @see java.awt.event.AWTEventListenerProxy
2109 * @since 1.2
2110 */
2111 public void removeAWTEventListener(AWTEventListener listener) {
2112 AWTEventListener localL = deProxyAWTEventListener(listener);
2113
2114 if (listener == null) {
2115 return;
2116 }
2117 SecurityManager security = System.getSecurityManager();
2118 if (security != null) {
2119 security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION);
2120 }
2121
2122 synchronized (this) {
2123 SelectiveAWTEventListener selectiveListener =
2124 (SelectiveAWTEventListener)listener2SelectiveListener.get(localL);
2125
2126 if (selectiveListener != null) {
2127 listener2SelectiveListener.remove(localL);
2128 int[] listenerCalls = selectiveListener.getCalls();
2129 for (int i=0; i<LONG_BITS; i++) {
2130 calls[i] -= listenerCalls[i];
2131 assert calls[i] >= 0: "Negative Listeners count";
2132
2133 if (calls[i] == 0) {
2134 enabledOnToolkitMask &= ~(1L<<i);
2135 }
2136 }
2137 }
2138 eventListener = ToolkitEventMulticaster.remove(eventListener,
2139 (selectiveListener == null) ? localL : selectiveListener);
2140 }
2141 }
2142
2143 static boolean enabledOnToolkit(long eventMask) {
2144 return (enabledOnToolkitMask & eventMask) != 0;
2145 }
2146
2147 synchronized int countAWTEventListeners(long eventMask) {
2148 if (log.isLoggable(PlatformLogger.FINE)) {
2149 if (eventMask == 0) {
2150 log.fine("Assertion (eventMask != 0) failed");
2151 }
2152 }
2153
2154 int ci = 0;
2155 for (; eventMask != 0; eventMask >>>= 1, ci++) {
2156 }
2157 ci--;
2158 return calls[ci];
2159 }
2160 /**
2161 * Returns an array of all the <code>AWTEventListener</code>s
2162 * registered on this toolkit.
2163 * If there is a security manager, its {@code checkPermission}
2164 * method is called with an
2165 * {@code AWTPermission("listenToAllAWTEvents")} permission.
2166 * This may result in a SecurityException.
2167 * Listeners can be returned
2168 * within <code>AWTEventListenerProxy</code> objects, which also contain
2169 * the event mask for the given listener.
2170 * Note that listener objects
2171 * added multiple times appear only once in the returned array.
2172 *
2173 * @return all of the <code>AWTEventListener</code>s or an empty
2174 * array if no listeners are currently registered
2175 * @throws SecurityException
2176 * if a security manager exists and its
2177 * <code>checkPermission</code> method doesn't allow the operation.
2178 * @see #addAWTEventListener
2179 * @see #removeAWTEventListener
2180 * @see SecurityManager#checkPermission
2181 * @see java.awt.AWTEvent
2182 * @see java.awt.AWTPermission
2183 * @see java.awt.event.AWTEventListener
2184 * @see java.awt.event.AWTEventListenerProxy
2185 * @since 1.4
2186 */
2187 public AWTEventListener[] getAWTEventListeners() {
2188 SecurityManager security = System.getSecurityManager();
2189 if (security != null) {
2190 security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION);
2191 }
2192 synchronized (this) {
2193 EventListener[] la = ToolkitEventMulticaster.getListeners(eventListener,AWTEventListener.class);
2194
2195 AWTEventListener[] ret = new AWTEventListener[la.length];
2196 for (int i = 0; i < la.length; i++) {
2197 SelectiveAWTEventListener sael = (SelectiveAWTEventListener)la[i];
2198 AWTEventListener tempL = sael.getListener();
2199 //assert tempL is not an AWTEventListenerProxy - we should
2200 // have weeded them all out
2201 // don't want to wrap a proxy inside a proxy
2202 ret[i] = new AWTEventListenerProxy(sael.getEventMask(), tempL);
2203 }
2204 return ret;
2205 }
2206 }
2207
2208 /**
2209 * Returns an array of all the <code>AWTEventListener</code>s
2210 * registered on this toolkit which listen to all of the event
2211 * types specified in the {@code eventMask} argument.
2212 * If there is a security manager, its {@code checkPermission}
2213 * method is called with an
2214 * {@code AWTPermission("listenToAllAWTEvents")} permission.
2215 * This may result in a SecurityException.
2216 * Listeners can be returned
2217 * within <code>AWTEventListenerProxy</code> objects, which also contain
2218 * the event mask for the given listener.
2219 * Note that listener objects
2220 * added multiple times appear only once in the returned array.
2221 *
2222 * @param eventMask the bitmask of event types to listen for
2223 * @return all of the <code>AWTEventListener</code>s registered
2224 * on this toolkit for the specified
2225 * event types, or an empty array if no such listeners
2226 * are currently registered
2227 * @throws SecurityException
2228 * if a security manager exists and its
2229 * <code>checkPermission</code> method doesn't allow the operation.
2230 * @see #addAWTEventListener
2231 * @see #removeAWTEventListener
2232 * @see SecurityManager#checkPermission
2233 * @see java.awt.AWTEvent
2234 * @see java.awt.AWTPermission
2235 * @see java.awt.event.AWTEventListener
2236 * @see java.awt.event.AWTEventListenerProxy
2237 * @since 1.4
2238 */
2239 public AWTEventListener[] getAWTEventListeners(long eventMask) {
2240 SecurityManager security = System.getSecurityManager();
2241 if (security != null) {
2242 security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION);
2243 }
2244 synchronized (this) {
2245 EventListener[] la = ToolkitEventMulticaster.getListeners(eventListener,AWTEventListener.class);
2246
2247 java.util.List list = new ArrayList(la.length);
2248
2249 for (int i = 0; i < la.length; i++) {
2250 SelectiveAWTEventListener sael = (SelectiveAWTEventListener)la[i];
2251 if ((sael.getEventMask() & eventMask) == eventMask) {
2252 //AWTEventListener tempL = sael.getListener();
2253 list.add(new AWTEventListenerProxy(sael.getEventMask(),
2254 sael.getListener()));
2255 }
2256 }
2257 return (AWTEventListener[])list.toArray(new AWTEventListener[0]);
2258 }
2259 }
2260
2261 /*
2262 * This method notifies any AWTEventListeners that an event
2263 * is about to be dispatched.
2264 *
2265 * @param theEvent the event which will be dispatched.
2266 */
2267 void notifyAWTEventListeners(AWTEvent theEvent) {
2268 // This is a workaround for headless toolkits. It would be
2269 // better to override this method but it is declared package private.
2270 // "this instanceof" syntax defeats polymorphism.
2271 // --mm, 03/03/00
2272 if (this instanceof HeadlessToolkit) {
2273 ((HeadlessToolkit)this).getUnderlyingToolkit()
2274 .notifyAWTEventListeners(theEvent);
2275 return;
2276 }
2277
2278 AWTEventListener eventListener = this.eventListener;
2279 if (eventListener != null) {
2280 eventListener.eventDispatched(theEvent);
2281 }
2282 }
2283
2284 static private class ToolkitEventMulticaster extends AWTEventMulticaster
2285 implements AWTEventListener {
2286 // Implementation cloned from AWTEventMulticaster.
2287
2288 ToolkitEventMulticaster(AWTEventListener a, AWTEventListener b) {
2289 super(a, b);
2290 }
2291
2292 static AWTEventListener add(AWTEventListener a,
2293 AWTEventListener b) {
2294 if (a == null) return b;
2295 if (b == null) return a;
2296 return new ToolkitEventMulticaster(a, b);
2297 }
2298
2299 static AWTEventListener remove(AWTEventListener l,
2300 AWTEventListener oldl) {
2301 return (AWTEventListener) removeInternal(l, oldl);
2302 }
2303
2304 // #4178589: must overload remove(EventListener) to call our add()
2305 // instead of the static addInternal() so we allocate a
2306 // ToolkitEventMulticaster instead of an AWTEventMulticaster.
2307 // Note: this method is called by AWTEventListener.removeInternal(),
2308 // so its method signature must match AWTEventListener.remove().
2309 protected EventListener remove(EventListener oldl) {
2310 if (oldl == a) return b;
2311 if (oldl == b) return a;
2312 AWTEventListener a2 = (AWTEventListener)removeInternal(a, oldl);
2313 AWTEventListener b2 = (AWTEventListener)removeInternal(b, oldl);
2314 if (a2 == a && b2 == b) {
2315 return this; // it's not here
2316 }
2317 return add(a2, b2);
2318 }
2319
2320 public void eventDispatched(AWTEvent event) {
2321 ((AWTEventListener)a).eventDispatched(event);
2322 ((AWTEventListener)b).eventDispatched(event);
2323 }
2324 }
2325
2326 private class SelectiveAWTEventListener implements AWTEventListener {
2327 AWTEventListener listener;
2328 private long eventMask;
2329 // This array contains the number of times to call the eventlistener
2330 // for each event type.
2331 int[] calls = new int[Toolkit.LONG_BITS];
2332
2333 public AWTEventListener getListener() {return listener;}
2334 public long getEventMask() {return eventMask;}
2335 public int[] getCalls() {return calls;}
2336
2337 public void orEventMasks(long mask) {
2338 eventMask |= mask;
2339 // For each event bit set in mask, increment its call count.
2340 for (int i=0; i<Toolkit.LONG_BITS; i++) {
2341 // If no bits are set, break out of loop.
2342 if (mask == 0) {
2343 break;
2344 }
2345 if ((mask & 1L) != 0) { // Always test bit 0.
2346 calls[i]++;
2347 }
2348 mask >>>= 1; // Right shift, fill with zeros on left.
2349 }
2350 }
2351
2352 SelectiveAWTEventListener(AWTEventListener l, long mask) {
2353 listener = l;
2354 eventMask = mask;
2355 }
2356
2357 public void eventDispatched(AWTEvent event) {
2358 long eventBit = 0; // Used to save the bit of the event type.
2359 if (((eventBit = eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 &&
2360 event.id >= ComponentEvent.COMPONENT_FIRST &&
2361 event.id <= ComponentEvent.COMPONENT_LAST)
2362 || ((eventBit = eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 &&
2363 event.id >= ContainerEvent.CONTAINER_FIRST &&
2364 event.id <= ContainerEvent.CONTAINER_LAST)
2365 || ((eventBit = eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 &&
2366 event.id >= FocusEvent.FOCUS_FIRST &&
2367 event.id <= FocusEvent.FOCUS_LAST)
2368 || ((eventBit = eventMask & AWTEvent.KEY_EVENT_MASK) != 0 &&
2369 event.id >= KeyEvent.KEY_FIRST &&
2370 event.id <= KeyEvent.KEY_LAST)
2371 || ((eventBit = eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 &&
2372 event.id == MouseEvent.MOUSE_WHEEL)
2373 || ((eventBit = eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 &&
2374 (event.id == MouseEvent.MOUSE_MOVED ||
2375 event.id == MouseEvent.MOUSE_DRAGGED))
2376 || ((eventBit = eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 &&
2377 event.id != MouseEvent.MOUSE_MOVED &&
2378 event.id != MouseEvent.MOUSE_DRAGGED &&
2379 event.id != MouseEvent.MOUSE_WHEEL &&
2380 event.id >= MouseEvent.MOUSE_FIRST &&
2381 event.id <= MouseEvent.MOUSE_LAST)
2382 || ((eventBit = eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 &&
2383 (event.id >= WindowEvent.WINDOW_FIRST &&
2384 event.id <= WindowEvent.WINDOW_LAST))
2385 || ((eventBit = eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 &&
2386 event.id >= ActionEvent.ACTION_FIRST &&
2387 event.id <= ActionEvent.ACTION_LAST)
2388 || ((eventBit = eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0 &&
2389 event.id >= AdjustmentEvent.ADJUSTMENT_FIRST &&
2390 event.id <= AdjustmentEvent.ADJUSTMENT_LAST)
2391 || ((eventBit = eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 &&
2392 event.id >= ItemEvent.ITEM_FIRST &&
2393 event.id <= ItemEvent.ITEM_LAST)
2394 || ((eventBit = eventMask & AWTEvent.TEXT_EVENT_MASK) != 0 &&
2395 event.id >= TextEvent.TEXT_FIRST &&
2396 event.id <= TextEvent.TEXT_LAST)
2397 || ((eventBit = eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 &&
2398 event.id >= InputMethodEvent.INPUT_METHOD_FIRST &&
2399 event.id <= InputMethodEvent.INPUT_METHOD_LAST)
2400 || ((eventBit = eventMask & AWTEvent.PAINT_EVENT_MASK) != 0 &&
2401 event.id >= PaintEvent.PAINT_FIRST &&
2402 event.id <= PaintEvent.PAINT_LAST)
2403 || ((eventBit = eventMask & AWTEvent.INVOCATION_EVENT_MASK) != 0 &&
2404 event.id >= InvocationEvent.INVOCATION_FIRST &&
2405 event.id <= InvocationEvent.INVOCATION_LAST)
2406 || ((eventBit = eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
2407 event.id == HierarchyEvent.HIERARCHY_CHANGED)
2408 || ((eventBit = eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 &&
2409 (event.id == HierarchyEvent.ANCESTOR_MOVED ||
2410 event.id == HierarchyEvent.ANCESTOR_RESIZED))
2411 || ((eventBit = eventMask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0 &&
2412 event.id == WindowEvent.WINDOW_STATE_CHANGED)
2413 || ((eventBit = eventMask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0 &&
2414 (event.id == WindowEvent.WINDOW_GAINED_FOCUS ||
2415 event.id == WindowEvent.WINDOW_LOST_FOCUS))
2416 || ((eventBit = eventMask & sun.awt.SunToolkit.GRAB_EVENT_MASK) != 0 &&
2417 (event instanceof sun.awt.UngrabEvent))) {
2418 // Get the index of the call count for this event type.
2419 // Instead of using Math.log(...) we will calculate it with
2420 // bit shifts. That's what previous implementation looked like:
2421 //
2422 // int ci = (int) (Math.log(eventBit)/Math.log(2));
2423 int ci = 0;
2424 for (long eMask = eventBit; eMask != 0; eMask >>>= 1, ci++) {
2425 }
2426 ci--;
2427 // Call the listener as many times as it was added for this
2428 // event type.
2429 for (int i=0; i<calls[ci]; i++) {
2430 listener.eventDispatched(event);
2431 }
2432 }
2433 }
2434 }
2435
2436 /**
2437 * Returns a map of visual attributes for the abstract level description
2438 * of the given input method highlight, or null if no mapping is found.
2439 * The style field of the input method highlight is ignored. The map
2440 * returned is unmodifiable.
2441 * @param highlight input method highlight
2442 * @return style attribute map, or <code>null</code>
2443 * @exception HeadlessException if
2444 * <code>GraphicsEnvironment.isHeadless</code> returns true
2445 * @see java.awt.GraphicsEnvironment#isHeadless
2446 * @since 1.3
2447 */
2448 public abstract Map<java.awt.font.TextAttribute,?>
2449 mapInputMethodHighlight(InputMethodHighlight highlight)
2450 throws HeadlessException;
2451
2452 private static PropertyChangeSupport createPropertyChangeSupport(Toolkit toolkit) {
2453 if (toolkit instanceof SunToolkit || toolkit instanceof HeadlessToolkit) {
2454 return new DesktopPropertyChangeSupport(toolkit);
2455 } else {
2456 return new PropertyChangeSupport(toolkit);
2457 }
2458 }
2459
2460 private static class DesktopPropertyChangeSupport extends PropertyChangeSupport {
2461 private static final StringBuilder PROP_CHANGE_SUPPORT_KEY =
2462 new StringBuilder("desktop property change support key");
2463 private final Object source;
2464
2465 public DesktopPropertyChangeSupport(Object sourceBean) {
2466 super(sourceBean);
2467 source = sourceBean;
2468 }
2469
2470 @Override
2471 public synchronized void addPropertyChangeListener(
2472 String propertyName,
2473 PropertyChangeListener listener)
2474 {
2475 PropertyChangeSupport pcs = (PropertyChangeSupport)
2476 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2477 if (null == pcs) {
2478 pcs = new PropertyChangeSupport(source);
2479 AppContext.getAppContext().put(PROP_CHANGE_SUPPORT_KEY, pcs);
2480 }
2481 pcs.addPropertyChangeListener(propertyName, listener);
2482 }
2483
2484 @Override
2485 public synchronized void removePropertyChangeListener(
2486 String propertyName,
2487 PropertyChangeListener listener)
2488 {
2489 PropertyChangeSupport pcs = (PropertyChangeSupport)
2490 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2491 if (null != pcs) {
2492 pcs.removePropertyChangeListener(propertyName, listener);
2493 }
2494 }
2495
2496 @Override
2497 public synchronized PropertyChangeListener[] getPropertyChangeListeners()
2498 {
2499 PropertyChangeSupport pcs = (PropertyChangeSupport)
2500 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2501 if (null != pcs) {
2502 return pcs.getPropertyChangeListeners();
2503 } else {
2504 return new PropertyChangeListener[0];
2505 }
2506 }
2507
2508 @Override
2509 public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName)
2510 {
2511 PropertyChangeSupport pcs = (PropertyChangeSupport)
2512 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2513 if (null != pcs) {
2514 return pcs.getPropertyChangeListeners(propertyName);
2515 } else {
2516 return new PropertyChangeListener[0];
2517 }
2518 }
2519
2520 @Override
2521 public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
2522 PropertyChangeSupport pcs = (PropertyChangeSupport)
2523 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2524 if (null == pcs) {
2525 pcs = new PropertyChangeSupport(source);
2526 AppContext.getAppContext().put(PROP_CHANGE_SUPPORT_KEY, pcs);
2527 }
2528 pcs.addPropertyChangeListener(listener);
2529 }
2530
2531 @Override
2532 public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
2533 PropertyChangeSupport pcs = (PropertyChangeSupport)
2534 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2535 if (null != pcs) {
2536 pcs.removePropertyChangeListener(listener);
2537 }
2538 }
2539
2540 /*
2541 * we do expect that all other fireXXX() methods of java.beans.PropertyChangeSupport
2542 * use this method. If this will be changed we will need to change this class.
2543 */
2544 @Override
2545 public void firePropertyChange(final PropertyChangeEvent evt) {
2546 Object oldValue = evt.getOldValue();
2547 Object newValue = evt.getNewValue();
2548 String propertyName = evt.getPropertyName();
2549 if (oldValue != null && newValue != null && oldValue.equals(newValue)) {
2550 return;
2551 }
2552 Runnable updater = new Runnable() {
2553 public void run() {
2554 PropertyChangeSupport pcs = (PropertyChangeSupport)
2555 AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2556 if (null != pcs) {
2557 pcs.firePropertyChange(evt);
2558 }
2559 }
2560 };
2561 final AppContext currentAppContext = AppContext.getAppContext();
2562 for (AppContext appContext : AppContext.getAppContexts()) {
2563 if (null == appContext || appContext.isDisposed()) {
2564 continue;
2565 }
2566 if (currentAppContext == appContext) {
2567 updater.run();
2568 } else {
2569 final PeerEvent e = new PeerEvent(source, updater, PeerEvent.ULTIMATE_PRIORITY_EVENT);
2570 SunToolkit.postEvent(appContext, e);
2571 }
2572 }
2573 }
2574 }
2575
2576 /**
2577 * Reports whether events from extra mouse buttons are allowed to be processed and posted into
2578 * {@code EventQueue}.
2579 * <br>
2580 * To change the returned value it is necessary to set the {@code sun.awt.enableExtraMouseButtons}
2581 * property before the {@code Toolkit} class initialization. This setting could be done on the application
2582 * startup by the following command:
2583 * <pre>
2584 * java -Dsun.awt.enableExtraMouseButtons=false Application
2585 * </pre>
2586 * Alternatively, the property could be set in the application by using the following code:
2587 * <pre>
2588 * System.setProperty("sun.awt.enableExtraMouseButtons", "true");
2589 * </pre>
2590 * before the {@code Toolkit} class initialization.
2591 * If not set by the time of the {@code Toolkit} class initialization, this property will be
2592 * initialized with {@code true}.
2593 * Changing this value after the {@code Toolkit} class initialization will have no effect.
2594 * <p>
2595 * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
2596 * @return {@code true} if events from extra mouse buttons are allowed to be processed and posted;
2597 * {@code false} otherwise
2598 * @see System#getProperty(String propertyName)
2599 * @see System#setProperty(String propertyName, String value)
2600 * @see java.awt.EventQueue
2601 * @since 1.7
2602 */
2603 public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
2604 GraphicsEnvironment.checkHeadless();
2605
2606 return Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled();
2607 }
2608 }