53 * table. Unless otherwise noted each of the {@code ComponentUI}
54 * implementations in this package document the set of defaults they
55 * use. Unless otherwise noted the defaults are installed at the time
56 * {@code installUI} is invoked, and follow the recommendations
57 * outlined in {@code LookAndFeel} for installing defaults.
58 * <p>
59 * {@code MetalLookAndFeel} derives it's color palette and fonts from
60 * {@code MetalTheme}. The default theme is {@code OceanTheme}. The theme
61 * can be changed using the {@code setCurrentTheme} method, refer to it
62 * for details on changing the theme. Prior to 1.5 the default
63 * theme was {@code DefaultMetalTheme}. The system property
64 * {@code "swing.metalTheme"} can be set to {@code "steel"} to indicate
65 * the default should be {@code DefaultMetalTheme}.
66 * <p>
67 * <strong>Warning:</strong>
68 * Serialized objects of this class will not be compatible with
69 * future Swing releases. The current serialization support is
70 * appropriate for short term storage or RMI between applications running
71 * the same version of Swing. As of 1.4, support for long term storage
72 * of all JavaBeans™
73 * has been added to the <code>java.beans</code> package.
74 * Please see {@link java.beans.XMLEncoder}.
75 *
76 * @see MetalTheme
77 * @see DefaultMetalTheme
78 * @see OceanTheme
79 *
80 * @author Steve Wilson
81 */
82 @SuppressWarnings("serial") // Same-version serialization only
83 public class MetalLookAndFeel extends BasicLookAndFeel
84 {
85
86 private static boolean METAL_LOOK_AND_FEEL_INITED = false;
87
88
89 /**
90 * True if checked for windows yet.
91 */
92 private static boolean checkedWindows;
93 /**
1548 METAL_LOOK_AND_FEEL_INITED = true;
1549
1550 createDefaultTheme();
1551 UIDefaults table = super.getDefaults();
1552 MetalTheme currentTheme = getCurrentTheme();
1553 currentTheme.addCustomEntriesToTable(table);
1554 currentTheme.install();
1555 return table;
1556 }
1557
1558 /**
1559 * {@inheritDoc}
1560 *
1561 * @since 1.4
1562 */
1563 public void provideErrorFeedback(Component component) {
1564 super.provideErrorFeedback(component);
1565 }
1566
1567 /**
1568 * Set the theme used by <code>MetalLookAndFeel</code>.
1569 * <p>
1570 * After the theme is set, {@code MetalLookAndFeel} needs to be
1571 * re-installed and the uis need to be recreated. The following
1572 * shows how to do this:
1573 * <pre>
1574 * MetalLookAndFeel.setCurrentTheme(theme);
1575 *
1576 * // re-install the Metal Look and Feel
1577 * UIManager.setLookAndFeel(new MetalLookAndFeel());
1578 *
1579 * // Update the ComponentUIs for all Components. This
1580 * // needs to be invoked for all windows.
1581 * SwingUtilities.updateComponentTreeUI(rootComponent);
1582 * </pre>
1583 * If this is not done the results are undefined.
1584 *
1585 * @param theme the theme to use
1586 * @throws NullPointerException if {@code theme} is {@code null}
1587 * @see #getCurrentTheme
1588 */
1589 public static void setCurrentTheme(MetalTheme theme) {
1590 // NOTE: because you need to recreate the look and feel after
1591 // this step, we don't bother blowing away any potential windows
1592 // values.
1593 if (theme == null) {
1594 throw new NullPointerException("Can't have null theme");
1595 }
1596 AppContext.getAppContext().put( "currentMetalTheme", theme );
1597 }
1598
1599 /**
1600 * Return the theme currently being used by <code>MetalLookAndFeel</code>.
1601 * If the current theme is {@code null}, the default theme is created.
1602 *
1603 * @return the current theme
1604 * @see #setCurrentTheme
1605 * @since 1.5
1606 */
1607 public static MetalTheme getCurrentTheme() {
1608 MetalTheme currentTheme;
1609 AppContext context = AppContext.getAppContext();
1610 currentTheme = (MetalTheme) context.get( "currentMetalTheme" );
1611 if (currentTheme == null) {
1612 // This will happen in two cases:
1613 // . When MetalLookAndFeel is first being initialized.
1614 // . When a new AppContext has been created that hasn't
1615 // triggered UIManager to load a LAF. Rather than invoke
1616 // a method on the UIManager, which would trigger the loading
1617 // of a potentially different LAF, we directly set the
1618 // Theme here.
1619 if (useHighContrastTheme()) {
1620 currentTheme = new MetalHighContrastTheme();
1621 }
1622 else {
1623 // Create the default theme. We prefer Ocean, but will
1624 // use DefaultMetalTheme if told to.
1625 String theme = AccessController.doPrivileged(
1626 new GetPropertyAction("swing.metalTheme"));
1627 if ("steel".equals(theme)) {
1628 currentTheme = new DefaultMetalTheme();
1629 }
1630 else {
1631 currentTheme = new OceanTheme();
1632 }
1633 }
1634 setCurrentTheme(currentTheme);
1635 }
1636 return currentTheme;
1637 }
1638
1639 /**
1640 * Returns an <code>Icon</code> with a disabled appearance.
1641 * This method is used to generate a disabled <code>Icon</code> when
1642 * one has not been specified. For example, if you create a
1643 * <code>JButton</code> and only specify an <code>Icon</code> via
1644 * <code>setIcon</code> this method will be called to generate the
1645 * disabled <code>Icon</code>. If null is passed as <code>icon</code>
1646 * this method returns null.
1647 * <p>
1648 * Some look and feels might not render the disabled Icon, in which
1649 * case they will ignore this.
1650 *
1651 * @param component JComponent that will display the Icon, may be null
1652 * @param icon Icon to generate disable icon from.
1653 * @return Disabled icon, or null if a suitable Icon can not be
1654 * generated.
1655 * @since 1.5
1656 */
1657 public Icon getDisabledIcon(JComponent component, Icon icon) {
1658 if ((icon instanceof ImageIcon) && MetalLookAndFeel.usingOcean()) {
1659 return MetalUtils.getOceanDisabledButtonIcon(
1660 ((ImageIcon)icon).getImage());
1661 }
1662 return super.getDisabledIcon(component, icon);
1663 }
1664
1665 /**
1666 * Returns an <code>Icon</code> for use by disabled
1667 * components that are also selected. This method is used to generate an
1668 * <code>Icon</code> for components that are in both the disabled and
1669 * selected states but do not have a specific <code>Icon</code> for this
1670 * state. For example, if you create a <code>JButton</code> and only
1671 * specify an <code>Icon</code> via <code>setIcon</code> this method
1672 * will be called to generate the disabled and selected
1673 * <code>Icon</code>. If null is passed as <code>icon</code> this method
1674 * returns null.
1675 * <p>
1676 * Some look and feels might not render the disabled and selected Icon,
1677 * in which case they will ignore this.
1678 *
1679 * @param component JComponent that will display the Icon, may be null
1680 * @param icon Icon to generate disabled and selected icon from.
1681 * @return Disabled and Selected icon, or null if a suitable Icon can not
1682 * be generated.
1683 * @since 1.5
1684 */
1685 public Icon getDisabledSelectedIcon(JComponent component, Icon icon) {
1686 if ((icon instanceof ImageIcon) && MetalLookAndFeel.usingOcean()) {
1687 return MetalUtils.getOceanDisabledButtonIcon(
1688 ((ImageIcon)icon).getImage());
1689 }
1690 return super.getDisabledSelectedIcon(component, icon);
1691 }
1692
1693 /**
|
53 * table. Unless otherwise noted each of the {@code ComponentUI}
54 * implementations in this package document the set of defaults they
55 * use. Unless otherwise noted the defaults are installed at the time
56 * {@code installUI} is invoked, and follow the recommendations
57 * outlined in {@code LookAndFeel} for installing defaults.
58 * <p>
59 * {@code MetalLookAndFeel} derives it's color palette and fonts from
60 * {@code MetalTheme}. The default theme is {@code OceanTheme}. The theme
61 * can be changed using the {@code setCurrentTheme} method, refer to it
62 * for details on changing the theme. Prior to 1.5 the default
63 * theme was {@code DefaultMetalTheme}. The system property
64 * {@code "swing.metalTheme"} can be set to {@code "steel"} to indicate
65 * the default should be {@code DefaultMetalTheme}.
66 * <p>
67 * <strong>Warning:</strong>
68 * Serialized objects of this class will not be compatible with
69 * future Swing releases. The current serialization support is
70 * appropriate for short term storage or RMI between applications running
71 * the same version of Swing. As of 1.4, support for long term storage
72 * of all JavaBeans™
73 * has been added to the {@code java.beans} package.
74 * Please see {@link java.beans.XMLEncoder}.
75 *
76 * @see MetalTheme
77 * @see DefaultMetalTheme
78 * @see OceanTheme
79 *
80 * @author Steve Wilson
81 */
82 @SuppressWarnings("serial") // Same-version serialization only
83 public class MetalLookAndFeel extends BasicLookAndFeel
84 {
85
86 private static boolean METAL_LOOK_AND_FEEL_INITED = false;
87
88
89 /**
90 * True if checked for windows yet.
91 */
92 private static boolean checkedWindows;
93 /**
1548 METAL_LOOK_AND_FEEL_INITED = true;
1549
1550 createDefaultTheme();
1551 UIDefaults table = super.getDefaults();
1552 MetalTheme currentTheme = getCurrentTheme();
1553 currentTheme.addCustomEntriesToTable(table);
1554 currentTheme.install();
1555 return table;
1556 }
1557
1558 /**
1559 * {@inheritDoc}
1560 *
1561 * @since 1.4
1562 */
1563 public void provideErrorFeedback(Component component) {
1564 super.provideErrorFeedback(component);
1565 }
1566
1567 /**
1568 * Set the theme used by {@code MetalLookAndFeel}.
1569 * <p>
1570 * After the theme is set, {@code MetalLookAndFeel} needs to be
1571 * re-installed and the uis need to be recreated. The following
1572 * shows how to do this:
1573 * <pre>
1574 * MetalLookAndFeel.setCurrentTheme(theme);
1575 *
1576 * // re-install the Metal Look and Feel
1577 * UIManager.setLookAndFeel(new MetalLookAndFeel());
1578 *
1579 * // Update the ComponentUIs for all Components. This
1580 * // needs to be invoked for all windows.
1581 * SwingUtilities.updateComponentTreeUI(rootComponent);
1582 * </pre>
1583 * If this is not done the results are undefined.
1584 *
1585 * @param theme the theme to use
1586 * @throws NullPointerException if {@code theme} is {@code null}
1587 * @see #getCurrentTheme
1588 */
1589 public static void setCurrentTheme(MetalTheme theme) {
1590 // NOTE: because you need to recreate the look and feel after
1591 // this step, we don't bother blowing away any potential windows
1592 // values.
1593 if (theme == null) {
1594 throw new NullPointerException("Can't have null theme");
1595 }
1596 AppContext.getAppContext().put( "currentMetalTheme", theme );
1597 }
1598
1599 /**
1600 * Return the theme currently being used by {@code MetalLookAndFeel}.
1601 * If the current theme is {@code null}, the default theme is created.
1602 *
1603 * @return the current theme
1604 * @see #setCurrentTheme
1605 * @since 1.5
1606 */
1607 public static MetalTheme getCurrentTheme() {
1608 MetalTheme currentTheme;
1609 AppContext context = AppContext.getAppContext();
1610 currentTheme = (MetalTheme) context.get( "currentMetalTheme" );
1611 if (currentTheme == null) {
1612 // This will happen in two cases:
1613 // . When MetalLookAndFeel is first being initialized.
1614 // . When a new AppContext has been created that hasn't
1615 // triggered UIManager to load a LAF. Rather than invoke
1616 // a method on the UIManager, which would trigger the loading
1617 // of a potentially different LAF, we directly set the
1618 // Theme here.
1619 if (useHighContrastTheme()) {
1620 currentTheme = new MetalHighContrastTheme();
1621 }
1622 else {
1623 // Create the default theme. We prefer Ocean, but will
1624 // use DefaultMetalTheme if told to.
1625 String theme = AccessController.doPrivileged(
1626 new GetPropertyAction("swing.metalTheme"));
1627 if ("steel".equals(theme)) {
1628 currentTheme = new DefaultMetalTheme();
1629 }
1630 else {
1631 currentTheme = new OceanTheme();
1632 }
1633 }
1634 setCurrentTheme(currentTheme);
1635 }
1636 return currentTheme;
1637 }
1638
1639 /**
1640 * Returns an {@code Icon} with a disabled appearance.
1641 * This method is used to generate a disabled {@code Icon} when
1642 * one has not been specified. For example, if you create a
1643 * {@code JButton} and only specify an {@code Icon} via
1644 * {@code setIcon} this method will be called to generate the
1645 * disabled {@code Icon}. If null is passed as {@code icon}
1646 * this method returns null.
1647 * <p>
1648 * Some look and feels might not render the disabled Icon, in which
1649 * case they will ignore this.
1650 *
1651 * @param component JComponent that will display the Icon, may be null
1652 * @param icon Icon to generate disable icon from.
1653 * @return Disabled icon, or null if a suitable Icon can not be
1654 * generated.
1655 * @since 1.5
1656 */
1657 public Icon getDisabledIcon(JComponent component, Icon icon) {
1658 if ((icon instanceof ImageIcon) && MetalLookAndFeel.usingOcean()) {
1659 return MetalUtils.getOceanDisabledButtonIcon(
1660 ((ImageIcon)icon).getImage());
1661 }
1662 return super.getDisabledIcon(component, icon);
1663 }
1664
1665 /**
1666 * Returns an {@code Icon} for use by disabled
1667 * components that are also selected. This method is used to generate an
1668 * {@code Icon} for components that are in both the disabled and
1669 * selected states but do not have a specific {@code Icon} for this
1670 * state. For example, if you create a {@code JButton} and only
1671 * specify an {@code Icon} via {@code setIcon} this method
1672 * will be called to generate the disabled and selected
1673 * {@code Icon}. If null is passed as {@code icon} this method
1674 * returns null.
1675 * <p>
1676 * Some look and feels might not render the disabled and selected Icon,
1677 * in which case they will ignore this.
1678 *
1679 * @param component JComponent that will display the Icon, may be null
1680 * @param icon Icon to generate disabled and selected icon from.
1681 * @return Disabled and Selected icon, or null if a suitable Icon can not
1682 * be generated.
1683 * @since 1.5
1684 */
1685 public Icon getDisabledSelectedIcon(JComponent component, Icon icon) {
1686 if ((icon instanceof ImageIcon) && MetalLookAndFeel.usingOcean()) {
1687 return MetalUtils.getOceanDisabledButtonIcon(
1688 ((ImageIcon)icon).getImage());
1689 }
1690 return super.getDisabledSelectedIcon(component, icon);
1691 }
1692
1693 /**
|