jdk/src/share/classes/javax/swing/plaf/LayerUI.java
changeset 3508 defe8eec9251
child 3733 af63479b67b8
equal deleted inserted replaced
3507:1610d6f5a0e3 3508:defe8eec9251
       
     1 /*
       
     2  * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
       
     3  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
       
     4  */
       
     5 
       
     6 package javax.swing.plaf;
       
     7 
       
     8 import javax.accessibility.Accessible;
       
     9 import javax.swing.*;
       
    10 import javax.swing.plaf.ComponentUI;
       
    11 import java.awt.*;
       
    12 import java.awt.event.*;
       
    13 import java.beans.PropertyChangeEvent;
       
    14 import java.beans.PropertyChangeSupport;
       
    15 import java.beans.PropertyChangeListener;
       
    16 import java.io.Serializable;
       
    17 
       
    18 /**
       
    19  * The base class for all {@link javax.swing.JLayer}'s UI delegates.
       
    20  * <p/>
       
    21  * {@link #paint(java.awt.Graphics, javax.swing.JComponent)} method performes the
       
    22  * painting of the {@code JLayer}
       
    23  * and {@link #eventDispatched(AWTEvent, JLayer)} method is notified
       
    24  * about any {@code AWTEvent}s which have been generated by a {@code JLayer}
       
    25  * or any of its subcomponents.
       
    26  * <p/>
       
    27  * The {@code LayerUI} differs from the UI delegates of the other components,
       
    28  * because it is LookAndFeel independent and is not updated by default when
       
    29  * the system LookAndFeel is changed.
       
    30  * <p/>
       
    31  * The subclasses of {@code LayerUI} can either be stateless and shareable
       
    32  * by multiple {@code JLayer}s or not shareable.
       
    33  *
       
    34  * @param <V> one of the super types of {@code JLayer}'s view component
       
    35  *
       
    36  * @see JLayer#setUI(LayerUI)
       
    37  * @see JLayer#setView(Component)
       
    38  * @see JLayer#getView()
       
    39  * @since 1.7
       
    40  *
       
    41  * @author Alexander Potochkin
       
    42  */
       
    43 public class LayerUI<V extends Component>
       
    44         extends ComponentUI implements Serializable {
       
    45 
       
    46     private final PropertyChangeSupport propertyChangeSupport =
       
    47             new PropertyChangeSupport(this);
       
    48 
       
    49     /**
       
    50      * Paints the specified component.
       
    51      * Subclasses should override this method and use
       
    52      * the specified {@code Graphics} object to
       
    53      * render the content of the component.
       
    54      *
       
    55      * @param g the {@code Graphics} context in which to paint;
       
    56      * @param c the component being painted;
       
    57      * it can be safely cast to the {@code JLayer<V>}
       
    58      */
       
    59     @Override
       
    60     public void paint(Graphics g, JComponent c) {
       
    61         c.paint(g);
       
    62     }
       
    63 
       
    64     /**
       
    65      * Dispatches {@code AWTEvent}s for {@code JLayer}
       
    66      * and <b>all it subcomponents</b> to this {@code LayerUI} instance.
       
    67      * <p>
       
    68      * To enable the {@code AWTEvent} of the particular type,
       
    69      * you call {@link javax.swing.JLayer#setLayerEventMask}
       
    70      * in {@link #installUI(javax.swing.JComponent)}
       
    71      * and set the layer event mask to {@code 0}
       
    72      * in {@link #uninstallUI(javax.swing.JComponent)} after that
       
    73      *
       
    74      * @param e the event to be dispatched
       
    75      * @param l the layer this LayerUI is set to
       
    76      *
       
    77      * @see JLayer#setLayerEventMask(long)
       
    78      * @see javax.swing.JLayer#getLayerEventMask()
       
    79      */
       
    80     public void eventDispatched(AWTEvent e, JLayer<? extends V> l){
       
    81     }
       
    82 
       
    83     /**
       
    84      * Invoked when {@link javax.swing.JLayer#updateUI()} is called
       
    85      * by the {@code JLayer} this {@code LayerUI} is set to.
       
    86      *
       
    87      * @param l the {@code JLayer} which UI is updated
       
    88      */
       
    89     public void updateUI(JLayer<? extends V> l){
       
    90     }
       
    91 
       
    92     /**
       
    93      * Configures the {@code JLayer} this {@code LayerUI} is set to.
       
    94      * The default implementation registers the {@code LayerUI}
       
    95      * as a property change listener for the passed {@code JLayer} component.
       
    96      *
       
    97      * @param c the {@code JLayer} component where this UI delegate is being installed
       
    98      */
       
    99     public void installUI(JComponent c) {
       
   100         addPropertyChangeListener((JLayer) c);
       
   101     }
       
   102 
       
   103     /**
       
   104      * Reverses the configuration which was previously set
       
   105      * in the {@link #installUI(JComponent)} method.
       
   106      * The default implementation unregisters the property change listener
       
   107      * for the passed JLayer component.
       
   108      *
       
   109      * @param c the component from which this UI delegate is being removed.
       
   110      */
       
   111     public void uninstallUI(JComponent c) {
       
   112         removePropertyChangeListener((JLayer) c);
       
   113     }
       
   114 
       
   115     /**
       
   116      * Adds a PropertyChangeListener to the listener list. The listener is
       
   117      * registered for all bound properties of this class.
       
   118      * <p/>
       
   119      * If {@code listener} is {@code null},
       
   120      * no exception is thrown and no action is performed.
       
   121      *
       
   122      * @param listener the property change listener to be added
       
   123      * @see #removePropertyChangeListener
       
   124      * @see #getPropertyChangeListeners
       
   125      * @see #addPropertyChangeListener(String, java.beans.PropertyChangeListener)
       
   126      */
       
   127     public void addPropertyChangeListener(PropertyChangeListener listener) {
       
   128         propertyChangeSupport.addPropertyChangeListener(listener);
       
   129     }
       
   130 
       
   131     /**
       
   132      * Removes a PropertyChangeListener from the listener list. This method
       
   133      * should be used to remove PropertyChangeListeners that were registered
       
   134      * for all bound properties of this class.
       
   135      * <p/>
       
   136      * If {@code listener} is {@code null},
       
   137      * no exception is thrown and no action is performed.
       
   138      *
       
   139      * @param listener the PropertyChangeListener to be removed
       
   140      * @see #addPropertyChangeListener
       
   141      * @see #getPropertyChangeListeners
       
   142      * @see #removePropertyChangeListener(String, PropertyChangeListener)
       
   143      */
       
   144     public void removePropertyChangeListener(PropertyChangeListener listener) {
       
   145         propertyChangeSupport.removePropertyChangeListener(listener);
       
   146     }
       
   147 
       
   148     /**
       
   149      * Returns an array of all the property change listeners
       
   150      * registered on this component.
       
   151      *
       
   152      * @return all of this ui's {@code PropertyChangeListener}s
       
   153      *         or an empty array if no property change
       
   154      *         listeners are currently registered
       
   155      * @see #addPropertyChangeListener
       
   156      * @see #removePropertyChangeListener
       
   157      * @see #getPropertyChangeListeners(String)
       
   158      */
       
   159     public PropertyChangeListener[] getPropertyChangeListeners() {
       
   160         return propertyChangeSupport.getPropertyChangeListeners();
       
   161     }
       
   162 
       
   163     /**
       
   164      * Adds a PropertyChangeListener to the listener list for a specific
       
   165      * property.
       
   166      * <p/>
       
   167      * If {@code propertyName} or {@code listener} is {@code null},
       
   168      * no exception is thrown and no action is taken.
       
   169      *
       
   170      * @param propertyName one of the property names listed above
       
   171      * @param listener     the property change listener to be added
       
   172      * @see #removePropertyChangeListener(String, PropertyChangeListener)
       
   173      * @see #getPropertyChangeListeners(String)
       
   174      * @see #addPropertyChangeListener(String, PropertyChangeListener)
       
   175      */
       
   176     public void addPropertyChangeListener(String propertyName,
       
   177                                           PropertyChangeListener listener) {
       
   178         propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
       
   179     }
       
   180 
       
   181     /**
       
   182      * Removes a {@code PropertyChangeListener} from the listener
       
   183      * list for a specific property. This method should be used to remove
       
   184      * {@code PropertyChangeListener}s
       
   185      * that were registered for a specific bound property.
       
   186      * <p/>
       
   187      * If {@code propertyName} or {@code listener} is {@code null},
       
   188      * no exception is thrown and no action is taken.
       
   189      *
       
   190      * @param propertyName a valid property name
       
   191      * @param listener     the PropertyChangeListener to be removed
       
   192      * @see #addPropertyChangeListener(String, PropertyChangeListener)
       
   193      * @see #getPropertyChangeListeners(String)
       
   194      * @see #removePropertyChangeListener(PropertyChangeListener)
       
   195      */
       
   196     public void removePropertyChangeListener(String propertyName,
       
   197                                              PropertyChangeListener listener) {
       
   198         propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
       
   199     }
       
   200 
       
   201     /**
       
   202      * Returns an array of all the listeners which have been associated
       
   203      * with the named property.
       
   204      *
       
   205      * @return all of the {@code PropertyChangeListener}s associated with
       
   206      *         the named property; if no such listeners have been added or
       
   207      *         if {@code propertyName} is {@code null}, an empty
       
   208      *         array is returned
       
   209      * @see #addPropertyChangeListener(String, PropertyChangeListener)
       
   210      * @see #removePropertyChangeListener(String, PropertyChangeListener)
       
   211      * @see #getPropertyChangeListeners
       
   212      */
       
   213     public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
       
   214         return propertyChangeSupport.getPropertyChangeListeners(propertyName);
       
   215     }
       
   216 
       
   217     /**
       
   218      * Support for reporting bound property changes for Object properties.
       
   219      * This method can be called when a bound property has changed and it will
       
   220      * send the appropriate PropertyChangeEvent to any registered
       
   221      * PropertyChangeListeners.
       
   222      *
       
   223      * @param propertyName the property whose value has changed
       
   224      * @param oldValue     the property's previous value
       
   225      * @param newValue     the property's new value
       
   226      */
       
   227     protected void firePropertyChange(String propertyName,
       
   228                                       Object oldValue, Object newValue) {
       
   229         propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
       
   230     }
       
   231 
       
   232     /**
       
   233      * Notifies the {@code LayerUI} when any of its property are changed
       
   234      * and enables updating every {@code JLayer} this {@code LayerUI} instance is set to.
       
   235      *
       
   236      * @param evt the PropertyChangeEvent generated by this {@code LayerUI}
       
   237      * @param l the {@code JLayer} this LayerUI is set to
       
   238      */
       
   239     public void applyPropertyChange(PropertyChangeEvent evt, JLayer<? extends V> l) {
       
   240     }
       
   241 
       
   242     /**
       
   243      * Returns the preferred size of the viewport for a view component.
       
   244      *
       
   245      * @return the preferred size of the viewport for a view component
       
   246      * @see Scrollable#getPreferredScrollableViewportSize()
       
   247      */
       
   248     public Dimension getPreferredScrollableViewportSize(JLayer<? extends V> l) {
       
   249         if (l.getView() instanceof Scrollable) {
       
   250             return ((Scrollable)l.getView()).getPreferredScrollableViewportSize();
       
   251         }
       
   252         return l.getPreferredSize();
       
   253     }
       
   254 
       
   255     /**
       
   256      * Returns a scroll increment, which is required for components
       
   257      * that display logical rows or columns in order to completely expose
       
   258      * one block of rows or columns, depending on the value of orientation.
       
   259      *
       
   260      * @return the "block" increment for scrolling in the specified direction
       
   261      * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int)
       
   262      */
       
   263      public int getScrollableBlockIncrement(JLayer<? extends V> l,
       
   264                                            Rectangle visibleRect,
       
   265                                            int orientation, int direction) {
       
   266         if (l.getView() instanceof Scrollable) {
       
   267             return ((Scrollable)l.getView()).getScrollableBlockIncrement(
       
   268                     visibleRect,orientation, direction);
       
   269         }
       
   270         return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
       
   271             visibleRect.width;
       
   272     }
       
   273 
       
   274     /**
       
   275      * Returns {@code false} to indicate that the height of the viewport does not
       
   276      * determine the height of the layer, unless the preferred height
       
   277      * of the layer is smaller than the height of the viewport.
       
   278      *
       
   279      * @return whether the layer should track the height of the viewport
       
   280      * @see Scrollable#getScrollableTracksViewportHeight()
       
   281      */
       
   282     public boolean getScrollableTracksViewportHeight(JLayer<? extends V> l) {
       
   283         if (l.getView() instanceof Scrollable) {
       
   284             return ((Scrollable)l.getView()).getScrollableTracksViewportHeight();
       
   285         }
       
   286         if (l.getParent() instanceof JViewport) {
       
   287             return (((JViewport)l.getParent()).getHeight() > l.getPreferredSize().height);
       
   288         }
       
   289         return false;
       
   290     }
       
   291 
       
   292     /**
       
   293      * Returns {@code false} to indicate that the width of the viewport does not
       
   294      * determine the width of the layer, unless the preferred width
       
   295      * of the layer is smaller than the width of the viewport.
       
   296      *
       
   297      * @return whether the layer should track the width of the viewport
       
   298      * @see Scrollable
       
   299      * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
       
   300      */
       
   301     public boolean getScrollableTracksViewportWidth(JLayer<? extends V> l) {
       
   302         if (l.getView() instanceof Scrollable) {
       
   303             return ((Scrollable)l.getView()).getScrollableTracksViewportWidth();
       
   304         }
       
   305         if (l.getParent() instanceof JViewport) {
       
   306             return (((JViewport)l.getParent()).getWidth() > l.getPreferredSize().width);
       
   307         }
       
   308         return false;
       
   309     }
       
   310 
       
   311     /**
       
   312      * Returns a scroll increment, which is required for components
       
   313      * that display logical rows or columns in order to completely expose
       
   314      * one new row or column, depending on the value of orientation.
       
   315      * Ideally, components should handle a partially exposed row or column
       
   316      * by returning the distance required to completely expose the item.
       
   317      * <p>
       
   318      * Scrolling containers, like JScrollPane, will use this method
       
   319      * each time the user requests a unit scroll.
       
   320      *
       
   321      * @return The "unit" increment for scrolling in the specified direction.
       
   322      *         This value should always be positive.
       
   323      * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int)
       
   324      */
       
   325     public int getScrollableUnitIncrement(JLayer<? extends V> l,
       
   326                                           Rectangle visibleRect,
       
   327                                           int orientation, int direction) {
       
   328         if (l.getView() instanceof Scrollable) {
       
   329             return ((Scrollable)l.getView()).getScrollableUnitIncrement(
       
   330                     visibleRect, orientation, direction);
       
   331         }
       
   332         return 1;
       
   333     }
       
   334 
       
   335     /**
       
   336      * If the {@code JLayer}'s view component is not {@code null},
       
   337      * this calls the view's {@code getBaseline()} method.
       
   338      * Otherwise, the default implementation is called.
       
   339      *
       
   340      * @param c {@code JLayer} to return baseline resize behavior for
       
   341      * @param width the width to get the baseline for
       
   342      * @param height the height to get the baseline for
       
   343      * @return baseline or a value &lt; 0 indicating there is no reasonable
       
   344      *                  baseline
       
   345      */
       
   346     public int getBaseline(JComponent c, int width, int height) {
       
   347         JLayer l = (JLayer) c;
       
   348         if (l.getView() != null) {
       
   349             return l.getView().getBaseline(width, height);
       
   350         }
       
   351         return super.getBaseline(c, width, height);
       
   352      }
       
   353 
       
   354     /**
       
   355      * If the {@code JLayer}'s view component is not {@code null},
       
   356      * this calls the view's {@code getBaselineResizeBehavior()} method.
       
   357      * Otherwise, the default implementation is called.
       
   358      *
       
   359      * @param c {@code JLayer} to return baseline resize behavior for
       
   360      * @return an enum indicating how the baseline changes as the component
       
   361      *         size changes
       
   362      */
       
   363     public Component.BaselineResizeBehavior getBaselineResizeBehavior(JComponent c) {
       
   364         JLayer l = (JLayer) c;
       
   365         if (l.getView() != null) {
       
   366             return l.getView().getBaselineResizeBehavior();
       
   367         }
       
   368         return super.getBaselineResizeBehavior(c);
       
   369     }
       
   370 }