LayerUI.java revision 10517:e50dfa1c0902
1/*
2 * Copyright (c) 2009, 2014, 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
26package javax.swing.plaf;
27
28import javax.swing.*;
29import java.awt.*;
30import java.awt.event.*;
31import java.beans.PropertyChangeEvent;
32import java.beans.PropertyChangeSupport;
33import java.beans.PropertyChangeListener;
34import 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
62public 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     */
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&lt;event&nbsp;type&gt;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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h, JLayer<? extends V> l) {
735        return l.imageUpdate(img, infoflags, x, y, w, h);
736    }
737}
738