< prev index next >

src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java

Print this page




  33 import java.text.*;
  34 import java.util.*;
  35 import javax.swing.*;
  36 import javax.swing.plaf.*;
  37 import javax.swing.plaf.basic.*;
  38 
  39 import sun.awt.*;
  40 import sun.security.action.*;
  41 import sun.swing.*;
  42 import sun.swing.plaf.synth.*;
  43 
  44 /**
  45  * SynthLookAndFeel provides the basis for creating a customized look and
  46  * feel. SynthLookAndFeel does not directly provide a look, all painting is
  47  * delegated.
  48  * You need to either provide a configuration file, by way of the
  49  * {@link #load} method, or provide your own {@link SynthStyleFactory}
  50  * to {@link #setStyleFactory}. Refer to the
  51  * <a href="package-summary.html">package summary</a> for an example of
  52  * loading a file, and {@link javax.swing.plaf.synth.SynthStyleFactory} for
  53  * an example of providing your own <code>SynthStyleFactory</code> to
  54  * <code>setStyleFactory</code>.
  55  * <p>
  56  * <strong>Warning:</strong>
  57  * This class implements {@link Serializable} as a side effect of it
  58  * extending {@link BasicLookAndFeel}. It is not intended to be serialized.
  59  * An attempt to serialize it will
  60  * result in {@link NotSerializableException}.
  61  *
  62  * @serial exclude
  63  * @since 1.5
  64  * @author Scott Violet
  65  */
  66 @SuppressWarnings("serial") // Per above comment, not actually serializable
  67 public class SynthLookAndFeel extends BasicLookAndFeel {
  68     /**
  69      * Used in a handful of places where we need an empty Insets.
  70      */
  71     static final Insets EMPTY_UIRESOURCE_INSETS = new InsetsUIResource(
  72                                                             0, 0, 0, 0);
  73 
  74     /**
  75      * AppContext key to get the current SynthStyleFactory.
  76      */
  77     private static final Object STYLE_FACTORY_KEY =
  78                   new StringBuffer("com.sun.java.swing.plaf.gtk.StyleCache");
  79 
  80     /**
  81      * AppContext key to get selectedUI.
  82      */
  83     private static final Object SELECTED_UI_KEY = new StringBuilder("selectedUI");
  84 
  85     /**
  86      * AppContext key to get selectedUIState.
  87      */
  88     private static final Object SELECTED_UI_STATE_KEY = new StringBuilder("selectedUIState");
  89 
  90     /**
  91      * The last SynthStyleFactory that was asked for from AppContext
  92      * <code>lastContext</code>.
  93      */
  94     private static SynthStyleFactory lastFactory;
  95     /**
  96      * AppContext lastLAF came from.
  97      */
  98     private static AppContext lastContext;
  99 
 100     /**
 101      * SynthStyleFactory for the this SynthLookAndFeel.
 102      */
 103     private SynthStyleFactory factory;
 104 
 105     /**
 106      * Map of defaults table entries. This is populated via the load
 107      * method.
 108      */
 109     private Map<String, Object> defaultsMap;
 110 
 111     private Handler _handler;
 112 
 113     static ComponentUI getSelectedUI() {
 114         return (ComponentUI) AppContext.getAppContext().get(SELECTED_UI_KEY);
 115     }
 116 
 117     /**
 118      * Used by the renderers. For the most part the renderers are implemented
 119      * as Labels, which is problematic in so far as they are never selected.
 120      * To accommodate this SynthLabelUI checks if the current
 121      * UI matches that of <code>selectedUI</code> (which this methods sets), if
 122      * it does, then a state as set by this method is returned. This provides
 123      * a way for labels to have a state other than selected.
 124      */
 125     static void setSelectedUI(ComponentUI uix, boolean selected,
 126                               boolean focused, boolean enabled,
 127                               boolean rollover) {
 128         int selectedUIState = 0;
 129 
 130         if (selected) {
 131             selectedUIState = SynthConstants.SELECTED;
 132             if (focused) {
 133                 selectedUIState |= SynthConstants.FOCUSED;
 134             }
 135         }
 136         else if (rollover && enabled) {
 137             selectedUIState |=
 138                     SynthConstants.MOUSE_OVER | SynthConstants.ENABLED;
 139             if (focused) {
 140                 selectedUIState |= SynthConstants.FOCUSED;
 141             }


 222         }
 223         return SynthUI.DISABLED;
 224     }
 225 
 226     /**
 227      * Gets a SynthStyle for the specified region of the specified component.
 228      * This is not for general consumption, only custom UIs should call this
 229      * method.
 230      *
 231      * @param c JComponent to get the SynthStyle for
 232      * @param region Identifies the region of the specified component
 233      * @return SynthStyle to use.
 234      */
 235     public static SynthStyle getStyle(JComponent c, Region region) {
 236         return getStyleFactory().getStyle(c, region);
 237     }
 238 
 239     /**
 240      * Returns true if the Style should be updated in response to the
 241      * specified PropertyChangeEvent. This forwards to
 242      * <code>shouldUpdateStyleOnAncestorChanged</code> as necessary.
 243      */
 244     static boolean shouldUpdateStyle(PropertyChangeEvent event) {
 245         LookAndFeel laf = UIManager.getLookAndFeel();
 246         return (laf instanceof SynthLookAndFeel &&
 247                 ((SynthLookAndFeel) laf).shouldUpdateStyleOnEvent(event));
 248     }
 249 
 250     /**
 251      * A convience method that will reset the Style of StyleContext if
 252      * necessary.
 253      *
 254      * @return newStyle
 255      */
 256     static SynthStyle updateStyle(SynthContext context, SynthUI ui) {
 257         SynthStyle newStyle = getStyle(context.getComponent(),
 258                                        context.getRegion());
 259         SynthStyle oldStyle = context.getStyle();
 260 
 261         if (newStyle != oldStyle) {
 262             if (oldStyle != null) {
 263                 oldStyle.uninstallDefaults(context);
 264             }
 265             context.setStyle(newStyle);
 266             newStyle.installDefaults(context, ui);
 267         }
 268         return newStyle;
 269     }
 270 
 271     /**
 272      * Updates the style associated with <code>c</code>, and all its children.
 273      * This is a lighter version of
 274      * <code>SwingUtilities.updateComponentTreeUI</code>.
 275      *
 276      * @param c Component to update style for.
 277      */
 278     public static void updateStyles(Component c) {
 279         if (c instanceof JComponent) {
 280             // Yes, this is hacky. A better solution is to get the UI
 281             // and cast, but JComponent doesn't expose a getter for the UI
 282             // (each of the UIs do), making that approach impractical.
 283             String name = c.getName();
 284             c.setName(null);
 285             if (name != null) {
 286                 c.setName(name);
 287             }
 288             ((JComponent)c).revalidate();
 289         }
 290         Component[] children = null;
 291         if (c instanceof JMenu) {
 292             children = ((JMenu)c).getMenuComponents();
 293         }
 294         else if (c instanceof Container) {
 295             children = ((Container)c).getComponents();
 296         }
 297         if (children != null) {
 298             for (Component child : children) {
 299                 updateStyles(child);
 300             }
 301         }
 302         c.repaint();
 303     }
 304 
 305     /**
 306      * Returns the Region for the JComponent <code>c</code>.
 307      *
 308      * @param c JComponent to fetch the Region for
 309      * @return Region corresponding to <code>c</code>
 310      */
 311     public static Region getRegion(JComponent c) {
 312         return Region.getRegion(c);
 313     }
 314 
 315     /**
 316      * A convenience method to return where the foreground should be
 317      * painted for the Component identified by the passed in
 318      * AbstractSynthContext.
 319      */
 320     static Insets getPaintingInsets(SynthContext state, Insets insets) {
 321         if (state.isSubregion()) {
 322             insets = state.getStyle().getInsets(state, insets);
 323         }
 324         else {
 325             insets = state.getComponent().getInsets(insets);
 326         }
 327         return insets;
 328     }
 329 


 362             x = bounds.x;
 363             y = bounds.y;
 364             width = bounds.width;
 365             height = bounds.height;
 366         }
 367 
 368         // Fill in the background, if necessary.
 369         boolean subregion = state.isSubregion();
 370         if ((subregion && style.isOpaque(state)) ||
 371                           (!subregion && c.isOpaque())) {
 372             g.setColor(style.getColor(state, ColorType.BACKGROUND));
 373             g.fillRect(x, y, width, height);
 374         }
 375     }
 376 
 377     static boolean isLeftToRight(Component c) {
 378         return c.getComponentOrientation().isLeftToRight();
 379     }
 380 
 381     /**
 382      * Returns the ui that is of type <code>klass</code>, or null if
 383      * one can not be found.
 384      */
 385     static Object getUIOfType(ComponentUI ui, Class<?> klass) {
 386         if (klass.isInstance(ui)) {
 387             return ui;
 388         }
 389         return null;
 390     }
 391 
 392     /**
 393      * Creates the Synth look and feel <code>ComponentUI</code> for
 394      * the passed in <code>JComponent</code>.
 395      *
 396      * @param c JComponent to create the <code>ComponentUI</code> for
 397      * @return ComponentUI to use for <code>c</code>
 398      */
 399     public static ComponentUI createUI(JComponent c) {
 400         String key = c.getUIClassID().intern();
 401 
 402         if (key == "ButtonUI") {
 403             return SynthButtonUI.createUI(c);
 404         }
 405         else if (key == "CheckBoxUI") {
 406             return SynthCheckBoxUI.createUI(c);
 407         }
 408         else if (key == "CheckBoxMenuItemUI") {
 409             return SynthCheckBoxMenuItemUI.createUI(c);
 410         }
 411         else if (key == "ColorChooserUI") {
 412             return SynthColorChooserUI.createUI(c);
 413         }
 414         else if (key == "ComboBoxUI") {
 415             return SynthComboBoxUI.createUI(c);
 416         }
 417         else if (key == "DesktopPaneUI") {


 518         }
 519         else if (key == "ToolBarUI") {
 520             return SynthToolBarUI.createUI(c);
 521         }
 522         else if (key == "ToolTipUI") {
 523             return SynthToolTipUI.createUI(c);
 524         }
 525         else if (key == "TreeUI") {
 526             return SynthTreeUI.createUI(c);
 527         }
 528         else if (key == "ViewportUI") {
 529             return SynthViewportUI.createUI(c);
 530         }
 531         return null;
 532     }
 533 
 534 
 535     /**
 536      * Creates a SynthLookAndFeel.
 537      * <p>
 538      * For the returned <code>SynthLookAndFeel</code> to be useful you need to
 539      * invoke <code>load</code> to specify the set of
 540      * <code>SynthStyle</code>s, or invoke <code>setStyleFactory</code>.
 541      *
 542      * @see #load
 543      * @see #setStyleFactory
 544      */
 545     public SynthLookAndFeel() {
 546         factory = new DefaultSynthStyleFactory();
 547         _handler = new Handler();
 548     }
 549 
 550     /**
 551      * Loads the set of <code>SynthStyle</code>s that will be used by
 552      * this <code>SynthLookAndFeel</code>. <code>resourceBase</code> is
 553      * used to resolve any path based resources, for example an
 554      * <code>Image</code> would be resolved by
 555      * <code>resourceBase.getResource(path)</code>. Refer to
 556      * <a href="doc-files/synthFileFormat.html">Synth File Format</a>
 557      * for more information.
 558      *
 559      * @param input InputStream to load from
 560      * @param resourceBase used to resolve any images or other resources
 561      * @throws ParseException if there is an error in parsing
 562      * @throws IllegalArgumentException if input or resourceBase is <code>null</code>
 563      */
 564     public void load(InputStream input, Class<?> resourceBase) throws
 565                        ParseException {
 566         if (resourceBase == null) {
 567             throw new IllegalArgumentException(
 568                 "You must supply a valid resource base Class");
 569         }
 570 
 571         if (defaultsMap == null) {
 572             defaultsMap = new HashMap<String, Object>();
 573         }
 574 
 575         new SynthParser().parse(input, (DefaultSynthStyleFactory) factory,
 576                                 null, resourceBase, defaultsMap);
 577     }
 578 
 579     /**
 580      * Loads the set of <code>SynthStyle</code>s that will be used by
 581      * this <code>SynthLookAndFeel</code>. Path based resources are resolved
 582      * relatively to the specified <code>URL</code> of the style. For example
 583      * an <code>Image</code> would be resolved by
 584      * <code>new URL(synthFile, path)</code>. Refer to
 585      * <a href="doc-files/synthFileFormat.html">Synth File Format</a> for more
 586      * information.
 587      *
 588      * @param url the <code>URL</code> to load the set of
 589      *     <code>SynthStyle</code> from
 590      * @throws ParseException if there is an error in parsing
 591      * @throws IllegalArgumentException if synthSet is <code>null</code>
 592      * @throws IOException if synthSet cannot be opened as an <code>InputStream</code>
 593      * @since 1.6
 594      */
 595     public void load(URL url) throws ParseException, IOException {
 596         if (url == null) {
 597             throw new IllegalArgumentException(
 598                 "You must supply a valid Synth set URL");
 599         }
 600 
 601         if (defaultsMap == null) {
 602             defaultsMap = new HashMap<String, Object>();
 603         }
 604 
 605         InputStream input = url.openStream();
 606         new SynthParser().parse(input, (DefaultSynthStyleFactory) factory,
 607                                 url, null, defaultsMap);
 608     }
 609 
 610     /**
 611      * Called by UIManager when this look and feel is installed.
 612      */


 732      *
 733      * @return a short string identifying this look and feel.
 734      */
 735     @Override
 736     public String getName() {
 737         return "Synth look and feel";
 738     }
 739 
 740     /**
 741      * Return a string that identifies this look and feel.
 742      *
 743      * @return a short string identifying this look and feel.
 744      */
 745     @Override
 746     public String getID() {
 747         return "Synth";
 748     }
 749 
 750     /**
 751      * Returns whether or not the UIs should update their
 752      * <code>SynthStyles</code> from the <code>SynthStyleFactory</code>
 753      * when the ancestor of the <code>JComponent</code> changes. A subclass
 754      * that provided a <code>SynthStyleFactory</code> that based the
 755      * return value from <code>getStyle</code> off the containment hierarchy
 756      * would override this method to return true.
 757      *
 758      * @return whether or not the UIs should update their
 759      * <code>SynthStyles</code> from the <code>SynthStyleFactory</code>
 760      * when the ancestor changed.
 761      */
 762     public boolean shouldUpdateStyleOnAncestorChanged() {
 763         return false;
 764     }
 765 
 766     /**
 767      * Returns whether or not the UIs should update their styles when a
 768      * particular event occurs.
 769      *
 770      * @param ev a {@code PropertyChangeEvent}
 771      * @return whether or not the UIs should update their styles
 772      * @since 1.7
 773      */
 774     protected boolean shouldUpdateStyleOnEvent(PropertyChangeEvent ev) {
 775         String eName = ev.getPropertyName();
 776         if ("name" == eName || "componentOrientation" == eName) {
 777             return true;
 778         }
 779         if ("ancestor" == eName && ev.getNewValue() != null) {




  33 import java.text.*;
  34 import java.util.*;
  35 import javax.swing.*;
  36 import javax.swing.plaf.*;
  37 import javax.swing.plaf.basic.*;
  38 
  39 import sun.awt.*;
  40 import sun.security.action.*;
  41 import sun.swing.*;
  42 import sun.swing.plaf.synth.*;
  43 
  44 /**
  45  * SynthLookAndFeel provides the basis for creating a customized look and
  46  * feel. SynthLookAndFeel does not directly provide a look, all painting is
  47  * delegated.
  48  * You need to either provide a configuration file, by way of the
  49  * {@link #load} method, or provide your own {@link SynthStyleFactory}
  50  * to {@link #setStyleFactory}. Refer to the
  51  * <a href="package-summary.html">package summary</a> for an example of
  52  * loading a file, and {@link javax.swing.plaf.synth.SynthStyleFactory} for
  53  * an example of providing your own {@code SynthStyleFactory} to
  54  * {@code setStyleFactory}.
  55  * <p>
  56  * <strong>Warning:</strong>
  57  * This class implements {@link Serializable} as a side effect of it
  58  * extending {@link BasicLookAndFeel}. It is not intended to be serialized.
  59  * An attempt to serialize it will
  60  * result in {@link NotSerializableException}.
  61  *
  62  * @serial exclude
  63  * @since 1.5
  64  * @author Scott Violet
  65  */
  66 @SuppressWarnings("serial") // Per above comment, not actually serializable
  67 public class SynthLookAndFeel extends BasicLookAndFeel {
  68     /**
  69      * Used in a handful of places where we need an empty Insets.
  70      */
  71     static final Insets EMPTY_UIRESOURCE_INSETS = new InsetsUIResource(
  72                                                             0, 0, 0, 0);
  73 
  74     /**
  75      * AppContext key to get the current SynthStyleFactory.
  76      */
  77     private static final Object STYLE_FACTORY_KEY =
  78                   new StringBuffer("com.sun.java.swing.plaf.gtk.StyleCache");
  79 
  80     /**
  81      * AppContext key to get selectedUI.
  82      */
  83     private static final Object SELECTED_UI_KEY = new StringBuilder("selectedUI");
  84 
  85     /**
  86      * AppContext key to get selectedUIState.
  87      */
  88     private static final Object SELECTED_UI_STATE_KEY = new StringBuilder("selectedUIState");
  89 
  90     /**
  91      * The last SynthStyleFactory that was asked for from AppContext
  92      * {@code lastContext}.
  93      */
  94     private static SynthStyleFactory lastFactory;
  95     /**
  96      * AppContext lastLAF came from.
  97      */
  98     private static AppContext lastContext;
  99 
 100     /**
 101      * SynthStyleFactory for the this SynthLookAndFeel.
 102      */
 103     private SynthStyleFactory factory;
 104 
 105     /**
 106      * Map of defaults table entries. This is populated via the load
 107      * method.
 108      */
 109     private Map<String, Object> defaultsMap;
 110 
 111     private Handler _handler;
 112 
 113     static ComponentUI getSelectedUI() {
 114         return (ComponentUI) AppContext.getAppContext().get(SELECTED_UI_KEY);
 115     }
 116 
 117     /**
 118      * Used by the renderers. For the most part the renderers are implemented
 119      * as Labels, which is problematic in so far as they are never selected.
 120      * To accommodate this SynthLabelUI checks if the current
 121      * UI matches that of {@code selectedUI} (which this methods sets), if
 122      * it does, then a state as set by this method is returned. This provides
 123      * a way for labels to have a state other than selected.
 124      */
 125     static void setSelectedUI(ComponentUI uix, boolean selected,
 126                               boolean focused, boolean enabled,
 127                               boolean rollover) {
 128         int selectedUIState = 0;
 129 
 130         if (selected) {
 131             selectedUIState = SynthConstants.SELECTED;
 132             if (focused) {
 133                 selectedUIState |= SynthConstants.FOCUSED;
 134             }
 135         }
 136         else if (rollover && enabled) {
 137             selectedUIState |=
 138                     SynthConstants.MOUSE_OVER | SynthConstants.ENABLED;
 139             if (focused) {
 140                 selectedUIState |= SynthConstants.FOCUSED;
 141             }


 222         }
 223         return SynthUI.DISABLED;
 224     }
 225 
 226     /**
 227      * Gets a SynthStyle for the specified region of the specified component.
 228      * This is not for general consumption, only custom UIs should call this
 229      * method.
 230      *
 231      * @param c JComponent to get the SynthStyle for
 232      * @param region Identifies the region of the specified component
 233      * @return SynthStyle to use.
 234      */
 235     public static SynthStyle getStyle(JComponent c, Region region) {
 236         return getStyleFactory().getStyle(c, region);
 237     }
 238 
 239     /**
 240      * Returns true if the Style should be updated in response to the
 241      * specified PropertyChangeEvent. This forwards to
 242      * {@code shouldUpdateStyleOnAncestorChanged} as necessary.
 243      */
 244     static boolean shouldUpdateStyle(PropertyChangeEvent event) {
 245         LookAndFeel laf = UIManager.getLookAndFeel();
 246         return (laf instanceof SynthLookAndFeel &&
 247                 ((SynthLookAndFeel) laf).shouldUpdateStyleOnEvent(event));
 248     }
 249 
 250     /**
 251      * A convience method that will reset the Style of StyleContext if
 252      * necessary.
 253      *
 254      * @return newStyle
 255      */
 256     static SynthStyle updateStyle(SynthContext context, SynthUI ui) {
 257         SynthStyle newStyle = getStyle(context.getComponent(),
 258                                        context.getRegion());
 259         SynthStyle oldStyle = context.getStyle();
 260 
 261         if (newStyle != oldStyle) {
 262             if (oldStyle != null) {
 263                 oldStyle.uninstallDefaults(context);
 264             }
 265             context.setStyle(newStyle);
 266             newStyle.installDefaults(context, ui);
 267         }
 268         return newStyle;
 269     }
 270 
 271     /**
 272      * Updates the style associated with {@code c}, and all its children.
 273      * This is a lighter version of
 274      * {@code SwingUtilities.updateComponentTreeUI}.
 275      *
 276      * @param c Component to update style for.
 277      */
 278     public static void updateStyles(Component c) {
 279         if (c instanceof JComponent) {
 280             // Yes, this is hacky. A better solution is to get the UI
 281             // and cast, but JComponent doesn't expose a getter for the UI
 282             // (each of the UIs do), making that approach impractical.
 283             String name = c.getName();
 284             c.setName(null);
 285             if (name != null) {
 286                 c.setName(name);
 287             }
 288             ((JComponent)c).revalidate();
 289         }
 290         Component[] children = null;
 291         if (c instanceof JMenu) {
 292             children = ((JMenu)c).getMenuComponents();
 293         }
 294         else if (c instanceof Container) {
 295             children = ((Container)c).getComponents();
 296         }
 297         if (children != null) {
 298             for (Component child : children) {
 299                 updateStyles(child);
 300             }
 301         }
 302         c.repaint();
 303     }
 304 
 305     /**
 306      * Returns the Region for the JComponent {@code c}.
 307      *
 308      * @param c JComponent to fetch the Region for
 309      * @return Region corresponding to {@code c}
 310      */
 311     public static Region getRegion(JComponent c) {
 312         return Region.getRegion(c);
 313     }
 314 
 315     /**
 316      * A convenience method to return where the foreground should be
 317      * painted for the Component identified by the passed in
 318      * AbstractSynthContext.
 319      */
 320     static Insets getPaintingInsets(SynthContext state, Insets insets) {
 321         if (state.isSubregion()) {
 322             insets = state.getStyle().getInsets(state, insets);
 323         }
 324         else {
 325             insets = state.getComponent().getInsets(insets);
 326         }
 327         return insets;
 328     }
 329 


 362             x = bounds.x;
 363             y = bounds.y;
 364             width = bounds.width;
 365             height = bounds.height;
 366         }
 367 
 368         // Fill in the background, if necessary.
 369         boolean subregion = state.isSubregion();
 370         if ((subregion && style.isOpaque(state)) ||
 371                           (!subregion && c.isOpaque())) {
 372             g.setColor(style.getColor(state, ColorType.BACKGROUND));
 373             g.fillRect(x, y, width, height);
 374         }
 375     }
 376 
 377     static boolean isLeftToRight(Component c) {
 378         return c.getComponentOrientation().isLeftToRight();
 379     }
 380 
 381     /**
 382      * Returns the ui that is of type {@code klass}, or null if
 383      * one can not be found.
 384      */
 385     static Object getUIOfType(ComponentUI ui, Class<?> klass) {
 386         if (klass.isInstance(ui)) {
 387             return ui;
 388         }
 389         return null;
 390     }
 391 
 392     /**
 393      * Creates the Synth look and feel {@code ComponentUI} for
 394      * the passed in {@code JComponent}.
 395      *
 396      * @param c JComponent to create the {@code ComponentUI} for
 397      * @return ComponentUI to use for {@code c}
 398      */
 399     public static ComponentUI createUI(JComponent c) {
 400         String key = c.getUIClassID().intern();
 401 
 402         if (key == "ButtonUI") {
 403             return SynthButtonUI.createUI(c);
 404         }
 405         else if (key == "CheckBoxUI") {
 406             return SynthCheckBoxUI.createUI(c);
 407         }
 408         else if (key == "CheckBoxMenuItemUI") {
 409             return SynthCheckBoxMenuItemUI.createUI(c);
 410         }
 411         else if (key == "ColorChooserUI") {
 412             return SynthColorChooserUI.createUI(c);
 413         }
 414         else if (key == "ComboBoxUI") {
 415             return SynthComboBoxUI.createUI(c);
 416         }
 417         else if (key == "DesktopPaneUI") {


 518         }
 519         else if (key == "ToolBarUI") {
 520             return SynthToolBarUI.createUI(c);
 521         }
 522         else if (key == "ToolTipUI") {
 523             return SynthToolTipUI.createUI(c);
 524         }
 525         else if (key == "TreeUI") {
 526             return SynthTreeUI.createUI(c);
 527         }
 528         else if (key == "ViewportUI") {
 529             return SynthViewportUI.createUI(c);
 530         }
 531         return null;
 532     }
 533 
 534 
 535     /**
 536      * Creates a SynthLookAndFeel.
 537      * <p>
 538      * For the returned {@code SynthLookAndFeel} to be useful you need to
 539      * invoke {@code load} to specify the set of
 540      * {@code SynthStyle}s, or invoke {@code setStyleFactory}.
 541      *
 542      * @see #load
 543      * @see #setStyleFactory
 544      */
 545     public SynthLookAndFeel() {
 546         factory = new DefaultSynthStyleFactory();
 547         _handler = new Handler();
 548     }
 549 
 550     /**
 551      * Loads the set of {@code SynthStyle}s that will be used by
 552      * this {@code SynthLookAndFeel}. {@code resourceBase} is
 553      * used to resolve any path based resources, for example an
 554      * {@code Image} would be resolved by
 555      * {@code resourceBase.getResource(path)}. Refer to
 556      * <a href="doc-files/synthFileFormat.html">Synth File Format</a>
 557      * for more information.
 558      *
 559      * @param input InputStream to load from
 560      * @param resourceBase used to resolve any images or other resources
 561      * @throws ParseException if there is an error in parsing
 562      * @throws IllegalArgumentException if input or resourceBase is {@code null}
 563      */
 564     public void load(InputStream input, Class<?> resourceBase) throws
 565                        ParseException {
 566         if (resourceBase == null) {
 567             throw new IllegalArgumentException(
 568                 "You must supply a valid resource base Class");
 569         }
 570 
 571         if (defaultsMap == null) {
 572             defaultsMap = new HashMap<String, Object>();
 573         }
 574 
 575         new SynthParser().parse(input, (DefaultSynthStyleFactory) factory,
 576                                 null, resourceBase, defaultsMap);
 577     }
 578 
 579     /**
 580      * Loads the set of {@code SynthStyle}s that will be used by
 581      * this {@code SynthLookAndFeel}. Path based resources are resolved
 582      * relatively to the specified {@code URL} of the style. For example
 583      * an {@code Image} would be resolved by
 584      * {@code new URL(synthFile, path)}. Refer to
 585      * <a href="doc-files/synthFileFormat.html">Synth File Format</a> for more
 586      * information.
 587      *
 588      * @param url the {@code URL} to load the set of
 589      *     {@code SynthStyle} from
 590      * @throws ParseException if there is an error in parsing
 591      * @throws IllegalArgumentException if synthSet is {@code null}
 592      * @throws IOException if synthSet cannot be opened as an {@code InputStream}
 593      * @since 1.6
 594      */
 595     public void load(URL url) throws ParseException, IOException {
 596         if (url == null) {
 597             throw new IllegalArgumentException(
 598                 "You must supply a valid Synth set URL");
 599         }
 600 
 601         if (defaultsMap == null) {
 602             defaultsMap = new HashMap<String, Object>();
 603         }
 604 
 605         InputStream input = url.openStream();
 606         new SynthParser().parse(input, (DefaultSynthStyleFactory) factory,
 607                                 url, null, defaultsMap);
 608     }
 609 
 610     /**
 611      * Called by UIManager when this look and feel is installed.
 612      */


 732      *
 733      * @return a short string identifying this look and feel.
 734      */
 735     @Override
 736     public String getName() {
 737         return "Synth look and feel";
 738     }
 739 
 740     /**
 741      * Return a string that identifies this look and feel.
 742      *
 743      * @return a short string identifying this look and feel.
 744      */
 745     @Override
 746     public String getID() {
 747         return "Synth";
 748     }
 749 
 750     /**
 751      * Returns whether or not the UIs should update their
 752      * {@code SynthStyles} from the {@code SynthStyleFactory}
 753      * when the ancestor of the {@code JComponent} changes. A subclass
 754      * that provided a {@code SynthStyleFactory} that based the
 755      * return value from {@code getStyle} off the containment hierarchy
 756      * would override this method to return true.
 757      *
 758      * @return whether or not the UIs should update their
 759      * {@code SynthStyles} from the {@code SynthStyleFactory}
 760      * when the ancestor changed.
 761      */
 762     public boolean shouldUpdateStyleOnAncestorChanged() {
 763         return false;
 764     }
 765 
 766     /**
 767      * Returns whether or not the UIs should update their styles when a
 768      * particular event occurs.
 769      *
 770      * @param ev a {@code PropertyChangeEvent}
 771      * @return whether or not the UIs should update their styles
 772      * @since 1.7
 773      */
 774     protected boolean shouldUpdateStyleOnEvent(PropertyChangeEvent ev) {
 775         String eName = ev.getPropertyName();
 776         if ("name" == eName || "componentOrientation" == eName) {
 777             return true;
 778         }
 779         if ("ancestor" == eName && ev.getNewValue() != null) {


< prev index next >