1 /* Toolkit.java -- AWT Toolkit superclass
2    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3    Free Software Foundation, Inc.
4 
5 This file is part of GNU Classpath.
6 
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11 
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING.  If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21 
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library.  Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
26 
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module.  An independent module is a module which is not derived from
34 or based on this library.  If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so.  If you do not wish to do so, delete this
37 exception statement from your version. */
38 
39 
40 package java.awt;
41 
42 import gnu.classpath.SystemProperties;
43 import gnu.java.awt.AWTUtilities;
44 import gnu.java.awt.peer.GLightweightPeer;
45 import gnu.java.awt.peer.headless.HeadlessToolkit;
46 
47 import java.awt.datatransfer.Clipboard;
48 import java.awt.dnd.DragGestureEvent;
49 import java.awt.dnd.DragGestureListener;
50 import java.awt.dnd.DragGestureRecognizer;
51 import java.awt.dnd.DragSource;
52 import java.awt.dnd.peer.DragSourceContextPeer;
53 import java.awt.event.AWTEventListener;
54 import java.awt.event.AWTEventListenerProxy;
55 import java.awt.event.KeyEvent;
56 import java.awt.font.TextAttribute;
57 import java.awt.im.InputMethodHighlight;
58 import java.awt.image.ColorModel;
59 import java.awt.image.ImageObserver;
60 import java.awt.image.ImageProducer;
61 import java.awt.peer.ButtonPeer;
62 import java.awt.peer.CanvasPeer;
63 import java.awt.peer.CheckboxMenuItemPeer;
64 import java.awt.peer.CheckboxPeer;
65 import java.awt.peer.ChoicePeer;
66 import java.awt.peer.DesktopPeer;
67 import java.awt.peer.DialogPeer;
68 import java.awt.peer.FileDialogPeer;
69 import java.awt.peer.FontPeer;
70 import java.awt.peer.FramePeer;
71 import java.awt.peer.LabelPeer;
72 import java.awt.peer.LightweightPeer;
73 import java.awt.peer.ListPeer;
74 import java.awt.peer.MenuBarPeer;
75 import java.awt.peer.MenuItemPeer;
76 import java.awt.peer.MenuPeer;
77 import java.awt.peer.MouseInfoPeer;
78 import java.awt.peer.PanelPeer;
79 import java.awt.peer.PopupMenuPeer;
80 import java.awt.peer.ScrollPanePeer;
81 import java.awt.peer.ScrollbarPeer;
82 import java.awt.peer.TextAreaPeer;
83 import java.awt.peer.TextFieldPeer;
84 import java.awt.peer.WindowPeer;
85 import java.beans.PropertyChangeListener;
86 import java.beans.PropertyChangeSupport;
87 import java.io.File;
88 import java.io.FileInputStream;
89 import java.net.URL;
90 import java.security.AccessController;
91 import java.security.PrivilegedAction;
92 import java.util.ArrayList;
93 import java.util.Hashtable;
94 import java.util.Map;
95 import java.util.Properties;
96 import java.util.StringTokenizer;
97 
98 /**
99  * The AWT system uses a set of native peer objects to implement its
100  * widgets.  These peers are provided by a peer toolkit, that is accessed
101  * via a subclass of this superclass.  The system toolkit is retrieved
102  * by the static methods <code>getDefaultToolkit</code>.  This method
103  * determines the system toolkit by examining the system property
104  * <code>awt.toolkit</code>.  That property is set to the name of the
105  * <code>Toolkit</code> subclass for the specified peer set.  If the
106  * <code>awt.toolkit</code> property is not set, then the default
107  * toolkit <code>gnu.java.awt.peer.gtk.GtkToolkit</code> is used.  This
108  * toolkit creates its peers using the GTK+ toolkit.
109  *
110  * @author Aaron M. Renn (arenn@urbanophile.com)
111  */
112 public abstract class Toolkit
113 {
114   /** The default toolkit name. */
115   private static String default_toolkit_name
116     = gnu.classpath.Configuration.default_awt_peer_toolkit;
117 
118   /**
119    * The toolkit in use.  Once we load it, we don't ever change it
120    * if the awt.toolkit property is set.
121    */
122   private static Toolkit toolkit;
123 
124   /** The toolkit properties. */
125   private static Properties props = new Properties();
126 
127   protected final Map<String,Object> desktopProperties =
128     new Hashtable<String,Object>();
129 
130   protected final PropertyChangeSupport desktopPropsSupport
131     = new PropertyChangeSupport(this);
132 
133   /**
134    * All registered AWTEventListener objects. This is package private, so the
135    * event queue can efficiently access this list.
136    */
137   AWTEventListenerProxy[] awtEventListeners;
138 
139   /**
140    * The shared peer for all lightweight components.
141    */
142   private GLightweightPeer lightweightPeer;
143 
144   /**
145    * Default constructor for subclasses.
146    */
Toolkit()147   public Toolkit()
148   {
149     awtEventListeners = new AWTEventListenerProxy[0];
150   }
151 
152   /**
153    *
154    * @param target
155    * @return
156    * @throws HeadlessException
157    */
createDesktopPeer(Desktop target)158   protected abstract DesktopPeer createDesktopPeer(Desktop target)
159     throws HeadlessException;
160 
161   /**
162    * Creates a peer object for the specified <code>Button</code>.
163    *
164    * @param target The <code>Button</code> to create the peer for.
165    *
166    * @return The peer for the specified <code>Button</code> object.
167    *
168    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
169    */
createButton(Button target)170   protected abstract ButtonPeer createButton(Button target);
171 
172   /**
173    * Creates a peer object for the specified <code>TextField</code>.
174    *
175    * @param target The <code>TextField</code> to create the peer for.
176    *
177    * @return The peer for the specified <code>TextField</code> object.
178    *
179    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
180    */
createTextField(TextField target)181   protected abstract TextFieldPeer createTextField(TextField target);
182 
183   /**
184    * Creates a peer object for the specified <code>Label</code>.
185    *
186    * @param target The <code>Label</code> to create the peer for.
187    *
188    * @return The peer for the specified <code>Label</code> object.
189    *
190    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
191    */
createLabel(Label target)192   protected abstract LabelPeer createLabel(Label target);
193 
194   /**
195    * Creates a peer object for the specified <code>List</code>.
196    *
197    * @param target The <code>List</code> to create the peer for.
198    *
199    * @return The peer for the specified <code>List</code> object.
200    *
201    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
202    */
createList(List target)203   protected abstract ListPeer createList(List target);
204 
205   /**
206    * Creates a peer object for the specified <code>Checkbox</code>.
207    *
208    * @param target The <code>Checkbox</code> to create the peer for.
209    *
210    * @return The peer for the specified <code>Checkbox</code> object.
211    *
212    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
213    */
createCheckbox(Checkbox target)214   protected abstract CheckboxPeer createCheckbox(Checkbox target);
215 
216   /**
217    * Creates a peer object for the specified <code>Scrollbar</code>.
218    *
219    * @param target The <code>Scrollbar</code> to create the peer for.
220    *
221    * @return The peer for the specified <code>Scrollbar</code> object.
222    *
223    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
224    */
createScrollbar(Scrollbar target)225   protected abstract ScrollbarPeer createScrollbar(Scrollbar target);
226 
227   /**
228    * Creates a peer object for the specified <code>ScrollPane</code>.
229    *
230    * @param target The <code>ScrollPane</code> to create the peer for.
231    *
232    * @return The peer for the specified <code>ScrollPane</code> object.
233    *
234    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
235    */
createScrollPane(ScrollPane target)236   protected abstract ScrollPanePeer createScrollPane(ScrollPane target);
237 
238   /**
239    * Creates a peer object for the specified <code>TextArea</code>.
240    *
241    * @param target The <code>TextArea</code> to create the peer for.
242    *
243    * @return The peer for the specified <code>TextArea</code> object.
244    *
245    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
246    */
createTextArea(TextArea target)247   protected abstract TextAreaPeer createTextArea(TextArea target);
248 
249   /**
250    * Creates a peer object for the specified <code>Choice</code>.
251    *
252    * @param target The <code>Choice</code> to create the peer for.
253    *
254    * @return The peer for the specified <code>Choice</code> object.
255    *
256    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
257    */
createChoice(Choice target)258   protected abstract ChoicePeer createChoice(Choice target);
259 
260   /**
261    * Creates a peer object for the specified <code>Frame</code>.
262    *
263    * @param target The <code>Frame</code> to create the peer for.
264    *
265    * @return The peer for the specified <code>Frame</code> object.
266    *
267    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
268    */
createFrame(Frame target)269   protected abstract FramePeer createFrame(Frame target);
270 
271   /**
272    * Creates a peer object for the specified <code>Canvas</code>.
273    *
274    * @param target The <code>Canvas</code> to create the peer for.
275    *
276    * @return The peer for the specified <code>Canvas</code> object.
277    */
createCanvas(Canvas target)278   protected abstract CanvasPeer createCanvas(Canvas target);
279 
280   /**
281    * Creates a peer object for the specified <code>Panel</code>.
282    *
283    * @param target The <code>Panel</code> to create the peer for.
284    *
285    * @return The peer for the specified <code>Panel</code> object.
286    */
createPanel(Panel target)287   protected abstract PanelPeer createPanel(Panel target);
288 
289   /**
290    * Creates a peer object for the specified <code>Window</code>.
291    *
292    * @param target The <code>Window</code> to create the peer for.
293    *
294    * @return The peer for the specified <code>Window</code> object.
295    *
296    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
297    */
createWindow(Window target)298   protected abstract WindowPeer createWindow(Window target);
299 
300   /**
301    * Creates a peer object for the specified <code>Dialog</code>.
302    *
303    * @param target The dialog to create the peer for
304    *
305    * @return The peer for the specified font name.
306    *
307    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
308    */
createDialog(Dialog target)309   protected abstract DialogPeer createDialog(Dialog target);
310 
311   /**
312    * Creates a peer object for the specified <code>MenuBar</code>.
313    *
314    * @param target The <code>MenuBar</code> to create the peer for.
315    *
316    * @return The peer for the specified <code>MenuBar</code> object.
317    *
318    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
319    */
createMenuBar(MenuBar target)320   protected abstract MenuBarPeer createMenuBar(MenuBar target);
321 
322   /**
323    * Creates a peer object for the specified <code>Menu</code>.
324    *
325    * @param target The <code>Menu</code> to create the peer for.
326    *
327    * @return The peer for the specified <code>Menu</code> object.
328    *
329    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
330    */
createMenu(Menu target)331   protected abstract MenuPeer createMenu(Menu target);
332 
333   /**
334    * Creates a peer object for the specified <code>PopupMenu</code>.
335    *
336    * @param target The <code>PopupMenu</code> to create the peer for.
337    *
338    * @return The peer for the specified <code>PopupMenu</code> object.
339    *
340    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
341    */
createPopupMenu(PopupMenu target)342   protected abstract PopupMenuPeer createPopupMenu(PopupMenu target);
343 
344   /**
345    * Creates a peer object for the specified <code>MenuItem</code>.
346    *
347    * @param target The <code>MenuItem</code> to create the peer for.
348    *
349    * @return The peer for the specified <code>MenuItem</code> object.
350    *
351    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
352    */
createMenuItem(MenuItem target)353   protected abstract MenuItemPeer createMenuItem(MenuItem target);
354 
355   /**
356    * Returns a MouseInfoPeer.
357    * The default implementation of this method throws
358    * UnsupportedOperationException.
359    *
360    * Toolkit implementations should overload this if possible, however.
361    */
getMouseInfoPeer()362   protected MouseInfoPeer getMouseInfoPeer()
363   {
364     throw new UnsupportedOperationException("No mouse info peer.");
365   }
366 
367   /**
368    * Creates a peer object for the specified <code>FileDialog</code>.
369    *
370    * @param target The <code>FileDialog</code> to create the peer for.
371    *
372    * @return The peer for the specified <code>FileDialog</code> object.
373    *
374    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
375    */
createFileDialog(FileDialog target)376   protected abstract FileDialogPeer createFileDialog(FileDialog target);
377 
378   /**
379    * Creates a peer object for the specified <code>CheckboxMenuItem</code>.
380    *
381    * @param target The <code>CheckboxMenuItem</code> to create the peer for.
382    *
383    * @return The peer for the specified <code>CheckboxMenuItem</code> object.
384    *
385    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
386    */
387   protected abstract CheckboxMenuItemPeer
createCheckboxMenuItem(CheckboxMenuItem target)388     createCheckboxMenuItem(CheckboxMenuItem target);
389 
390   /**
391    * Creates a peer object for the specified <code>Component</code>.  The
392    * peer returned by this method is not a native windowing system peer
393    * with its own native window.  Instead, this method allows the component
394    * to draw on its parent window as a "lightweight" widget.
395    *
396    * @param target The <code>Component</code> to create the peer for.
397    *
398    * @return The peer for the specified <code>Component</code> object.
399    */
createComponent(Component target)400   protected LightweightPeer createComponent(Component target)
401   {
402     if (lightweightPeer == null)
403       lightweightPeer = new GLightweightPeer();
404     return lightweightPeer;
405   }
406 
407   /**
408    * Creates a peer object for the specified font name.
409    *
410    * @param name The font to create the peer for.
411    * @param style The font style to create the peer for.
412    *
413    * @return The peer for the specified font name.
414    *
415    * @deprecated
416    */
getFontPeer(String name, int style)417   protected abstract FontPeer getFontPeer(String name, int style);
418 
419   /**
420    * Copies the current system colors into the specified array.  This is
421    * the interface used by the <code>SystemColor</code> class.  Although
422    * this method fills in the array with some default colors a real Toolkit
423    * should override this method and provide real system colors for the
424    * native GUI platform.
425    *
426    * @param systemColors The array to copy the system colors into.
427    * It must be at least 26 elements.
428    *
429    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
430    *
431    * @see java.awt.SystemColor
432    */
loadSystemColors(int systemColors[])433   protected void loadSystemColors(int systemColors[])
434   {
435     systemColors[SystemColor.DESKTOP]                 = 0xFF005C5C;
436     systemColors[SystemColor.ACTIVE_CAPTION]          = 0xFF000080;
437     systemColors[SystemColor.ACTIVE_CAPTION_TEXT]     = 0xFFFFFFFF;
438     systemColors[SystemColor.ACTIVE_CAPTION_BORDER]   = 0xFFC0C0C0;
439     systemColors[SystemColor.INACTIVE_CAPTION]        = 0xFF808080;
440     systemColors[SystemColor.INACTIVE_CAPTION_TEXT]   = 0xFFC0C0C0;
441     systemColors[SystemColor.INACTIVE_CAPTION_BORDER] = 0xFFC0C0C0;
442     systemColors[SystemColor.WINDOW]                  = 0xFFFFFFFF;
443     systemColors[SystemColor.WINDOW_BORDER]           = 0xFF000000;
444     systemColors[SystemColor.WINDOW_TEXT]             = 0xFF000000;
445     systemColors[SystemColor.MENU]                    = 0xFFC0C0C0;
446     systemColors[SystemColor.MENU_TEXT]               = 0xFF000000;
447     systemColors[SystemColor.TEXT]                    = 0xFFC0C0C0;
448     systemColors[SystemColor.TEXT_TEXT]               = 0xFF000000;
449     systemColors[SystemColor.TEXT_HIGHLIGHT]          = 0xFF000090;
450     systemColors[SystemColor.TEXT_HIGHLIGHT_TEXT]     = 0xFFFFFFFF;
451     systemColors[SystemColor.TEXT_INACTIVE_TEXT]      = 0xFF808080;
452     systemColors[SystemColor.CONTROL]                 = 0xFFC0C0C0;
453     systemColors[SystemColor.CONTROL_TEXT]            = 0xFF000000;
454     systemColors[SystemColor.CONTROL_HIGHLIGHT]       = 0xFFFFFFFF;
455     systemColors[SystemColor.CONTROL_LT_HIGHLIGHT]    = 0xFFE0E0E0;
456     systemColors[SystemColor.CONTROL_SHADOW]          = 0xFF808080;
457     systemColors[SystemColor.CONTROL_DK_SHADOW]       = 0xFF000000;
458     systemColors[SystemColor.SCROLLBAR]               = 0xFFE0E0E0;
459     systemColors[SystemColor.INFO]                    = 0xFFE0E000;
460     systemColors[SystemColor.INFO_TEXT]               = 0xFF000000;
461   }
462 
463   /**
464    * @since 1.4
465    *
466    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
467    */
setDynamicLayout(boolean dynamic)468   public void setDynamicLayout(boolean dynamic)
469   {
470   }
471 
472   /**
473    * @since 1.4
474    *
475    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
476    */
isDynamicLayoutSet()477   protected boolean isDynamicLayoutSet()
478   {
479     return false;
480   }
481 
482   /**
483    * @since 1.4
484    *
485    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
486    */
isDynamicLayoutActive()487   public boolean isDynamicLayoutActive()
488   {
489     return false;
490   }
491 
492   /**
493    * Returns the dimensions of the screen in pixels.
494    *
495    * @return The dimensions of the screen in pixels.
496    *
497    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
498    */
getScreenSize()499   public abstract Dimension getScreenSize();
500 
501   /**
502    * Returns the screen resolution in dots per square inch.
503    *
504    * @return The screen resolution in dots per square inch.
505    *
506    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
507    */
getScreenResolution()508   public abstract int getScreenResolution();
509 
510   /**
511    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
512    *
513    * @since 1.4
514    */
getScreenInsets(GraphicsConfiguration gc)515   public Insets getScreenInsets(GraphicsConfiguration gc)
516   {
517     return new Insets(0, 0, 0, 0);
518   }
519 
520   /**
521    * Returns the color model of the screen.
522    *
523    * @return The color model of the screen.
524    *
525    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
526    */
getColorModel()527   public abstract ColorModel getColorModel();
528 
529   /**
530    * Returns the names of the available fonts.
531    *
532    * @return The names of the available fonts.
533    *
534    * @deprecated
535    */
getFontList()536   public abstract String[] getFontList();
537 
538   /**
539    * Return the font metrics for the specified font
540    *
541    * @param name The name of the font to return metrics for.
542    *
543    * @return The requested font metrics.
544    *
545    * @deprecated
546    */
getFontMetrics(Font name)547   public abstract FontMetrics getFontMetrics(Font name);
548 
549   /**
550    * Flushes any buffered data to the screen so that it is in sync with
551    * what the AWT system has drawn to it.
552    */
sync()553   public abstract void sync();
554 
555   /**
556    * Returns an instance of the default toolkit.  The default toolkit is
557    * the subclass of <code>Toolkit</code> specified in the system property
558    * <code>awt.toolkit</code>, or <code>gnu.java.awt.peer.gtk.GtkToolkit</code>
559    * if the property is not set.
560    *
561    * @return An instance of the system default toolkit.
562    *
563    * @throws AWTError If the toolkit cannot be loaded.
564    */
getDefaultToolkit()565   public static synchronized Toolkit getDefaultToolkit()
566   {
567     if (toolkit != null)
568       return toolkit;
569 
570     String toolkit_name = SystemProperties.getProperty("awt.toolkit",
571                                                        default_toolkit_name);
572     try
573       {
574         ClassLoader cl;
575         cl = (ClassLoader) AccessController.doPrivileged
576         (new PrivilegedAction()
577           {
578             public Object run()
579               {
580                 return ClassLoader.getSystemClassLoader();
581               }
582           });
583         Class cls = Class.forName(toolkit_name, true, cl);
584         Object obj = cls.newInstance();
585         if (!(obj instanceof Toolkit))
586           throw new AWTError(toolkit_name + " is not a subclass of " +
587                              "java.awt.Toolkit");
588         toolkit = (Toolkit) obj;
589 
590         initAccessibility();
591         return toolkit;
592       }
593     catch (ThreadDeath death)
594       {
595         throw death;
596       }
597     catch (Throwable t)
598       {
599         // Check for the headless property.
600         if (GraphicsEnvironment.isHeadless())
601           {
602             toolkit = new HeadlessToolkit();
603             return toolkit;
604           }
605         else
606           {
607             AWTError e = new AWTError("Cannot load AWT toolkit: "
608                                       + toolkit_name);
609             throw (AWTError) e.initCause(t);
610           }
611       }
612   }
613 
614   /**
615    * Returns an image from the specified file, which must be in a
616    * recognized format.  Supported formats vary from toolkit to toolkit.
617    *
618    * @return name The name of the file to read the image from.
619    */
getImage(String name)620   public abstract Image getImage(String name);
621 
622   /**
623    * Returns an image from the specified URL, which must be in a
624    * recognized format.  Supported formats vary from toolkit to toolkit.
625    *
626    * @return url The URl to read the image from.
627    */
getImage(URL url)628   public abstract Image getImage(URL url);
629 
createImage(String filename)630   public abstract Image createImage(String filename);
631 
createImage(URL url)632   public abstract Image createImage(URL url);
633 
634   /**
635    * Readies an image to be rendered on the screen.  The width and height
636    * values can be set to the default sizes for the image by passing -1
637    * in those parameters.
638    *
639    * @param image The image to prepare for rendering.
640    * @param width The width of the image.
641    * @param height The height of the image.
642    * @param observer The observer to receive events about the preparation
643    * process.
644    *
645    * @return <code>true</code> if the image is already prepared for rendering,
646    * <code>false</code> otherwise.
647    */
prepareImage(Image image, int width, int height, ImageObserver observer)648   public abstract boolean prepareImage(Image image, int width, int height,
649                                        ImageObserver observer);
650 
651   /**
652    * Checks the status of specified image as it is being readied for
653    * rendering.
654    *
655    * @param image The image to prepare for rendering.
656    * @param width The width of the image.
657    * @param height The height of the image.
658    * @param observer The observer to receive events about the preparation
659    * process.
660    *
661    * @return A union of the bitmasks from
662    * <code>java.awt.image.ImageObserver</code> that indicates the current
663    * state of the imaging readying process.
664    */
checkImage(Image image, int width, int height, ImageObserver observer)665   public abstract int checkImage(Image image, int width, int height,
666                                  ImageObserver observer);
667 
668   /**
669    * Creates an image using the specified <code>ImageProducer</code>
670    *
671    * @param producer The <code>ImageProducer</code> to create the image from.
672    *
673    * @return The created image.
674    */
createImage(ImageProducer producer)675   public abstract Image createImage(ImageProducer producer);
676 
677   /**
678    * Creates an image from the specified byte array. The array must be in
679    * a recognized format.  Supported formats vary from toolkit to toolkit.
680    *
681    * @param data The raw image data.
682    *
683    * @return The created image.
684    */
createImage(byte[] data)685   public Image createImage(byte[] data)
686   {
687     return createImage(data, 0, data.length);
688   }
689 
690   /**
691    * Creates an image from the specified portion of the byte array passed.
692    * The array must be in a recognized format.  Supported formats vary from
693    * toolkit to toolkit.
694    *
695    * @param data The raw image data.
696    * @param offset The offset into the data where the image data starts.
697    * @param len The length of the image data.
698    *
699    * @return The created image.
700    */
createImage(byte[] data, int offset, int len)701   public abstract Image createImage(byte[] data, int offset, int len);
702 
703   /**
704    * Returns a instance of <code>PrintJob</code> for the specified
705    * arguments.
706    *
707    * @param frame The window initiating the print job.
708    * @param title The print job title.
709    * @param props The print job properties.
710    *
711    * @return The requested print job, or <code>null</code> if the job
712    * was cancelled.
713    *
714    * @exception NullPointerException If frame is null,
715    * or GraphicsEnvironment.isHeadless() returns true.
716    * @exception SecurityException If this thread is not allowed to initiate
717    * a print job request.
718    */
getPrintJob(Frame frame, String title, Properties props)719   public abstract PrintJob getPrintJob(Frame frame, String title,
720                                        Properties props);
721 
722   /**
723    * Returns a instance of <code>PrintJob</code> for the specified
724    * arguments.
725    *
726    * @param frame The window initiating the print job.
727    * @param title The print job title.
728    * @param jobAttr A set of job attributes which will control the print job.
729    * @param pageAttr A set of page attributes which will control the print job.
730    *
731    * @exception NullPointerException If frame is null, and either jobAttr is null
732    * or jobAttr.getDialog() returns JobAttributes.DialogType.NATIVE.
733    * @exception IllegalArgumentException If pageAttrspecifies differing cross
734    * feed and feed resolutions, or when GraphicsEnvironment.isHeadless() returns
735    * true.
736    * @exception SecurityException If this thread is not allowed to initiate
737    * a print job request.
738    *
739    * @since 1.3
740    */
getPrintJob(Frame frame, String title, JobAttributes jobAttr, PageAttributes pageAttr)741   public PrintJob getPrintJob(Frame frame, String title,
742                               JobAttributes jobAttr, PageAttributes pageAttr)
743   {
744     // FIXME: it is possible this check may be removed
745     // if this method, when written, always delegates to
746     // getPrintJob(Frame, String, Properties).
747     SecurityManager sm;
748     sm = System.getSecurityManager();
749     if (sm != null)
750       sm.checkPrintJobAccess();
751 
752     return null;
753   }
754 
755   /**
756    * Causes a "beep" tone to be generated.
757    */
beep()758   public abstract void beep();
759 
760   /**
761    * Returns the system clipboard.
762    *
763    * @return THe system clipboard.
764    *
765    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
766    */
getSystemClipboard()767   public abstract Clipboard getSystemClipboard();
768 
769   /**
770    * Gets the singleton instance of the system selection as a
771    * Clipboard object. The system selection contains the selected text
772    * of the last component/widget that had focus and a text selection.
773    * The default implementation returns null.
774    *
775    * @return The Clipboard holding the system (text) selection or null
776    * if the Toolkit or system doesn't support a selection clipboard.
777    *
778    * @exception HeadlessException If GraphicsEnvironment.isHeadless()
779    * is true.
780    * @exception SecurityException If the current security manager
781    * checkSystemClipboardAccess() doesn't allow access.
782    *
783    * @since 1.4
784    */
getSystemSelection()785   public Clipboard getSystemSelection()
786   {
787     return null;
788   }
789 
790   /**
791    * Returns the accelerator key mask for menu shortcuts. The default is
792    * <code>Event.CTRL_MASK</code>.  A toolkit must override this method
793    * to change the default.
794    *
795    * @return The key mask for the menu accelerator key.
796    *
797    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
798    */
getMenuShortcutKeyMask()799   public int getMenuShortcutKeyMask()
800   {
801     return Event.CTRL_MASK;
802   }
803 
804   /**
805    * Returns whether the given locking key on the keyboard is currently in its
806    * "on" state.
807    *
808    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
809    * @exception IllegalArgumentException If keyCode is not one of the valid keys.
810    * @exception UnsupportedOperationException If the host system doesn't allow
811    * getting the state of this key programmatically, or if the keyboard doesn't
812    * have this key.
813    */
getLockingKeyState(int keyCode)814   public boolean getLockingKeyState(int keyCode)
815   {
816     if (AWTUtilities.isValidKey(keyCode))
817       throw new UnsupportedOperationException
818         ("cannot get locking state of key code " + keyCode);
819 
820     throw new IllegalArgumentException("invalid key code " + keyCode);
821   }
822 
823   /**
824    * Sets the state of the given locking key on the keyboard.
825    *
826    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
827    * @exception IllegalArgumentException If keyCode is not one of the valid keys.
828    * @exception UnsupportedOperationException If the host system doesn't allow
829    * getting the state of this key programmatically, or if the keyboard doesn't
830    * have this key.
831    */
setLockingKeyState(int keyCode, boolean on)832   public void setLockingKeyState(int keyCode, boolean on)
833   {
834     if (keyCode != KeyEvent.VK_CAPS_LOCK
835         && keyCode != KeyEvent.VK_NUM_LOCK
836         && keyCode != KeyEvent.VK_SCROLL_LOCK)
837       throw new IllegalArgumentException();
838 
839     throw new UnsupportedOperationException();
840   }
841 
842   /**
843    * Returns the native container object of the specified component.  This
844    * method is necessary because the parent component might be a lightweight
845    * component.
846    *
847    * @param component The component to fetch the native container for.
848    *
849    * @return The native container object for this component.
850    */
getNativeContainer(Component component)851   protected static Container getNativeContainer(Component component)
852   {
853     component = component.getParent();
854     while (true)
855       {
856         if (component == null)
857           return null;
858         if (! (component instanceof Container))
859           {
860             component = component.getParent();
861             continue;
862           }
863         if (component.getPeer() instanceof LightweightPeer)
864           {
865             component = component.getParent();
866             continue;
867           }
868         return (Container) component;
869       }
870   }
871 
872   /**
873    * Creates a new custom cursor object.
874    *
875    * @exception IndexOutOfBoundsException If the hotSpot values are outside
876    * the bounds of the cursor.
877    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
878    */
createCustomCursor(Image cursor, Point hotSpot, String name)879   public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
880   {
881     // Presumably the only reason this isn't abstract is for backwards
882     // compatibility? FIXME?
883     if (GraphicsEnvironment.isHeadless())
884       throw new HeadlessException("No custom cursor in an headless graphics "
885                                   + "environment.");
886     return null;
887   }
888 
889   /**
890    * Returns the supported cursor dimension which is closest to the
891    * desired sizes.
892    *
893    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
894    */
getBestCursorSize(int preferredWidth, int preferredHeight)895   public Dimension getBestCursorSize(int preferredWidth, int preferredHeight)
896   {
897     if (GraphicsEnvironment.isHeadless())
898       throw new HeadlessException("No best cursor size in an headless "
899                                   + "graphics environment.");
900     return new Dimension (0,0);
901   }
902 
903   /**
904    * Returns the maximum number of colors the Toolkit supports in a custom
905    * cursor palette.
906    *
907    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
908    */
getMaximumCursorColors()909   public int getMaximumCursorColors()
910   {
911     return 0;
912   }
913 
914   /**
915    * Returns whether Toolkit supports this state for Frames.
916    *
917    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
918    *
919    * @since 1.4
920    */
isFrameStateSupported(int state)921   public boolean isFrameStateSupported(int state)
922   {
923     return false;
924   }
925 
926   /**
927    * Returns the value of the property with the specified name, or the
928    * default value if the property does not exist.
929    *
930    * @param key The name of the property to retrieve.
931    * @param def The default value of the property.
932    */
getProperty(String key, String def)933   public static String getProperty(String key, String def)
934   {
935     return props.getProperty(key, def);
936   }
937 
938 
939   /**
940    * Returns the event queue that is suitable for the calling context.
941    *
942    * <p>Despite the word &#x201c;System&#x201d; in the name of this
943    * method, a toolkit may provide different event queues for each
944    * applet. There is no guarantee that the same queue is shared
945    * system-wide.
946    *
947    * <p>The implementation first checks whether a
948    * SecurityManager has been installed. If so, its {@link
949    * java.lang.SecurityManager#checkAwtEventQueueAccess()} method gets
950    * called. The security manager will throw a SecurityException if it
951    * does not grant the permission to access the event queue.
952    *
953    * <p>Next, the call is delegated to {@link
954    * #getSystemEventQueueImpl()}.
955    *
956    * @return The event queue for this applet (or application).
957    *
958    * @throws SecurityException if a security manager has been
959    * installed, and it does not grant the permission to access the
960    * event queue.
961    */
getSystemEventQueue()962   public final EventQueue getSystemEventQueue()
963   {
964     SecurityManager sm;
965 
966     sm = System.getSecurityManager();
967     if (sm != null)
968       sm.checkAwtEventQueueAccess();
969 
970     return getSystemEventQueueImpl();
971   }
972 
973 
974   /**
975    * Returns the event queue that is suitable for the calling context.
976    *
977    * <p>Despite the word &#x201c;System&#x201d; in the name of this
978    * method, a toolkit may provide different event queues for each
979    * applet. There is no guarantee that the same queue is shared
980    * system-wide.
981    *
982    * <p>No security checks are performed, which is why this method
983    * may only be called by Toolkits.
984    *
985    * @see #getSystemEventQueue()
986    */
getSystemEventQueueImpl()987   protected abstract EventQueue getSystemEventQueueImpl();
988 
989 
990   /**
991    * @since 1.3
992    */
993   public abstract DragSourceContextPeer
createDragSourceContextPeer(DragGestureEvent e)994     createDragSourceContextPeer(DragGestureEvent e);
995 
996   /**
997    * @since 1.3
998    */
999   public <T extends DragGestureRecognizer> T
createDragGestureRecognizer(Class<T> recognizer, DragSource ds, Component comp, int actions, DragGestureListener l)1000     createDragGestureRecognizer(Class<T> recognizer, DragSource ds,
1001                                 Component comp, int actions,
1002                                 DragGestureListener l)
1003   {
1004     return null;
1005   }
1006 
getDesktopProperty(String propertyName)1007   public final Object getDesktopProperty(String propertyName)
1008   {
1009     return desktopProperties.get(propertyName);
1010   }
1011 
setDesktopProperty(String name, Object newValue)1012   protected final void setDesktopProperty(String name, Object newValue)
1013   {
1014     Object oldValue = getDesktopProperty(name);
1015     desktopProperties.put(name, newValue);
1016     desktopPropsSupport.firePropertyChange(name, oldValue, newValue);
1017   }
1018 
lazilyLoadDesktopProperty(String name)1019   protected Object lazilyLoadDesktopProperty(String name)
1020   {
1021     // FIXME - what is this??
1022     return null;
1023   }
1024 
initializeDesktopProperties()1025   protected void initializeDesktopProperties()
1026   {
1027     // Overridden by toolkit implementation?
1028   }
1029 
addPropertyChangeListener(String name, PropertyChangeListener pcl)1030   public void addPropertyChangeListener(String name,
1031                                         PropertyChangeListener pcl)
1032   {
1033     desktopPropsSupport.addPropertyChangeListener(name, pcl);
1034   }
1035 
removePropertyChangeListener(String name, PropertyChangeListener pcl)1036   public void removePropertyChangeListener(String name,
1037                                            PropertyChangeListener pcl)
1038   {
1039     desktopPropsSupport.removePropertyChangeListener(name, pcl);
1040   }
1041 
1042   /**
1043    * @since 1.4
1044    */
getPropertyChangeListeners()1045   public PropertyChangeListener[] getPropertyChangeListeners()
1046   {
1047     return desktopPropsSupport.getPropertyChangeListeners();
1048   }
1049 
1050   /**
1051    * @since 1.4
1052    */
getPropertyChangeListeners(String name)1053   public PropertyChangeListener[] getPropertyChangeListeners(String name)
1054   {
1055     return desktopPropsSupport.getPropertyChangeListeners(name);
1056   }
1057 
1058   /**
1059    * Adds an AWTEventListener to this toolkit. This listener is informed about
1060    * all events that pass the eventqueue that match the specified
1061    * <code>evenMask</code>. The <code>eventMask</code> is an ORed combination
1062    * of event masks as defined in {@link AWTEvent}.
1063    *
1064    * If a security manager is installed, it is asked first if an
1065    * <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code> is allowed.
1066    * This may result in a <code>SecurityException</code> beeing thrown.
1067    *
1068    * It is not recommended to use this kind of notification for normal
1069    * applications. It is intended solely for the purpose of debugging and to
1070    * support special facilities.
1071    *
1072    * @param listener the listener to add
1073    * @param eventMask the event mask of event types which the listener is
1074    *        interested in
1075    *
1076    * @since 1.2
1077    *
1078    * @throws SecurityException if there is a <code>SecurityManager</code> that
1079    *         doesn't grant
1080    *         <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code>
1081    *
1082    * @see #getAWTEventListeners()
1083    * @see #getAWTEventListeners(long)
1084    * @see #removeAWTEventListener(AWTEventListener)
1085    */
addAWTEventListener(AWTEventListener listener, long eventMask)1086   public void addAWTEventListener(AWTEventListener listener, long eventMask)
1087   {
1088     // First we must check the security permissions.
1089     SecurityManager s = System.getSecurityManager();
1090     if (s != null)
1091       s.checkPermission(new AWTPermission("listenToAllAWTEvents"));
1092 
1093     // Go through the list and check if the requested listener is already
1094     // registered.
1095     boolean found = false;
1096     for (int i = 0; i < awtEventListeners.length; ++i)
1097       {
1098         AWTEventListenerProxy proxy = awtEventListeners[i];
1099         if (proxy.getListener() == listener)
1100           {
1101             found = true;
1102             // Modify the proxies event mask to include the new event mask.
1103             AWTEventListenerProxy newProxy =
1104               new AWTEventListenerProxy(proxy.getEventMask() | eventMask,
1105                                         listener);
1106             awtEventListeners[i] = newProxy;
1107             break;
1108           }
1109       }
1110 
1111     // If that listener was not found, then add it.
1112     if (! found)
1113       {
1114         AWTEventListenerProxy proxy =
1115           new AWTEventListenerProxy(eventMask, listener);
1116         AWTEventListenerProxy[] newArray =
1117           new AWTEventListenerProxy[awtEventListeners.length + 1];
1118         System.arraycopy(awtEventListeners, 0, newArray, 0,
1119                          awtEventListeners.length);
1120         newArray[newArray.length - 1] = proxy;
1121         awtEventListeners = newArray;
1122       }
1123   }
1124 
1125   /**
1126    * Removes an AWT event listener from this toolkit. This listener is no
1127    * longer informed of any event types it was registered in.
1128    *
1129    * If a security manager is installed, it is asked first if an
1130    * <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code> is allowed.
1131    * This may result in a <code>SecurityException</code> beeing thrown.
1132    *
1133    * It is not recommended to use this kind of notification for normal
1134    * applications. It is intended solely for the purpose of debugging and to
1135    * support special facilities.
1136    *
1137    * @param listener the listener to remove
1138    *
1139    * @throws SecurityException if there is a <code>SecurityManager</code> that
1140    *         doesn't grant
1141    *         <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code>
1142    *
1143    * @since 1.2
1144    *
1145    * @see #addAWTEventListener(AWTEventListener, long)
1146    * @see #getAWTEventListeners()
1147    * @see #getAWTEventListeners(long)
1148    */
removeAWTEventListener(AWTEventListener listener)1149   public void removeAWTEventListener(AWTEventListener listener)
1150   {
1151     // First we must check the security permissions.
1152     SecurityManager s = System.getSecurityManager();
1153     if (s != null)
1154       s.checkPermission(new AWTPermission("listenToAllAWTEvents"));
1155 
1156 
1157     // Find the index of the listener.
1158     int index = -1;
1159     for (int i = 0; i < awtEventListeners.length; ++i)
1160       {
1161         AWTEventListenerProxy proxy = awtEventListeners[i];
1162         if (proxy.getListener() == listener)
1163           {
1164             index = i;
1165             break;
1166           }
1167       }
1168 
1169     // Copy over the arrays and leave out the removed element.
1170     if (index != -1)
1171       {
1172         AWTEventListenerProxy[] newArray =
1173           new AWTEventListenerProxy[awtEventListeners.length - 1];
1174         if (index > 0)
1175           System.arraycopy(awtEventListeners, 0, newArray, 0, index);
1176         if (index < awtEventListeners.length - 1)
1177           System.arraycopy(awtEventListeners, index + 1, newArray, index,
1178                            awtEventListeners.length - index - 1);
1179         awtEventListeners = newArray;
1180       }
1181   }
1182 
1183   /**
1184    * Returns all registered AWT event listeners. This method returns a copy of
1185    * the listener array, so that application cannot trash the listener list.
1186    *
1187    * If a security manager is installed, it is asked first if an
1188    * <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code> is allowed.
1189    * This may result in a <code>SecurityException</code> beeing thrown.
1190    *
1191    * It is not recommended to use this kind of notification for normal
1192    * applications. It is intended solely for the purpose of debugging and to
1193    * support special facilities.
1194    *
1195    * @return all registered AWT event listeners
1196    *
1197    * @throws SecurityException if there is a <code>SecurityManager</code> that
1198    *         doesn't grant
1199    *         <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code>
1200    *
1201    * @since 1.4
1202    *
1203    * @see #addAWTEventListener(AWTEventListener, long)
1204    * @see #removeAWTEventListener(AWTEventListener)
1205    * @see #getAWTEventListeners(long)
1206    */
getAWTEventListeners()1207   public AWTEventListener[] getAWTEventListeners()
1208   {
1209     // First we must check the security permissions.
1210     SecurityManager s = System.getSecurityManager();
1211     if (s != null)
1212       s.checkPermission(new AWTPermission("listenToAllAWTEvents"));
1213 
1214     // Create a copy of the array.
1215     AWTEventListener[] copy = new AWTEventListener[awtEventListeners.length];
1216     System.arraycopy(awtEventListeners, 0, copy, 0, awtEventListeners.length);
1217     return copy;
1218   }
1219 
1220   /**
1221    * Returns all registered AWT event listeners that listen for events with
1222    * the specified <code>eventMask</code>. This method returns a copy of
1223    * the listener array, so that application cannot trash the listener list.
1224    *
1225    * If a security manager is installed, it is asked first if an
1226    * <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code> is allowed.
1227    * This may result in a <code>SecurityException</code> beeing thrown.
1228    *
1229    * It is not recommended to use this kind of notification for normal
1230    * applications. It is intended solely for the purpose of debugging and to
1231    * support special facilities.
1232    *
1233    * @param mask the event mask
1234    *
1235    * @throws SecurityException if there is a <code>SecurityManager</code> that
1236    *         doesn't grant
1237    *         <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code>
1238    *
1239    *
1240    * @since 1.4
1241    *
1242    * @see #addAWTEventListener(AWTEventListener, long)
1243    * @see #removeAWTEventListener(AWTEventListener)
1244    * @see #getAWTEventListeners()
1245    */
getAWTEventListeners(long mask)1246   public AWTEventListener[] getAWTEventListeners(long mask)
1247   {
1248     // First we must check the security permissions.
1249     SecurityManager s = System.getSecurityManager();
1250     if (s != null)
1251       s.checkPermission(new AWTPermission("listenToAllAWTEvents"));
1252 
1253     // Create a copy of the array with only the requested listeners in it.
1254     ArrayList l = new ArrayList(awtEventListeners.length);
1255     for (int i = 0; i < awtEventListeners.length; ++i)
1256       {
1257         if ((awtEventListeners[i].getEventMask() & mask) != 0)
1258           l.add(awtEventListeners[i]);
1259       }
1260 
1261     return (AWTEventListener[] ) l.toArray(new AWTEventListener[l.size()]);
1262   }
1263 
1264 
1265   /**
1266    * Dispatches events to listeners registered to this Toolkit. This is called
1267    * by {@link Component#dispatchEventImpl(AWTEvent)} in order to dispatch
1268    * events globally.
1269    *
1270    * @param ev the event to dispatch
1271    */
globalDispatchEvent(AWTEvent ev)1272   void globalDispatchEvent(AWTEvent ev)
1273   {
1274     // We do not use the accessor methods here because they create new
1275     // arrays each time. We must be very efficient, so we access this directly.
1276     for (int i = 0; i < awtEventListeners.length; ++i)
1277       {
1278         AWTEventListenerProxy proxy = awtEventListeners[i];
1279         if ((proxy.getEventMask() & AWTEvent.eventIdToMask(ev.getID())) != 0)
1280           proxy.eventDispatched(ev);
1281       }
1282   }
1283 
1284   /**
1285    * @since 1.3
1286    */
1287   public abstract Map<TextAttribute,?>
mapInputMethodHighlight(InputMethodHighlight highlight)1288     mapInputMethodHighlight(InputMethodHighlight highlight);
1289 
isModalExclusionTypeSupported(Dialog.ModalExclusionType modalExclusionType)1290   public abstract boolean isModalExclusionTypeSupported
1291                           (Dialog.ModalExclusionType modalExclusionType);
1292 
isModalityTypeSupported(Dialog.ModalityType modalityType)1293   public abstract boolean isModalityTypeSupported
1294                           (Dialog.ModalityType modalityType);
1295 
1296   /**
1297    * Initializes the accessibility framework. In particular, this loads the
1298    * properties javax.accessibility.screen_magnifier_present and
1299    * javax.accessibility.screen_reader_present and loads
1300    * the classes specified in javax.accessibility.assistive_technologies.
1301    */
initAccessibility()1302   private static void initAccessibility()
1303   {
1304     AccessController.doPrivileged
1305     (new PrivilegedAction()
1306      {
1307        public Object run()
1308        {
1309          Properties props = new Properties();
1310          String sep = File.separator;
1311 
1312          // Try the user configuration.
1313          try
1314            {
1315              File propsFile = new File(System.getProperty("user.home") + sep
1316                                        + ".accessibility.properties");
1317              FileInputStream in = new FileInputStream(propsFile);
1318              props.load(in);
1319              in.close();
1320            }
1321          catch (Exception ex)
1322            {
1323              // User configuration not present, ignore.
1324            }
1325 
1326          // Try the system configuration if there was no user configuration.
1327          if (props.size() == 0)
1328            {
1329              try
1330                {
1331                  File propsFile =
1332                    new File(System.getProperty("gnu.classpath.home.url")
1333                             + sep + "accessibility.properties");
1334                  FileInputStream in = new FileInputStream(propsFile);
1335                  props.load(in);
1336                  in.close();
1337                }
1338              catch (Exception ex)
1339                {
1340                  // System configuration not present, ignore.
1341                }
1342            }
1343 
1344        // Fetch the screen_magnifier_present property. Check systen properties
1345        // first, then fallback to the configuration file.
1346        String magPresent = SystemProperties.getProperty
1347                               ("javax.accessibility.screen_magnifier_present");
1348        if (magPresent == null)
1349          {
1350            magPresent = props.getProperty("screen_magnifier_present");
1351            if (magPresent != null)
1352              {
1353                SystemProperties.setProperty
1354                  ("javax.accessibility.screen_magnifier_present", magPresent);
1355              }
1356          }
1357 
1358        // Fetch the screen_reader_present property. Check systen properties
1359        // first, then fallback to the configuration file.
1360        String readerPresent = SystemProperties.getProperty
1361                                 ("javax.accessibility.screen_reader_present");
1362        if (readerPresent == null)
1363          {
1364            readerPresent = props.getProperty("screen_reader_present");
1365            if (readerPresent != null)
1366              {
1367                SystemProperties.setProperty
1368                  ("javax.accessibility.screen_reader_present", readerPresent);
1369              }
1370          }
1371 
1372        // Fetch the list of classes to be loaded.
1373        String classes = SystemProperties.getProperty
1374          ("javax.accessibility.assistive_technologies");
1375        if (classes == null)
1376          {
1377            classes = props.getProperty("assistive_technologies");
1378            if (classes != null)
1379              {
1380                SystemProperties.setProperty
1381                ("javax.accessibility.assistive_technologies", classes);
1382              }
1383          }
1384 
1385        // Try to load the assisitive_technologies classes.
1386        if (classes != null)
1387          {
1388            ClassLoader cl = ClassLoader.getSystemClassLoader();
1389            StringTokenizer tokenizer = new StringTokenizer(classes, ",");
1390            while (tokenizer.hasMoreTokens())
1391              {
1392                String className = tokenizer.nextToken();
1393                try
1394                  {
1395                    Class atClass = cl.loadClass(className);
1396                    atClass.newInstance();
1397                  }
1398                catch (ClassNotFoundException ex)
1399                  {
1400                    AWTError err = new AWTError("Assistive Technology class not"
1401                                                + " found: " + className);
1402                    err.initCause(ex);
1403                    throw err;
1404                  }
1405                catch (InstantiationException ex)
1406                  {
1407                    AWTError err =
1408                      new AWTError("Assistive Technology class cannot be "
1409                                   + "instantiated: " + className);
1410                    err.initCause(ex);
1411                    throw err;
1412                  }
1413                catch (IllegalAccessException ex)
1414                  {
1415                    AWTError err =
1416                      new AWTError("Assistive Technology class cannot be "
1417                                   + "accessed: " + className);
1418                    err.initCause(err);
1419                    throw err;
1420                  }
1421              }
1422          }
1423        return null;
1424        }
1425      });
1426 
1427   }
1428 
1429 } // class Toolkit
1430