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