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