< prev index next >

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

Print this page
rev 1580 : 6727661: Code improvement and warnings removing from the swing/plaf packages
Summary: Removed unnecessary castings and other warnings
Reviewed-by: alexp
Contributed-by: Florian Brunner <fbrunnerlist@gmx.ch>


  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 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 accomodate 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 


 309     private static void _updateStyles(Component c) {
 310         if (c instanceof JComponent) {
 311             // Yes, this is hacky. A better solution is to get the UI
 312             // and cast, but JComponent doesn't expose a getter for the UI
 313             // (each of the UIs do), making that approach impractical.
 314             String name = c.getName();
 315             c.setName(null);
 316             if (name != null) {
 317                 c.setName(name);
 318             }
 319             ((JComponent)c).revalidate();
 320         }
 321         Component[] children = null;
 322         if (c instanceof JMenu) {
 323             children = ((JMenu)c).getMenuComponents();
 324         }
 325         else if (c instanceof Container) {
 326             children = ((Container)c).getComponents();
 327         }
 328         if (children != null) {
 329             for(int i = 0; i < children.length; i++) {
 330                 updateStyles(children[i]);
 331             }
 332         }
 333     }
 334 
 335     /**
 336      * Returns the Region for the JComponent <code>c</code>.
 337      *
 338      * @param c JComponent to fetch the Region for
 339      * @return Region corresponding to <code>c</code>
 340      */
 341     public static Region getRegion(JComponent c) {
 342         return Region.getRegion(c);
 343     }
 344 
 345     /**
 346      * A convenience method to return where the foreground should be
 347      * painted for the Component identified by the passed in
 348      * AbstractSynthContext.
 349      */
 350     static Insets getPaintingInsets(SynthContext state, Insets insets) {


 582      * this <code>SynthLookAndFeel</code>. <code>resourceBase</code> is
 583      * used to resolve any path based resources, for example an
 584      * <code>Image</code> would be resolved by
 585      * <code>resourceBase.getResource(path)</code>. Refer to
 586      * <a href="doc-files/synthFileFormat.html">Synth File Format</a>
 587      * for more information.
 588      *
 589      * @param input InputStream to load from
 590      * @param resourceBase used to resolve any images or other resources
 591      * @throws ParseException if there is an error in parsing
 592      * @throws IllegalArgumentException if input or resourceBase is <code>null</code>
 593      */
 594     public void load(InputStream input, Class<?> resourceBase) throws
 595                        ParseException {
 596         if (resourceBase == null) {
 597             throw new IllegalArgumentException(
 598                 "You must supply a valid resource base Class");
 599         }
 600 
 601         if (defaultsMap == null) {
 602             defaultsMap = new HashMap();
 603         }
 604 
 605         new SynthParser().parse(input, (DefaultSynthStyleFactory) factory,
 606                                 null, resourceBase, defaultsMap);
 607     }
 608 
 609     /**
 610      * Loads the set of <code>SynthStyle</code>s that will be used by
 611      * this <code>SynthLookAndFeel</code>. Path based resources are resolved
 612      * relatively to the specified <code>URL</code> of the style. For example
 613      * an <code>Image</code> would be resolved by
 614      * <code>new URL(synthFile, path)</code>. Refer to
 615      * <a href="doc-files/synthFileFormat.html">Synth File Format</a> for more
 616      * information.
 617      *
 618      * @param url the <code>URL</code> to load the set of
 619      *     <code>SynthStyle</code> from
 620      * @throws ParseException if there is an error in parsing
 621      * @throws IllegalArgumentException if synthSet is <code>null</code>
 622      * @throws IOException if synthSet cannot be opened as an <code>InputStream</code>
 623      * @since 1.6
 624      */
 625     public void load(URL url) throws ParseException, IOException {
 626         if (url == null) {
 627             throw new IllegalArgumentException(
 628                 "You must supply a valid Synth set URL");
 629         }
 630 
 631         if (defaultsMap == null) {
 632             defaultsMap = new HashMap();
 633         }
 634 
 635         InputStream input = url.openStream();
 636         new SynthParser().parse(input, (DefaultSynthStyleFactory) factory,
 637                                 url, null, defaultsMap);
 638     }
 639 
 640     /**
 641      * Called by UIManager when this look and feel is installed.
 642      */
 643     @Override
 644     public void initialize() {
 645         super.initialize();
 646         DefaultLookup.setDefaultLookup(new SynthDefaultLookup());
 647         setStyleFactory(factory);
 648         KeyboardFocusManager.getCurrentKeyboardFocusManager().
 649             addPropertyChangeListener(_handler);
 650     }
 651 
 652     /**


 788      *
 789      * @return whether or not the UIs should update their
 790      * <code>SynthStyles</code> from the <code>SynthStyleFactory</code>
 791      * when the ancestor changed.
 792      */
 793     public boolean shouldUpdateStyleOnAncestorChanged() {
 794         return false;
 795     }
 796 
 797     /**
 798      * Returns the antialiasing information as specified by the host desktop.
 799      * Antialiasing might be forced off if the desktop is GNOME and the user
 800      * has set his locale to Chinese, Japanese or Korean. This is consistent
 801      * with what GTK does. See com.sun.java.swing.plaf.gtk.GtkLookAndFeel
 802      * for more information about CJK and antialiased fonts.
 803      *
 804      * @return the text antialiasing information associated to the desktop
 805      */
 806     private static Object getAATextInfo() {
 807         String language = Locale.getDefault().getLanguage();
 808         String desktop = (String)
 809             AccessController.doPrivileged(new GetPropertyAction("sun.desktop"));
 810 
 811         boolean isCjkLocale = (Locale.CHINESE.getLanguage().equals(language) ||
 812                 Locale.JAPANESE.getLanguage().equals(language) ||
 813                 Locale.KOREAN.getLanguage().equals(language));
 814         boolean isGnome = "gnome".equals(desktop);
 815         boolean isLocal = SwingUtilities2.isLocalDisplay();
 816 
 817         boolean setAA = isLocal && (!isGnome || !isCjkLocale);
 818 
 819         Object aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(setAA);
 820         return aaTextInfo;
 821     }
 822 
 823     private static ReferenceQueue queue = new ReferenceQueue();
 824 
 825     private static void flushUnreferenced() {
 826         AATextListener aatl;
 827         while ((aatl = (AATextListener) queue.poll()) != null) {
 828             aatl.dispose();
 829         }
 830     }
 831 
 832     private static class AATextListener
 833         extends WeakReference implements PropertyChangeListener {
 834         private String key = SunToolkit.DESKTOPFONTHINTS;
 835 
 836         AATextListener(LookAndFeel laf) {
 837             super(laf, queue);
 838             Toolkit tk = Toolkit.getDefaultToolkit();
 839             tk.addPropertyChangeListener(key, this);
 840         }
 841 
 842         @Override
 843         public void propertyChange(PropertyChangeEvent pce) {
 844             UIDefaults defaults = UIManager.getLookAndFeelDefaults();
 845             if (defaults.getBoolean("Synth.doNotSetTextAA")) {
 846                 dispose();
 847                 return;
 848             }
 849 
 850             LookAndFeel laf = (LookAndFeel) get();
 851             if (laf == null || laf != UIManager.getLookAndFeel()) {
 852                 dispose();
 853                 return;
 854             }
 855 
 856             Object aaTextInfo = getAATextInfo();
 857             defaults.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
 858 
 859             updateUI();
 860         }
 861 
 862         void dispose() {
 863             Toolkit tk = Toolkit.getDefaultToolkit();
 864             tk.removePropertyChangeListener(key, this);
 865         }
 866 
 867         /**
 868          * Updates the UI of the passed in window and all its children.
 869          */
 870         private static void updateWindowUI(Window window) {
 871             updateStyles(window);
 872             Window ownedWins[] = window.getOwnedWindows();
 873             for (int i = 0; i < ownedWins.length; i++) {
 874                 updateWindowUI(ownedWins[i]);
 875             }
 876         }
 877 
 878         /**
 879          * Updates the UIs of all the known Frames.
 880          */
 881         private static void updateAllUIs() {
 882             Frame appFrames[] = Frame.getFrames();
 883             for (int i = 0; i < appFrames.length; i++) {
 884                 updateWindowUI(appFrames[i]);
 885             }
 886         }
 887 
 888         /**
 889          * Indicates if an updateUI call is pending.
 890          */
 891         private static boolean updatePending;
 892 
 893         /**
 894          * Sets whether or not an updateUI call is pending.
 895          */
 896         private static synchronized void setUpdatePending(boolean update) {
 897             updatePending = update;
 898         }
 899 
 900         /**
 901          * Returns true if a UI update is pending.
 902          */
 903         private static synchronized boolean isUpdatePending() {
 904             return updatePending;


 929         public void propertyChange(PropertyChangeEvent evt) {
 930             String propertyName = evt.getPropertyName();
 931             Object newValue = evt.getNewValue();
 932             Object oldValue = evt.getOldValue();
 933 
 934             if ("focusOwner" == propertyName) {
 935                 if (oldValue instanceof JComponent) {
 936                     repaintIfBackgroundsDiffer((JComponent)oldValue);
 937 
 938                 }
 939 
 940                 if (newValue instanceof JComponent) {
 941                     repaintIfBackgroundsDiffer((JComponent)newValue);
 942                 }
 943             }
 944             else if ("managingFocus" == propertyName) {
 945                 // De-register listener on old keyboard focus manager and
 946                 // register it on the new one.
 947                 KeyboardFocusManager manager =
 948                     (KeyboardFocusManager)evt.getSource();
 949                 if (((Boolean)newValue).equals(Boolean.FALSE)) {
 950                     manager.removePropertyChangeListener(_handler);
 951                 }
 952                 else {
 953                     manager.addPropertyChangeListener(_handler);
 954                 }
 955             }
 956         }
 957 
 958         /**
 959          * This is a support method that will check if the background colors of
 960          * the specified component differ between focused and unfocused states.
 961          * If the color differ the component will then repaint itself.
 962          *
 963          * @comp the component to check
 964          */
 965         private void repaintIfBackgroundsDiffer(JComponent comp) {
 966             ComponentUI ui = (ComponentUI)comp.getClientProperty(
 967                     SwingUtilities2.COMPONENT_UI_PROPERTY_KEY);
 968             if (ui instanceof SynthUI) {
 969                 SynthUI synthUI = (SynthUI)ui;




  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 accomodate 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 


 309     private static void _updateStyles(Component c) {
 310         if (c instanceof JComponent) {
 311             // Yes, this is hacky. A better solution is to get the UI
 312             // and cast, but JComponent doesn't expose a getter for the UI
 313             // (each of the UIs do), making that approach impractical.
 314             String name = c.getName();
 315             c.setName(null);
 316             if (name != null) {
 317                 c.setName(name);
 318             }
 319             ((JComponent)c).revalidate();
 320         }
 321         Component[] children = null;
 322         if (c instanceof JMenu) {
 323             children = ((JMenu)c).getMenuComponents();
 324         }
 325         else if (c instanceof Container) {
 326             children = ((Container)c).getComponents();
 327         }
 328         if (children != null) {
 329             for (Component child : children) {
 330                 updateStyles(child);
 331             }
 332         }
 333     }
 334 
 335     /**
 336      * Returns the Region for the JComponent <code>c</code>.
 337      *
 338      * @param c JComponent to fetch the Region for
 339      * @return Region corresponding to <code>c</code>
 340      */
 341     public static Region getRegion(JComponent c) {
 342         return Region.getRegion(c);
 343     }
 344 
 345     /**
 346      * A convenience method to return where the foreground should be
 347      * painted for the Component identified by the passed in
 348      * AbstractSynthContext.
 349      */
 350     static Insets getPaintingInsets(SynthContext state, Insets insets) {


 582      * this <code>SynthLookAndFeel</code>. <code>resourceBase</code> is
 583      * used to resolve any path based resources, for example an
 584      * <code>Image</code> would be resolved by
 585      * <code>resourceBase.getResource(path)</code>. Refer to
 586      * <a href="doc-files/synthFileFormat.html">Synth File Format</a>
 587      * for more information.
 588      *
 589      * @param input InputStream to load from
 590      * @param resourceBase used to resolve any images or other resources
 591      * @throws ParseException if there is an error in parsing
 592      * @throws IllegalArgumentException if input or resourceBase is <code>null</code>
 593      */
 594     public void load(InputStream input, Class<?> resourceBase) throws
 595                        ParseException {
 596         if (resourceBase == null) {
 597             throw new IllegalArgumentException(
 598                 "You must supply a valid resource base Class");
 599         }
 600 
 601         if (defaultsMap == null) {
 602             defaultsMap = new HashMap<String, Object>();
 603         }
 604 
 605         new SynthParser().parse(input, (DefaultSynthStyleFactory) factory,
 606                                 null, resourceBase, defaultsMap);
 607     }
 608 
 609     /**
 610      * Loads the set of <code>SynthStyle</code>s that will be used by
 611      * this <code>SynthLookAndFeel</code>. Path based resources are resolved
 612      * relatively to the specified <code>URL</code> of the style. For example
 613      * an <code>Image</code> would be resolved by
 614      * <code>new URL(synthFile, path)</code>. Refer to
 615      * <a href="doc-files/synthFileFormat.html">Synth File Format</a> for more
 616      * information.
 617      *
 618      * @param url the <code>URL</code> to load the set of
 619      *     <code>SynthStyle</code> from
 620      * @throws ParseException if there is an error in parsing
 621      * @throws IllegalArgumentException if synthSet is <code>null</code>
 622      * @throws IOException if synthSet cannot be opened as an <code>InputStream</code>
 623      * @since 1.6
 624      */
 625     public void load(URL url) throws ParseException, IOException {
 626         if (url == null) {
 627             throw new IllegalArgumentException(
 628                 "You must supply a valid Synth set URL");
 629         }
 630 
 631         if (defaultsMap == null) {
 632             defaultsMap = new HashMap<String, Object>();
 633         }
 634 
 635         InputStream input = url.openStream();
 636         new SynthParser().parse(input, (DefaultSynthStyleFactory) factory,
 637                                 url, null, defaultsMap);
 638     }
 639 
 640     /**
 641      * Called by UIManager when this look and feel is installed.
 642      */
 643     @Override
 644     public void initialize() {
 645         super.initialize();
 646         DefaultLookup.setDefaultLookup(new SynthDefaultLookup());
 647         setStyleFactory(factory);
 648         KeyboardFocusManager.getCurrentKeyboardFocusManager().
 649             addPropertyChangeListener(_handler);
 650     }
 651 
 652     /**


 788      *
 789      * @return whether or not the UIs should update their
 790      * <code>SynthStyles</code> from the <code>SynthStyleFactory</code>
 791      * when the ancestor changed.
 792      */
 793     public boolean shouldUpdateStyleOnAncestorChanged() {
 794         return false;
 795     }
 796 
 797     /**
 798      * Returns the antialiasing information as specified by the host desktop.
 799      * Antialiasing might be forced off if the desktop is GNOME and the user
 800      * has set his locale to Chinese, Japanese or Korean. This is consistent
 801      * with what GTK does. See com.sun.java.swing.plaf.gtk.GtkLookAndFeel
 802      * for more information about CJK and antialiased fonts.
 803      *
 804      * @return the text antialiasing information associated to the desktop
 805      */
 806     private static Object getAATextInfo() {
 807         String language = Locale.getDefault().getLanguage();
 808         String desktop =
 809             AccessController.doPrivileged(new GetPropertyAction("sun.desktop"));
 810 
 811         boolean isCjkLocale = (Locale.CHINESE.getLanguage().equals(language) ||
 812                 Locale.JAPANESE.getLanguage().equals(language) ||
 813                 Locale.KOREAN.getLanguage().equals(language));
 814         boolean isGnome = "gnome".equals(desktop);
 815         boolean isLocal = SwingUtilities2.isLocalDisplay();
 816 
 817         boolean setAA = isLocal && (!isGnome || !isCjkLocale);
 818 
 819         Object aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(setAA);
 820         return aaTextInfo;
 821     }
 822 
 823     private static ReferenceQueue<LookAndFeel> queue = new ReferenceQueue<LookAndFeel>();
 824 
 825     private static void flushUnreferenced() {
 826         AATextListener aatl;
 827         while ((aatl = (AATextListener) queue.poll()) != null) {
 828             aatl.dispose();
 829         }
 830     }
 831 
 832     private static class AATextListener
 833         extends WeakReference<LookAndFeel> implements PropertyChangeListener {
 834         private String key = SunToolkit.DESKTOPFONTHINTS;
 835 
 836         AATextListener(LookAndFeel laf) {
 837             super(laf, queue);
 838             Toolkit tk = Toolkit.getDefaultToolkit();
 839             tk.addPropertyChangeListener(key, this);
 840         }
 841 
 842         @Override
 843         public void propertyChange(PropertyChangeEvent pce) {
 844             UIDefaults defaults = UIManager.getLookAndFeelDefaults();
 845             if (defaults.getBoolean("Synth.doNotSetTextAA")) {
 846                 dispose();
 847                 return;
 848             }
 849 
 850             LookAndFeel laf = get();
 851             if (laf == null || laf != UIManager.getLookAndFeel()) {
 852                 dispose();
 853                 return;
 854             }
 855 
 856             Object aaTextInfo = getAATextInfo();
 857             defaults.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
 858 
 859             updateUI();
 860         }
 861 
 862         void dispose() {
 863             Toolkit tk = Toolkit.getDefaultToolkit();
 864             tk.removePropertyChangeListener(key, this);
 865         }
 866 
 867         /**
 868          * Updates the UI of the passed in window and all its children.
 869          */
 870         private static void updateWindowUI(Window window) {
 871             updateStyles(window);
 872             Window ownedWins[] = window.getOwnedWindows();
 873             for (Window w : ownedWins) {
 874                 updateWindowUI(w);
 875             }
 876         }
 877 
 878         /**
 879          * Updates the UIs of all the known Frames.
 880          */
 881         private static void updateAllUIs() {
 882             Frame appFrames[] = Frame.getFrames();
 883             for (Frame frame : appFrames) {
 884                 updateWindowUI(frame);
 885             }
 886         }
 887 
 888         /**
 889          * Indicates if an updateUI call is pending.
 890          */
 891         private static boolean updatePending;
 892 
 893         /**
 894          * Sets whether or not an updateUI call is pending.
 895          */
 896         private static synchronized void setUpdatePending(boolean update) {
 897             updatePending = update;
 898         }
 899 
 900         /**
 901          * Returns true if a UI update is pending.
 902          */
 903         private static synchronized boolean isUpdatePending() {
 904             return updatePending;


 929         public void propertyChange(PropertyChangeEvent evt) {
 930             String propertyName = evt.getPropertyName();
 931             Object newValue = evt.getNewValue();
 932             Object oldValue = evt.getOldValue();
 933 
 934             if ("focusOwner" == propertyName) {
 935                 if (oldValue instanceof JComponent) {
 936                     repaintIfBackgroundsDiffer((JComponent)oldValue);
 937 
 938                 }
 939 
 940                 if (newValue instanceof JComponent) {
 941                     repaintIfBackgroundsDiffer((JComponent)newValue);
 942                 }
 943             }
 944             else if ("managingFocus" == propertyName) {
 945                 // De-register listener on old keyboard focus manager and
 946                 // register it on the new one.
 947                 KeyboardFocusManager manager =
 948                     (KeyboardFocusManager)evt.getSource();
 949                 if (newValue.equals(Boolean.FALSE)) {
 950                     manager.removePropertyChangeListener(_handler);
 951                 }
 952                 else {
 953                     manager.addPropertyChangeListener(_handler);
 954                 }
 955             }
 956         }
 957 
 958         /**
 959          * This is a support method that will check if the background colors of
 960          * the specified component differ between focused and unfocused states.
 961          * If the color differ the component will then repaint itself.
 962          *
 963          * @comp the component to check
 964          */
 965         private void repaintIfBackgroundsDiffer(JComponent comp) {
 966             ComponentUI ui = (ComponentUI)comp.getClientProperty(
 967                     SwingUtilities2.COMPONENT_UI_PROPERTY_KEY);
 968             if (ui instanceof SynthUI) {
 969                 SynthUI synthUI = (SynthUI)ui;


< prev index next >