src/share/classes/java/awt/Toolkit.java

Print this page




 406      * Obtains this toolkit's implementation of helper class for
 407      * <code>MouseInfo</code> operations.
 408      * @return    this toolkit's implementation of  helper for <code>MouseInfo</code>
 409      * @throws    UnsupportedOperationException if this operation is not implemented
 410      * @see       java.awt.peer.MouseInfoPeer
 411      * @see       java.awt.MouseInfo
 412      * @since 1.5
 413      */
 414     protected MouseInfoPeer getMouseInfoPeer() {
 415         throw new UnsupportedOperationException("Not implemented");
 416     }
 417 
 418     private static LightweightPeer lightweightMarker;
 419 
 420     /**
 421      * Creates a peer for a component or container.  This peer is windowless
 422      * and allows the Component and Container classes to be extended directly
 423      * to create windowless components that are defined entirely in java.
 424      *
 425      * @param target The Component to be created.

 426      */
 427     protected LightweightPeer createComponent(Component target) {
 428         if (lightweightMarker == null) {
 429             lightweightMarker = new NullComponentPeer();
 430         }
 431         return lightweightMarker;
 432     }
 433 
 434     /**
 435      * Creates this toolkit's implementation of <code>Font</code> using
 436      * the specified peer interface.
 437      * @param     name the font to be implemented
 438      * @param     style the style of the font, such as <code>PLAIN</code>,
 439      *            <code>BOLD</code>, <code>ITALIC</code>, or a combination
 440      * @return    this toolkit's implementation of <code>Font</code>
 441      * @see       java.awt.Font
 442      * @see       java.awt.peer.FontPeer
 443      * @see       java.awt.GraphicsEnvironment#getAllFonts
 444      * @deprecated  see java.awt.GraphicsEnvironment#getAllFonts
 445      */


1353      * @see       java.awt.GraphicsEnvironment#isHeadless
1354      * @see       java.awt.MenuBar
1355      * @see       java.awt.MenuShortcut
1356      * @since     JDK1.1
1357      */
1358     public int getMenuShortcutKeyMask() throws HeadlessException {
1359         GraphicsEnvironment.checkHeadless();
1360 
1361         return Event.CTRL_MASK;
1362     }
1363 
1364     /**
1365      * Returns whether the given locking key on the keyboard is currently in
1366      * its "on" state.
1367      * Valid key codes are
1368      * {@link java.awt.event.KeyEvent#VK_CAPS_LOCK VK_CAPS_LOCK},
1369      * {@link java.awt.event.KeyEvent#VK_NUM_LOCK VK_NUM_LOCK},
1370      * {@link java.awt.event.KeyEvent#VK_SCROLL_LOCK VK_SCROLL_LOCK}, and
1371      * {@link java.awt.event.KeyEvent#VK_KANA_LOCK VK_KANA_LOCK}.
1372      *



1373      * @exception java.lang.IllegalArgumentException if <code>keyCode</code>
1374      * is not one of the valid key codes
1375      * @exception java.lang.UnsupportedOperationException if the host system doesn't
1376      * allow getting the state of this key programmatically, or if the keyboard
1377      * doesn't have this key
1378      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1379      * returns true
1380      * @see       java.awt.GraphicsEnvironment#isHeadless
1381      * @since 1.3
1382      */
1383     public boolean getLockingKeyState(int keyCode)
1384         throws UnsupportedOperationException
1385     {
1386         GraphicsEnvironment.checkHeadless();
1387 
1388         if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK ||
1389                keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) {
1390             throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
1391         }
1392         throw new UnsupportedOperationException("Toolkit.getLockingKeyState");
1393     }
1394 
1395     /**
1396      * Sets the state of the given locking key on the keyboard.
1397      * Valid key codes are
1398      * {@link java.awt.event.KeyEvent#VK_CAPS_LOCK VK_CAPS_LOCK},
1399      * {@link java.awt.event.KeyEvent#VK_NUM_LOCK VK_NUM_LOCK},
1400      * {@link java.awt.event.KeyEvent#VK_SCROLL_LOCK VK_SCROLL_LOCK}, and
1401      * {@link java.awt.event.KeyEvent#VK_KANA_LOCK VK_KANA_LOCK}.
1402      * <p>
1403      * Depending on the platform, setting the state of a locking key may
1404      * involve event processing and therefore may not be immediately
1405      * observable through getLockingKeyState.
1406      *


1407      * @exception java.lang.IllegalArgumentException if <code>keyCode</code>
1408      * is not one of the valid key codes
1409      * @exception java.lang.UnsupportedOperationException if the host system doesn't
1410      * allow setting the state of this key programmatically, or if the keyboard
1411      * doesn't have this key
1412      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1413      * returns true
1414      * @see       java.awt.GraphicsEnvironment#isHeadless
1415      * @since 1.3
1416      */
1417     public void setLockingKeyState(int keyCode, boolean on)
1418         throws UnsupportedOperationException
1419     {
1420         GraphicsEnvironment.checkHeadless();
1421 
1422         if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK ||
1423                keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) {
1424             throw new IllegalArgumentException("invalid key for Toolkit.setLockingKeyState");
1425         }
1426         throw new UnsupportedOperationException("Toolkit.setLockingKeyState");
1427     }
1428 
1429     /**
1430      * Give native peers the ability to query the native container
1431      * given a native component (eg the direct parent may be lightweight).



1432      */
1433     protected static Container getNativeContainer(Component c) {
1434         return c.getNativeContainer();
1435     }
1436 
1437     /**
1438      * Creates a new custom cursor object.
1439      * If the image to display is invalid, the cursor will be hidden (made
1440      * completely transparent), and the hotspot will be set to (0, 0).
1441      *
1442      * <p>Note that multi-frame images are invalid and may cause this
1443      * method to hang.
1444      *
1445      * @param cursor the image to display when the cursor is activated
1446      * @param hotSpot the X and Y of the large cursor's hot spot; the
1447      *   hotSpot values must be less than the Dimension returned by
1448      *   <code>getBestCursorSize</code>
1449      * @param     name a localized description of the cursor, for Java Accessibility use
1450      * @exception IndexOutOfBoundsException if the hotSpot values are outside
1451      *   the bounds of the cursor

1452      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1453      * returns true
1454      * @see       java.awt.GraphicsEnvironment#isHeadless
1455      * @since     1.2
1456      */
1457     public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
1458         throws IndexOutOfBoundsException, HeadlessException
1459     {
1460         // Override to implement custom cursor support.
1461         if (this != Toolkit.getDefaultToolkit()) {
1462             return Toolkit.getDefaultToolkit().
1463                 createCustomCursor(cursor, hotSpot, name);
1464         } else {
1465             return new Cursor(Cursor.DEFAULT_CURSOR);
1466         }
1467     }
1468 
1469     /**
1470      * Returns the supported cursor dimension which is closest to the desired
1471      * sizes.  Systems which only support a single cursor size will return that


1658                         ResourceBundle.getBundle("sun.awt.resources.awt",
1659                                                  CoreResourceBundleControl.getRBControlInstance());
1660                 } catch (MissingResourceException e) {
1661                     // No resource file; defaults will be used.
1662                 }
1663                 return null;
1664             }
1665         });
1666 
1667         // ensure that the proper libraries are loaded
1668         loadLibraries();
1669         initAssistiveTechnologies();
1670         if (!GraphicsEnvironment.isHeadless()) {
1671             initIDs();
1672         }
1673     }
1674 
1675     /**
1676      * Gets a property with the specified key and default.
1677      * This method returns defaultValue if the property is not found.





1678      */
1679     public static String getProperty(String key, String defaultValue) {
1680         // first try platform specific bundle
1681         if (platformResources != null) {
1682             try {
1683                 return platformResources.getString(key);
1684             }
1685             catch (MissingResourceException e) {}
1686         }
1687 
1688         // then shared one
1689         if (resources != null) {
1690             try {
1691                 return resources.getString(key);
1692             }
1693             catch (MissingResourceException e) {}
1694         }
1695 
1696         return defaultValue;
1697     }


1721         return getSystemEventQueueImpl();
1722     }
1723 
1724     /**
1725      * Gets the application's or applet's <code>EventQueue</code>
1726      * instance, without checking access.  For security reasons,
1727      * this can only be called from a <code>Toolkit</code> subclass.
1728      * @return the <code>EventQueue</code> object
1729      */
1730     protected abstract EventQueue getSystemEventQueueImpl();
1731 
1732     /* Accessor method for use by AWT package routines. */
1733     static EventQueue getEventQueue() {
1734         return getDefaultToolkit().getSystemEventQueueImpl();
1735     }
1736 
1737     /**
1738      * Creates the peer for a DragSourceContext.
1739      * Always throws InvalidDndOperationException if
1740      * GraphicsEnvironment.isHeadless() returns true.


1741      * @see java.awt.GraphicsEnvironment#isHeadless
1742      */
1743     public abstract DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException;
1744 
1745     /**
1746      * Creates a concrete, platform dependent, subclass of the abstract
1747      * DragGestureRecognizer class requested, and associates it with the
1748      * DragSource, Component and DragGestureListener specified.
1749      *
1750      * subclasses should override this to provide their own implementation
1751      *
1752      * @param abstractRecognizerClass The abstract class of the required recognizer
1753      * @param ds                      The DragSource
1754      * @param c                       The Component target for the DragGestureRecognizer
1755      * @param srcActions              The actions permitted for the gesture
1756      * @param dgl                     The DragGestureListener
1757      *
1758      * @return the new object or null.  Always returns null if
1759      * GraphicsEnvironment.isHeadless() returns true.
1760      * @see java.awt.GraphicsEnvironment#isHeadless
1761      */
1762     public <T extends DragGestureRecognizer> T
1763         createDragGestureRecognizer(Class<T> abstractRecognizerClass,
1764                                     DragSource ds, Component c, int srcActions,
1765                                     DragGestureListener dgl)
1766     {
1767         return null;
1768     }
1769 
1770     /**
1771      * Obtains a value for the specified desktop property.
1772      *
1773      * A desktop property is a uniquely named value for a resource that
1774      * is Toolkit global in nature. Usually it also is an abstract
1775      * representation for an underlying platform dependent desktop setting.
1776      * For more information on desktop properties supported by the AWT see
1777      * <a href="doc-files/DesktopProperties.html">AWT Desktop Properties</a>.



1778      */
1779     public final synchronized Object getDesktopProperty(String propertyName) {
1780         // This is a workaround for headless toolkits.  It would be
1781         // better to override this method but it is declared final.
1782         // "this instanceof" syntax defeats polymorphism.
1783         // --mm, 03/03/00
1784         if (this instanceof HeadlessToolkit) {
1785             return ((HeadlessToolkit)this).getUnderlyingToolkit()
1786                 .getDesktopProperty(propertyName);
1787         }
1788 
1789         if (desktopProperties.isEmpty()) {
1790             initializeDesktopProperties();
1791         }
1792 
1793         Object value;
1794 
1795         // This property should never be cached
1796         if (propertyName.equals("awt.dynamicLayoutSupported")) {
1797             return getDefaultToolkit().lazilyLoadDesktopProperty(propertyName);


1801 
1802         if (value == null) {
1803             value = lazilyLoadDesktopProperty(propertyName);
1804 
1805             if (value != null) {
1806                 setDesktopProperty(propertyName, value);
1807             }
1808         }
1809 
1810         /* for property "awt.font.desktophints" */
1811         if (value instanceof RenderingHints) {
1812             value = ((RenderingHints)value).clone();
1813         }
1814 
1815         return value;
1816     }
1817 
1818     /**
1819      * Sets the named desktop property to the specified value and fires a
1820      * property change event to notify any listeners that the value has changed.


1821      */
1822     protected final void setDesktopProperty(String name, Object newValue) {
1823         // This is a workaround for headless toolkits.  It would be
1824         // better to override this method but it is declared final.
1825         // "this instanceof" syntax defeats polymorphism.
1826         // --mm, 03/03/00
1827         if (this instanceof HeadlessToolkit) {
1828             ((HeadlessToolkit)this).getUnderlyingToolkit()
1829                 .setDesktopProperty(name, newValue);
1830             return;
1831         }
1832         Object oldValue;
1833 
1834         synchronized (this) {
1835             oldValue = desktopProperties.get(name);
1836             desktopProperties.put(name, newValue);
1837         }
1838 
1839         // Don't fire change event if old and new values are null.
1840         // It helps to avoid recursive resending of WM_THEMECHANGED




 406      * Obtains this toolkit's implementation of helper class for
 407      * <code>MouseInfo</code> operations.
 408      * @return    this toolkit's implementation of  helper for <code>MouseInfo</code>
 409      * @throws    UnsupportedOperationException if this operation is not implemented
 410      * @see       java.awt.peer.MouseInfoPeer
 411      * @see       java.awt.MouseInfo
 412      * @since 1.5
 413      */
 414     protected MouseInfoPeer getMouseInfoPeer() {
 415         throw new UnsupportedOperationException("Not implemented");
 416     }
 417 
 418     private static LightweightPeer lightweightMarker;
 419 
 420     /**
 421      * Creates a peer for a component or container.  This peer is windowless
 422      * and allows the Component and Container classes to be extended directly
 423      * to create windowless components that are defined entirely in java.
 424      *
 425      * @param target The Component to be created.
 426      * @return  the peer for the specified component
 427      */
 428     protected LightweightPeer createComponent(Component target) {
 429         if (lightweightMarker == null) {
 430             lightweightMarker = new NullComponentPeer();
 431         }
 432         return lightweightMarker;
 433     }
 434 
 435     /**
 436      * Creates this toolkit's implementation of <code>Font</code> using
 437      * the specified peer interface.
 438      * @param     name the font to be implemented
 439      * @param     style the style of the font, such as <code>PLAIN</code>,
 440      *            <code>BOLD</code>, <code>ITALIC</code>, or a combination
 441      * @return    this toolkit's implementation of <code>Font</code>
 442      * @see       java.awt.Font
 443      * @see       java.awt.peer.FontPeer
 444      * @see       java.awt.GraphicsEnvironment#getAllFonts
 445      * @deprecated  see java.awt.GraphicsEnvironment#getAllFonts
 446      */


1354      * @see       java.awt.GraphicsEnvironment#isHeadless
1355      * @see       java.awt.MenuBar
1356      * @see       java.awt.MenuShortcut
1357      * @since     JDK1.1
1358      */
1359     public int getMenuShortcutKeyMask() throws HeadlessException {
1360         GraphicsEnvironment.checkHeadless();
1361 
1362         return Event.CTRL_MASK;
1363     }
1364 
1365     /**
1366      * Returns whether the given locking key on the keyboard is currently in
1367      * its "on" state.
1368      * Valid key codes are
1369      * {@link java.awt.event.KeyEvent#VK_CAPS_LOCK VK_CAPS_LOCK},
1370      * {@link java.awt.event.KeyEvent#VK_NUM_LOCK VK_NUM_LOCK},
1371      * {@link java.awt.event.KeyEvent#VK_SCROLL_LOCK VK_SCROLL_LOCK}, and
1372      * {@link java.awt.event.KeyEvent#VK_KANA_LOCK VK_KANA_LOCK}.
1373      *
1374      * @param keyCode  the key code
1375      * @return  {@code true} if the given key is currently in its "on" state;
1376      *          otherwise {@code false}
1377      * @exception java.lang.IllegalArgumentException if <code>keyCode</code>
1378      * is not one of the valid key codes
1379      * @exception java.lang.UnsupportedOperationException if the host system doesn't
1380      * allow getting the state of this key programmatically, or if the keyboard
1381      * doesn't have this key
1382      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1383      * returns true
1384      * @see       java.awt.GraphicsEnvironment#isHeadless
1385      * @since 1.3
1386      */
1387     public boolean getLockingKeyState(int keyCode)
1388         throws UnsupportedOperationException
1389     {
1390         GraphicsEnvironment.checkHeadless();
1391 
1392         if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK ||
1393                keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) {
1394             throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
1395         }
1396         throw new UnsupportedOperationException("Toolkit.getLockingKeyState");
1397     }
1398 
1399     /**
1400      * Sets the state of the given locking key on the keyboard.
1401      * Valid key codes are
1402      * {@link java.awt.event.KeyEvent#VK_CAPS_LOCK VK_CAPS_LOCK},
1403      * {@link java.awt.event.KeyEvent#VK_NUM_LOCK VK_NUM_LOCK},
1404      * {@link java.awt.event.KeyEvent#VK_SCROLL_LOCK VK_SCROLL_LOCK}, and
1405      * {@link java.awt.event.KeyEvent#VK_KANA_LOCK VK_KANA_LOCK}.
1406      * <p>
1407      * Depending on the platform, setting the state of a locking key may
1408      * involve event processing and therefore may not be immediately
1409      * observable through getLockingKeyState.
1410      *
1411      * @param keyCode  the key code
1412      * @param on       the state of the key
1413      * @exception java.lang.IllegalArgumentException if <code>keyCode</code>
1414      * is not one of the valid key codes
1415      * @exception java.lang.UnsupportedOperationException if the host system doesn't
1416      * allow setting the state of this key programmatically, or if the keyboard
1417      * doesn't have this key
1418      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1419      * returns true
1420      * @see       java.awt.GraphicsEnvironment#isHeadless
1421      * @since 1.3
1422      */
1423     public void setLockingKeyState(int keyCode, boolean on)
1424         throws UnsupportedOperationException
1425     {
1426         GraphicsEnvironment.checkHeadless();
1427 
1428         if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK ||
1429                keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) {
1430             throw new IllegalArgumentException("invalid key for Toolkit.setLockingKeyState");
1431         }
1432         throw new UnsupportedOperationException("Toolkit.setLockingKeyState");
1433     }
1434 
1435     /**
1436      * Give native peers the ability to query the native container
1437      * given a native component (eg the direct parent may be lightweight).
1438      *
1439      * @param c  the component to fetch the container for
1440      * @return   the native container object for the component
1441      */
1442     protected static Container getNativeContainer(Component c) {
1443         return c.getNativeContainer();
1444     }
1445 
1446     /**
1447      * Creates a new custom cursor object.
1448      * If the image to display is invalid, the cursor will be hidden (made
1449      * completely transparent), and the hotspot will be set to (0, 0).
1450      *
1451      * <p>Note that multi-frame images are invalid and may cause this
1452      * method to hang.
1453      *
1454      * @param cursor the image to display when the cursor is activated
1455      * @param hotSpot the X and Y of the large cursor's hot spot; the
1456      *   hotSpot values must be less than the Dimension returned by
1457      *   <code>getBestCursorSize</code>
1458      * @param     name a localized description of the cursor, for Java Accessibility use
1459      * @exception IndexOutOfBoundsException if the hotSpot values are outside
1460      *   the bounds of the cursor
1461      * @return  the cursor created
1462      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1463      * returns true
1464      * @see       java.awt.GraphicsEnvironment#isHeadless
1465      * @since     1.2
1466      */
1467     public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
1468         throws IndexOutOfBoundsException, HeadlessException
1469     {
1470         // Override to implement custom cursor support.
1471         if (this != Toolkit.getDefaultToolkit()) {
1472             return Toolkit.getDefaultToolkit().
1473                 createCustomCursor(cursor, hotSpot, name);
1474         } else {
1475             return new Cursor(Cursor.DEFAULT_CURSOR);
1476         }
1477     }
1478 
1479     /**
1480      * Returns the supported cursor dimension which is closest to the desired
1481      * sizes.  Systems which only support a single cursor size will return that


1668                         ResourceBundle.getBundle("sun.awt.resources.awt",
1669                                                  CoreResourceBundleControl.getRBControlInstance());
1670                 } catch (MissingResourceException e) {
1671                     // No resource file; defaults will be used.
1672                 }
1673                 return null;
1674             }
1675         });
1676 
1677         // ensure that the proper libraries are loaded
1678         loadLibraries();
1679         initAssistiveTechnologies();
1680         if (!GraphicsEnvironment.isHeadless()) {
1681             initIDs();
1682         }
1683     }
1684 
1685     /**
1686      * Gets a property with the specified key and default.
1687      * This method returns defaultValue if the property is not found.
1688      *
1689      * @param key           the key
1690      * @param defaultValue  the default value
1691      * @return  the value of the property or the default value
1692      *          if the property was not found
1693      */
1694     public static String getProperty(String key, String defaultValue) {
1695         // first try platform specific bundle
1696         if (platformResources != null) {
1697             try {
1698                 return platformResources.getString(key);
1699             }
1700             catch (MissingResourceException e) {}
1701         }
1702 
1703         // then shared one
1704         if (resources != null) {
1705             try {
1706                 return resources.getString(key);
1707             }
1708             catch (MissingResourceException e) {}
1709         }
1710 
1711         return defaultValue;
1712     }


1736         return getSystemEventQueueImpl();
1737     }
1738 
1739     /**
1740      * Gets the application's or applet's <code>EventQueue</code>
1741      * instance, without checking access.  For security reasons,
1742      * this can only be called from a <code>Toolkit</code> subclass.
1743      * @return the <code>EventQueue</code> object
1744      */
1745     protected abstract EventQueue getSystemEventQueueImpl();
1746 
1747     /* Accessor method for use by AWT package routines. */
1748     static EventQueue getEventQueue() {
1749         return getDefaultToolkit().getSystemEventQueueImpl();
1750     }
1751 
1752     /**
1753      * Creates the peer for a DragSourceContext.
1754      * Always throws InvalidDndOperationException if
1755      * GraphicsEnvironment.isHeadless() returns true.
1756      * @param dge  the {@code DragGestureEvent}
1757      * @return  the peer created
1758      * @see java.awt.GraphicsEnvironment#isHeadless
1759      */
1760     public abstract DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException;
1761 
1762     /**
1763      * Creates a concrete, platform dependent, subclass of the abstract
1764      * DragGestureRecognizer class requested, and associates it with the
1765      * DragSource, Component and DragGestureListener specified.
1766      *
1767      * subclasses should override this to provide their own implementation
1768      *
1769      * @param abstractRecognizerClass The abstract class of the required recognizer
1770      * @param ds                      The DragSource
1771      * @param c                       The Component target for the DragGestureRecognizer
1772      * @param srcActions              The actions permitted for the gesture
1773      * @param dgl                     The DragGestureListener
1774      *
1775      * @return the new object or null.  Always returns null if
1776      * GraphicsEnvironment.isHeadless() returns true.
1777      * @see java.awt.GraphicsEnvironment#isHeadless
1778      */
1779     public <T extends DragGestureRecognizer> T
1780         createDragGestureRecognizer(Class<T> abstractRecognizerClass,
1781                                     DragSource ds, Component c, int srcActions,
1782                                     DragGestureListener dgl)
1783     {
1784         return null;
1785     }
1786 
1787     /**
1788      * Obtains a value for the specified desktop property.
1789      *
1790      * A desktop property is a uniquely named value for a resource that
1791      * is Toolkit global in nature. Usually it also is an abstract
1792      * representation for an underlying platform dependent desktop setting.
1793      * For more information on desktop properties supported by the AWT see
1794      * <a href="doc-files/DesktopProperties.html">AWT Desktop Properties</a>.
1795      *
1796      * @param   propertyName  the property name
1797      * @return  the value for the specified desktop property
1798      */
1799     public final synchronized Object getDesktopProperty(String propertyName) {
1800         // This is a workaround for headless toolkits.  It would be
1801         // better to override this method but it is declared final.
1802         // "this instanceof" syntax defeats polymorphism.
1803         // --mm, 03/03/00
1804         if (this instanceof HeadlessToolkit) {
1805             return ((HeadlessToolkit)this).getUnderlyingToolkit()
1806                 .getDesktopProperty(propertyName);
1807         }
1808 
1809         if (desktopProperties.isEmpty()) {
1810             initializeDesktopProperties();
1811         }
1812 
1813         Object value;
1814 
1815         // This property should never be cached
1816         if (propertyName.equals("awt.dynamicLayoutSupported")) {
1817             return getDefaultToolkit().lazilyLoadDesktopProperty(propertyName);


1821 
1822         if (value == null) {
1823             value = lazilyLoadDesktopProperty(propertyName);
1824 
1825             if (value != null) {
1826                 setDesktopProperty(propertyName, value);
1827             }
1828         }
1829 
1830         /* for property "awt.font.desktophints" */
1831         if (value instanceof RenderingHints) {
1832             value = ((RenderingHints)value).clone();
1833         }
1834 
1835         return value;
1836     }
1837 
1838     /**
1839      * Sets the named desktop property to the specified value and fires a
1840      * property change event to notify any listeners that the value has changed.
1841      * @param name      the property name
1842      * @param newValue  the new property value
1843      */
1844     protected final void setDesktopProperty(String name, Object newValue) {
1845         // This is a workaround for headless toolkits.  It would be
1846         // better to override this method but it is declared final.
1847         // "this instanceof" syntax defeats polymorphism.
1848         // --mm, 03/03/00
1849         if (this instanceof HeadlessToolkit) {
1850             ((HeadlessToolkit)this).getUnderlyingToolkit()
1851                 .setDesktopProperty(name, newValue);
1852             return;
1853         }
1854         Object oldValue;
1855 
1856         synchronized (this) {
1857             oldValue = desktopProperties.get(name);
1858             desktopProperties.put(name, newValue);
1859         }
1860 
1861         // Don't fire change event if old and new values are null.
1862         // It helps to avoid recursive resending of WM_THEMECHANGED