1 /*
2  * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package javax.swing.plaf;
27 
28 import javax.swing.*;
29 import java.awt.*;
30 import java.awt.event.*;
31 import java.beans.PropertyChangeEvent;
32 import java.beans.PropertyChangeSupport;
33 import java.beans.PropertyChangeListener;
34 import java.io.Serializable;
35 
36 /**
37  * The base class for all {@link javax.swing.JLayer}'s UI delegates.
38  * <p>
39  * {@link #paint(java.awt.Graphics, javax.swing.JComponent)} method performs the
40  * painting of the {@code JLayer}
41  * and {@link #eventDispatched(AWTEvent, JLayer)} method is notified
42  * about any {@code AWTEvent}s which have been generated by a {@code JLayer}
43  * or any of its subcomponents.
44  * <p>
45  * The {@code LayerUI} differs from the UI delegates of the other components,
46  * because it is LookAndFeel independent and is not updated by default when
47  * the system LookAndFeel is changed.
48  * <p>
49  * The subclasses of {@code LayerUI} can either be stateless and shareable
50  * by multiple {@code JLayer}s or not shareable.
51  *
52  * @param <V> one of the super types of {@code JLayer}'s view component
53  *
54  * @see JLayer#setUI(LayerUI)
55  * @see JLayer#setView(Component)
56  * @see JLayer#getView()
57  * @since 1.7
58  *
59  * @author Alexander Potochkin
60  */
61 @SuppressWarnings("serial") // Same-version serialization only
62 public class LayerUI<V extends Component>
63         extends ComponentUI implements Serializable {
64 
65     private final PropertyChangeSupport propertyChangeSupport =
66             new PropertyChangeSupport(this);
67 
68     /**
69      * Paints the specified component.
70      * Subclasses should override this method and use
71      * the specified {@code Graphics} object to
72      * render the content of the component.
73      * <p>
74      * The default implementation paints the passed component as is.
75      *
76      * @param g the {@code Graphics} context in which to paint
77      * @param c the component being painted
78      */
paint(Graphics g, JComponent c)79     public void paint(Graphics g, JComponent c) {
80         c.paint(g);
81     }
82 
83     /**
84      * Processes {@code AWTEvent}s for {@code JLayer}
85      * and <b>all its descendants</b> to this {@code LayerUI} instance.
86      * <p>
87      * To enable the {@code AWTEvent}s of a particular type,
88      * you call {@link JLayer#setLayerEventMask}
89      * in {@link #installUI(javax.swing.JComponent)}
90      * and set the layer event mask to {@code 0}
91      * in {@link #uninstallUI(javax.swing.JComponent)} after that.
92      * By default this  method calls the appropriate
93      * {@code process<event}&nbsp;{@code type>Event}
94      * method for the given class of event.
95      * <p>
96      * <b>Note:</b> Events are processed only for displayable {@code JLayer}s.
97      *
98      * @param e the event to be dispatched
99      * @param l the layer this LayerUI is set to
100      *
101      * @see JLayer#setLayerEventMask(long)
102      * @see Component#isDisplayable()
103      * @see #processComponentEvent
104      * @see #processFocusEvent
105      * @see #processKeyEvent
106      * @see #processMouseEvent
107      * @see #processMouseMotionEvent
108      * @see #processInputMethodEvent
109      * @see #processHierarchyEvent
110      * @see #processMouseWheelEvent
111      */
eventDispatched(AWTEvent e, JLayer<? extends V> l)112     public void eventDispatched(AWTEvent e, JLayer<? extends V> l){
113         if (e instanceof FocusEvent) {
114             processFocusEvent((FocusEvent)e, l);
115 
116         } else if (e instanceof MouseEvent) {
117             switch(e.getID()) {
118               case MouseEvent.MOUSE_PRESSED:
119               case MouseEvent.MOUSE_RELEASED:
120               case MouseEvent.MOUSE_CLICKED:
121               case MouseEvent.MOUSE_ENTERED:
122               case MouseEvent.MOUSE_EXITED:
123                   processMouseEvent((MouseEvent)e, l);
124                   break;
125               case MouseEvent.MOUSE_MOVED:
126               case MouseEvent.MOUSE_DRAGGED:
127                   processMouseMotionEvent((MouseEvent)e, l);
128                   break;
129               case MouseEvent.MOUSE_WHEEL:
130                   processMouseWheelEvent((MouseWheelEvent)e, l);
131                   break;
132             }
133         } else if (e instanceof KeyEvent) {
134             processKeyEvent((KeyEvent)e, l);
135         } else if (e instanceof ComponentEvent) {
136             processComponentEvent((ComponentEvent)e, l);
137         } else if (e instanceof InputMethodEvent) {
138             processInputMethodEvent((InputMethodEvent)e, l);
139         } else if (e instanceof HierarchyEvent) {
140             switch (e.getID()) {
141               case HierarchyEvent.HIERARCHY_CHANGED:
142                   processHierarchyEvent((HierarchyEvent)e, l);
143                   break;
144               case HierarchyEvent.ANCESTOR_MOVED:
145               case HierarchyEvent.ANCESTOR_RESIZED:
146                   processHierarchyBoundsEvent((HierarchyEvent)e, l);
147                   break;
148             }
149         }
150     }
151 
152     /**
153      * Processes component events occurring on the {@link JLayer}
154      * or any of its subcomponents.
155      * <p>
156      * This method is not called unless component events are
157      * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
158      * Component events are enabled in the overridden {@link #installUI} method
159      * and should be disabled in the {@link #uninstallUI} method after that.
160      * <pre>
161      * public void installUI(JComponent c) {
162      *    super.installUI(c);
163      *    JLayer l = (JLayer) c;
164      *    l.setLayerEventMask(AWTEvent.COMPONENT_EVENT_MASK);
165      * }
166      *
167      * public void uninstallUI(JComponent c) {
168      *     super.uninstallUI(c);
169      *     JLayer l = (JLayer) c;
170      *     l.setLayerEventMask(0);
171      * }
172      * </pre>
173      *
174      * @param e the {@code ComponentEvent} to be processed
175      * @param l the layer this {@code LayerUI} instance is set to
176      *
177      * @see JLayer#setLayerEventMask(long)
178      * @see #installUI(javax.swing.JComponent)
179      * @see #uninstallUI(javax.swing.JComponent)
180      */
processComponentEvent(ComponentEvent e, JLayer<? extends V> l)181     protected void processComponentEvent(ComponentEvent e, JLayer<? extends V> l) {
182     }
183 
184     /**
185      * Processes focus events occurring on the {@link JLayer}
186      * or any of its subcomponents.
187      * <p>
188      * This method is not called unless focus events are
189      * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
190      * Focus events are enabled in the overridden {@link #installUI} method
191      * and should be disabled in the {@link #uninstallUI} method after that.
192      * <pre>
193      * public void installUI(JComponent c) {
194      *    super.installUI(c);
195      *    JLayer l = (JLayer) c;
196      *    l.setLayerEventMask(AWTEvent.FOCUS_EVENT_MASK);
197      * }
198      *
199      * public void uninstallUI(JComponent c) {
200      *     super.uninstallUI(c);
201      *     JLayer l = (JLayer) c;
202      *     l.setLayerEventMask(0);
203      * }
204      * </pre>
205      *
206      * @param e the {@code FocusEvent} to be processed
207      * @param l the layer this {@code LayerUI} instance is set to
208      *
209      * @see JLayer#setLayerEventMask(long)
210      * @see #installUI(javax.swing.JComponent)
211      * @see #uninstallUI(javax.swing.JComponent)
212      */
processFocusEvent(FocusEvent e, JLayer<? extends V> l)213     protected void processFocusEvent(FocusEvent e, JLayer<? extends V> l) {
214     }
215 
216     /**
217      * Processes key events occurring on the {@link JLayer}
218      * or any of its subcomponents.
219      * <p>
220      * This method is not called unless key events are
221      * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
222      * Key events are enabled in the overridden {@link #installUI} method
223      * and should be disabled in the {@link #uninstallUI} method after that.
224      * <pre>
225      * public void installUI(JComponent c) {
226      *    super.installUI(c);
227      *    JLayer l = (JLayer) c;
228      *    l.setLayerEventMask(AWTEvent.KEY_EVENT_MASK);
229      * }
230      *
231      * public void uninstallUI(JComponent c) {
232      *     super.uninstallUI(c);
233      *     JLayer l = (JLayer) c;
234      *     l.setLayerEventMask(0);
235      * }
236      * </pre>
237      *
238      * @param e the {@code KeyEvent} to be processed
239      * @param l the layer this {@code LayerUI} instance is set to
240      *
241      * @see JLayer#setLayerEventMask(long)
242      * @see #installUI(javax.swing.JComponent)
243      * @see #uninstallUI(javax.swing.JComponent)
244      */
processKeyEvent(KeyEvent e, JLayer<? extends V> l)245     protected void processKeyEvent(KeyEvent e, JLayer<? extends V> l) {
246     }
247 
248     /**
249      * Processes mouse events occurring on the {@link JLayer}
250      * or any of its subcomponents.
251      * <p>
252      * This method is not called unless mouse events are
253      * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
254      * Mouse events are enabled in the overridden {@link #installUI} method
255      * and should be disabled in the {@link #uninstallUI} method after that.
256      * <pre>
257      * public void installUI(JComponent c) {
258      *    super.installUI(c);
259      *    JLayer l = (JLayer) c;
260      *    l.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
261      * }
262      *
263      * public void uninstallUI(JComponent c) {
264      *     super.uninstallUI(c);
265      *     JLayer l = (JLayer) c;
266      *     l.setLayerEventMask(0);
267      * }
268      * </pre>
269      *
270      * @param e the {@code MouseEvent} to be processed
271      * @param l the layer this {@code LayerUI} instance is set to
272      *
273      * @see JLayer#setLayerEventMask(long)
274      * @see #installUI(javax.swing.JComponent)
275      * @see #uninstallUI(javax.swing.JComponent)
276      */
processMouseEvent(MouseEvent e, JLayer<? extends V> l)277     protected void processMouseEvent(MouseEvent e, JLayer<? extends V> l) {
278     }
279 
280     /**
281      * Processes mouse motion event occurring on the {@link JLayer}
282      * or any of its subcomponents.
283      * <p>
284      * This method is not called unless mouse motion events are
285      * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
286      * Mouse motion events are enabled in the overridden {@link #installUI} method
287      * and should be disabled in the {@link #uninstallUI} method after that.
288      * <pre>
289      * public void installUI(JComponent c) {
290      *    super.installUI(c);
291      *    JLayer l = (JLayer) c;
292      *    l.setLayerEventMask(AWTEvent.MOUSE_MOTION_EVENT_MASK);
293      * }
294      *
295      * public void uninstallUI(JComponent c) {
296      *     super.uninstallUI(c);
297      *     JLayer l = (JLayer) c;
298      *     l.setLayerEventMask(0);
299      * }
300      * </pre>
301      *
302      * @param e the {@code MouseEvent} to be processed
303      * @param l the layer this {@code LayerUI} instance is set to
304      *
305      * @see JLayer#setLayerEventMask(long)
306      * @see #installUI(javax.swing.JComponent)
307      * @see #uninstallUI(javax.swing.JComponent)
308      */
processMouseMotionEvent(MouseEvent e, JLayer<? extends V> l)309     protected void processMouseMotionEvent(MouseEvent e, JLayer<? extends V> l) {
310     }
311 
312     /**
313      * Processes mouse wheel event occurring on the {@link JLayer}
314      * or any of its subcomponents.
315      * <p>
316      * This method is not called unless mouse wheel events are
317      * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
318      * Mouse wheel events are enabled in the overridden {@link #installUI} method
319      * and should be disabled in the {@link #uninstallUI} method after that.
320      * <pre>
321      * public void installUI(JComponent c) {
322      *    super.installUI(c);
323      *    JLayer l = (JLayer) c;
324      *    l.setLayerEventMask(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
325      * }
326      *
327      * public void uninstallUI(JComponent c) {
328      *     super.uninstallUI(c);
329      *     JLayer l = (JLayer) c;
330      *     l.setLayerEventMask(0);
331      * }
332      * </pre>
333      *
334      * @param e the {@code MouseEvent} to be processed
335      * @param l the layer this {@code LayerUI} instance is set to
336      *
337      * @see JLayer#setLayerEventMask(long)
338      * @see #installUI(javax.swing.JComponent)
339      * @see #uninstallUI(javax.swing.JComponent)
340      */
processMouseWheelEvent(MouseWheelEvent e, JLayer<? extends V> l)341     protected void processMouseWheelEvent(MouseWheelEvent e, JLayer<? extends V> l) {
342     }
343 
344     /**
345      * Processes input event occurring on the {@link JLayer}
346      * or any of its subcomponents.
347      * <p>
348      * This method is not called unless input events are
349      * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
350      * Input events are enabled in the overridden {@link #installUI} method
351      * and should be disabled in the {@link #uninstallUI} method after that.
352      * <pre>
353      * public void installUI(JComponent c) {
354      *    super.installUI(c);
355      *    JLayer l = (JLayer) c;
356      *    l.setLayerEventMask(AWTEvent.INPUT_METHOD_EVENT_MASK);
357      * }
358      *
359      * public void uninstallUI(JComponent c) {
360      *     super.uninstallUI(c);
361      *     JLayer l = (JLayer) c;
362      *     l.setLayerEventMask(0);
363      * }
364      * </pre>
365      *
366      * @param e the {@code InputMethodEvent} to be processed
367      * @param l the layer this {@code LayerUI} instance is set to
368      *
369      * @see JLayer#setLayerEventMask(long)
370      * @see #installUI(javax.swing.JComponent)
371      * @see #uninstallUI(javax.swing.JComponent)
372      */
processInputMethodEvent(InputMethodEvent e, JLayer<? extends V> l)373     protected void processInputMethodEvent(InputMethodEvent e, JLayer<? extends V> l) {
374     }
375 
376     /**
377      * Processes hierarchy event occurring on the {@link JLayer}
378      * or any of its subcomponents.
379      * <p>
380      * This method is not called unless hierarchy events are
381      * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
382      * Hierarchy events are enabled in the overridden {@link #installUI} method
383      * and should be disabled in the {@link #uninstallUI} method after that.
384      * <pre>
385      * public void installUI(JComponent c) {
386      *    super.installUI(c);
387      *    JLayer l = (JLayer) c;
388      *    l.setLayerEventMask(AWTEvent.HIERARCHY_EVENT_MASK);
389      * }
390      *
391      * public void uninstallUI(JComponent c) {
392      *     super.uninstallUI(c);
393      *     JLayer l = (JLayer) c;
394      *     l.setLayerEventMask(0);
395      * }
396      * </pre>
397      *
398      * @param e the {@code HierarchyEvent} to be processed
399      * @param l the layer this {@code LayerUI} instance is set to
400      *
401      * @see JLayer#setLayerEventMask(long)
402      * @see #installUI(javax.swing.JComponent)
403      * @see #uninstallUI(javax.swing.JComponent)
404      */
processHierarchyEvent(HierarchyEvent e, JLayer<? extends V> l)405     protected void processHierarchyEvent(HierarchyEvent e, JLayer<? extends V> l) {
406     }
407 
408     /**
409      * Processes hierarchy bounds event occurring on the {@link JLayer}
410      * or any of its subcomponents.
411      * <p>
412      * This method is not called unless hierarchy bounds events are
413      * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
414      * Hierarchy bounds events are enabled in the overridden {@link #installUI}
415      * method and should be disabled in the {@link #uninstallUI} method after that.
416      * <pre>
417      * public void installUI(JComponent c) {
418      *    super.installUI(c);
419      *    JLayer l = (JLayer) c;
420      *    l.setLayerEventMask(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
421      * }
422      *
423      * public void uninstallUI(JComponent c) {
424      *     super.uninstallUI(c);
425      *     JLayer l = (JLayer) c;
426      *     l.setLayerEventMask(0);
427      * }
428      * </pre>
429      *
430      * @param e the {@code HierarchyEvent} to be processed
431      * @param l the layer this {@code LayerUI} instance is set to
432      *
433      * @see JLayer#setLayerEventMask(long)
434      * @see #installUI(javax.swing.JComponent)
435      * @see #uninstallUI(javax.swing.JComponent)
436      */
processHierarchyBoundsEvent(HierarchyEvent e, JLayer<? extends V> l)437     protected void processHierarchyBoundsEvent(HierarchyEvent e, JLayer<? extends V> l) {
438     }
439 
440     /**
441      * Invoked when {@link javax.swing.JLayer#updateUI()} is called
442      * by the {@code JLayer} this {@code LayerUI} is set to.
443      *
444      * @param l the {@code JLayer} which UI is updated
445      */
updateUI(JLayer<? extends V> l)446     public void updateUI(JLayer<? extends V> l){
447     }
448 
449     /**
450      * Configures the {@code JLayer} this {@code LayerUI} is set to.
451      * The default implementation registers the passed {@code JLayer} component
452      * as a {@code PropertyChangeListener} for the property changes of this {@code LayerUI}.
453      *
454      * @param c the {@code JLayer} component where this UI delegate is being installed
455      */
installUI(JComponent c)456     public void installUI(JComponent c) {
457         addPropertyChangeListener((JLayer) c);
458     }
459 
460     /**
461      * Reverses the configuration which was previously set
462      * in the {@link #installUI(JComponent)} method.
463      * The default implementation unregisters the passed {@code JLayer} component
464      * as a {@code PropertyChangeListener} for the property changes of this {@code LayerUI}.
465      *
466      * @param c the component from which this UI delegate is being removed.
467      */
uninstallUI(JComponent c)468     public void uninstallUI(JComponent c) {
469         removePropertyChangeListener((JLayer) c);
470     }
471 
472     /**
473      * Adds a PropertyChangeListener to the listener list. The listener is
474      * registered for all bound properties of this class.
475      * <p>
476      * If {@code listener} is {@code null},
477      * no exception is thrown and no action is performed.
478      *
479      * @param listener the property change listener to be added
480      * @see #removePropertyChangeListener
481      * @see #getPropertyChangeListeners
482      * @see #addPropertyChangeListener(String, java.beans.PropertyChangeListener)
483      */
addPropertyChangeListener(PropertyChangeListener listener)484     public void addPropertyChangeListener(PropertyChangeListener listener) {
485         propertyChangeSupport.addPropertyChangeListener(listener);
486     }
487 
488     /**
489      * Removes a PropertyChangeListener from the listener list. This method
490      * should be used to remove PropertyChangeListeners that were registered
491      * for all bound properties of this class.
492      * <p>
493      * If {@code listener} is {@code null},
494      * no exception is thrown and no action is performed.
495      *
496      * @param listener the PropertyChangeListener to be removed
497      * @see #addPropertyChangeListener
498      * @see #getPropertyChangeListeners
499      * @see #removePropertyChangeListener(String, PropertyChangeListener)
500      */
removePropertyChangeListener(PropertyChangeListener listener)501     public void removePropertyChangeListener(PropertyChangeListener listener) {
502         propertyChangeSupport.removePropertyChangeListener(listener);
503     }
504 
505     /**
506      * Returns an array of all the property change listeners
507      * registered on this component.
508      *
509      * @return all of this ui's {@code PropertyChangeListener}s
510      *         or an empty array if no property change
511      *         listeners are currently registered
512      * @see #addPropertyChangeListener
513      * @see #removePropertyChangeListener
514      * @see #getPropertyChangeListeners(String)
515      */
getPropertyChangeListeners()516     public PropertyChangeListener[] getPropertyChangeListeners() {
517         return propertyChangeSupport.getPropertyChangeListeners();
518     }
519 
520     /**
521      * Adds a PropertyChangeListener to the listener list for a specific
522      * property.
523      * <p>
524      * If {@code propertyName} or {@code listener} is {@code null},
525      * no exception is thrown and no action is taken.
526      *
527      * @param propertyName one of the property names listed above
528      * @param listener     the property change listener to be added
529      * @see #removePropertyChangeListener(String, PropertyChangeListener)
530      * @see #getPropertyChangeListeners(String)
531      * @see #addPropertyChangeListener(String, PropertyChangeListener)
532      */
addPropertyChangeListener(String propertyName, PropertyChangeListener listener)533     public void addPropertyChangeListener(String propertyName,
534                                           PropertyChangeListener listener) {
535         propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
536     }
537 
538     /**
539      * Removes a {@code PropertyChangeListener} from the listener
540      * list for a specific property. This method should be used to remove
541      * {@code PropertyChangeListener}s
542      * that were registered for a specific bound property.
543      * <p>
544      * If {@code propertyName} or {@code listener} is {@code null},
545      * no exception is thrown and no action is taken.
546      *
547      * @param propertyName a valid property name
548      * @param listener     the PropertyChangeListener to be removed
549      * @see #addPropertyChangeListener(String, PropertyChangeListener)
550      * @see #getPropertyChangeListeners(String)
551      * @see #removePropertyChangeListener(PropertyChangeListener)
552      */
removePropertyChangeListener(String propertyName, PropertyChangeListener listener)553     public void removePropertyChangeListener(String propertyName,
554                                              PropertyChangeListener listener) {
555         propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
556     }
557 
558     /**
559      * Returns an array of all the listeners which have been associated
560      * with the named property.
561      *
562      * @param propertyName  The name of the property being listened to
563      * @return all of the {@code PropertyChangeListener}s associated with
564      *         the named property; if no such listeners have been added or
565      *         if {@code propertyName} is {@code null}, an empty
566      *         array is returned
567      * @see #addPropertyChangeListener(String, PropertyChangeListener)
568      * @see #removePropertyChangeListener(String, PropertyChangeListener)
569      * @see #getPropertyChangeListeners
570      */
getPropertyChangeListeners(String propertyName)571     public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
572         return propertyChangeSupport.getPropertyChangeListeners(propertyName);
573     }
574 
575     /**
576      * Support for reporting bound property changes for Object properties.
577      * This method can be called when a bound property has changed and it will
578      * send the appropriate PropertyChangeEvent to any registered
579      * PropertyChangeListeners.
580      *
581      * @param propertyName the property whose value has changed
582      * @param oldValue     the property's previous value
583      * @param newValue     the property's new value
584      */
firePropertyChange(String propertyName, Object oldValue, Object newValue)585     protected void firePropertyChange(String propertyName,
586                                       Object oldValue, Object newValue) {
587         propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
588     }
589 
590     /**
591      * Notifies the {@code LayerUI} when any of its property are changed
592      * and enables updating every {@code JLayer}
593      * this {@code LayerUI} instance is set to.
594      *
595      * @param evt the PropertyChangeEvent generated by this {@code LayerUI}
596      * @param l the {@code JLayer} this LayerUI is set to
597      */
applyPropertyChange(PropertyChangeEvent evt, JLayer<? extends V> l)598     public void applyPropertyChange(PropertyChangeEvent evt, JLayer<? extends V> l) {
599     }
600 
601     /**
602      * If the {@code JLayer}'s view component is not {@code null},
603      * this calls the view's {@code getBaseline()} method.
604      * Otherwise, the default implementation is called.
605      *
606      * @param c {@code JLayer} to return baseline resize behavior for
607      * @param width the width to get the baseline for
608      * @param height the height to get the baseline for
609      * @return baseline or a value &lt; 0 indicating there is no reasonable
610      *                  baseline
611      */
getBaseline(JComponent c, int width, int height)612     public int getBaseline(JComponent c, int width, int height) {
613         @SuppressWarnings("unchecked")
614         JLayer<?> l = (JLayer) c;
615         if (l.getView() != null) {
616             return l.getView().getBaseline(width, height);
617         }
618         return super.getBaseline(c, width, height);
619      }
620 
621     /**
622      * If the {@code JLayer}'s view component is not {@code null},
623      * this returns the result of the view's {@code getBaselineResizeBehavior()} method.
624      * Otherwise, the default implementation is called.
625      *
626      * @param c {@code JLayer} to return baseline resize behavior for
627      * @return an enum indicating how the baseline changes as the component
628      *         size changes
629      */
getBaselineResizeBehavior(JComponent c)630     public Component.BaselineResizeBehavior getBaselineResizeBehavior(JComponent c) {
631         @SuppressWarnings("unchecked")
632         JLayer<?> l = (JLayer) c;
633         if (l.getView() != null) {
634             return l.getView().getBaselineResizeBehavior();
635         }
636         return super.getBaselineResizeBehavior(c);
637     }
638 
639     /**
640      * Causes the passed instance of {@code JLayer} to lay out its components.
641      *
642      * @param l the {@code JLayer} component where this UI delegate is being installed
643      */
doLayout(JLayer<? extends V> l)644     public void doLayout(JLayer<? extends V> l) {
645         Component view = l.getView();
646         if (view != null) {
647             view.setBounds(0, 0, l.getWidth(), l.getHeight());
648         }
649         Component glassPane = l.getGlassPane();
650         if (glassPane != null) {
651             glassPane.setBounds(0, 0, l.getWidth(), l.getHeight());
652         }
653     }
654 
655     /**
656      * If the {@code JLayer}'s view component is not {@code null},
657      * this returns the result of  the view's {@code getPreferredSize()} method.
658      * Otherwise, the default implementation is used.
659      *
660      * @param c {@code JLayer} to return preferred size for
661      * @return preferred size for the passed {@code JLayer}
662      */
getPreferredSize(JComponent c)663     public Dimension getPreferredSize(JComponent c) {
664         @SuppressWarnings("unchecked")
665         JLayer<?> l = (JLayer) c;
666         Component view = l.getView();
667         if (view != null) {
668             return view.getPreferredSize();
669         }
670         return super.getPreferredSize(c);
671     }
672 
673     /**
674      * If the {@code JLayer}'s view component is not {@code null},
675      * this returns the result of  the view's {@code getMinimalSize()} method.
676      * Otherwise, the default implementation is used.
677      *
678      * @param c {@code JLayer} to return preferred size for
679      * @return minimal size for the passed {@code JLayer}
680      */
getMinimumSize(JComponent c)681     public Dimension getMinimumSize(JComponent c) {
682         @SuppressWarnings("unchecked")
683         JLayer<?> l = (JLayer) c;
684         Component view = l.getView();
685         if (view != null) {
686             return view.getMinimumSize();
687         }
688         return super.getMinimumSize(c);
689     }
690 
691     /**
692      * If the {@code JLayer}'s view component is not {@code null},
693      * this returns the result of  the view's {@code getMaximumSize()} method.
694      * Otherwise, the default implementation is used.
695      *
696      * @param c {@code JLayer} to return preferred size for
697      * @return maximum size for the passed {@code JLayer}
698      */
getMaximumSize(JComponent c)699     public Dimension getMaximumSize(JComponent c) {
700         @SuppressWarnings("unchecked")
701         JLayer<?> l = (JLayer) c;
702         Component view = l.getView();
703         if (view != null) {
704             return view.getMaximumSize();
705         }
706         return super.getMaximumSize(c);
707     }
708 
709     /**
710      * Paints the specified region in the {@code JLayer} this {@code LayerUI} is set to, immediately.
711      * <p>
712      * This method is to be overridden when the dirty region needs to be changed.
713      * The default implementation delegates its functionality to {@link JComponent#paintImmediately(int, int, int, int)}.
714      *
715      * @param x  the x value of the region to be painted
716      * @param y  the y value of the region to be painted
717      * @param width  the width of the region to be painted
718      * @param height  the height of the region to be painted
719      * @param l  a {@code JLayer} component
720      * @see JComponent#paintImmediately(int, int, int, int)
721      */
paintImmediately(int x, int y, int width, int height, JLayer<? extends V> l)722     public void paintImmediately(int x, int y, int width, int height, JLayer<? extends V> l) {
723         l.paintImmediately(x, y, width, height);
724     }
725 
726     /**
727      * Delegates its functionality to the default implementation of the {@code JLayer.imageUpdate} method
728      * which is inherited from {@code JLayer}'s base classes.
729      * <p>
730      * This method is to be overridden instead of {@code JLayer.imageUpdate}.
731      * <p>
732      * <b>Note:</b> This method is usually called <b>not</b> on the Event Dispatching Thread.
733      *
734      * @param img the image being observed
735      * @param infoflags see imageUpdate for information
736      * @param x the x coordinate
737      * @param y the y coordinate
738      * @param w the width
739      * @param h the height
740      * @param l a {@code JLayer} component
741      * @return false if the infoflags indicate that the image is completely loaded; true otherwise
742      */
imageUpdate(Image img, int infoflags, int x, int y, int w, int h, JLayer<? extends V> l)743     public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h, JLayer<? extends V> l) {
744         return l.imageUpdate(img, infoflags, x, y, w, h);
745     }
746 }
747