1/*
2 * Copyright (c) 2002, 2013, 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.synth;
27
28import java.beans.*;
29import javax.swing.*;
30import javax.swing.plaf.*;
31import java.awt.*;
32
33
34/**
35 * Provides the Synth L&F UI delegate for
36 * {@link javax.swing.JViewport}.
37 *
38 * @since 1.7
39 */
40public class SynthViewportUI extends ViewportUI
41                             implements PropertyChangeListener, SynthUI {
42    private SynthStyle style;
43
44    /**
45     * Creates a new UI object for the given component.
46     *
47     * @param c component to create UI object for
48     * @return the UI object
49     */
50    public static ComponentUI createUI(JComponent c) {
51        return new SynthViewportUI();
52    }
53
54    /**
55     * {@inheritDoc}
56     */
57    @Override
58    public void installUI(JComponent c) {
59        super.installUI(c);
60        installDefaults(c);
61        installListeners(c);
62    }
63
64    /**
65     * {@inheritDoc}
66     */
67    @Override
68    public void uninstallUI(JComponent c) {
69        super.uninstallUI(c);
70        uninstallListeners(c);
71        uninstallDefaults(c);
72    }
73
74    /**
75     * Installs defaults for a viewport.
76     *
77     * @param c a {@code JViewport} object
78     */
79    protected void installDefaults(JComponent c) {
80        updateStyle(c);
81    }
82
83    private void updateStyle(JComponent c) {
84        SynthContext context = getContext(c, ENABLED);
85
86        // Note: JViewport is special cased as it does not allow for
87        // a border to be set. JViewport.setBorder is overriden to throw
88        // an IllegalArgumentException. Refer to SynthScrollPaneUI for
89        // details of this.
90        SynthStyle newStyle = SynthLookAndFeel.getStyle(context.getComponent(),
91                                                        context.getRegion());
92        SynthStyle oldStyle = context.getStyle();
93
94        if (newStyle != oldStyle) {
95            if (oldStyle != null) {
96                oldStyle.uninstallDefaults(context);
97            }
98            context.setStyle(newStyle);
99            newStyle.installDefaults(context);
100        }
101        this.style = newStyle;
102    }
103
104    /**
105     * Installs listeners into the viewport.
106     *
107     * @param c a {@code JViewport} object
108     */
109    protected void installListeners(JComponent c) {
110        c.addPropertyChangeListener(this);
111    }
112
113    /**
114     * Uninstalls listeners from the viewport.
115     *
116     * @param c a {@code JViewport} object
117     */
118    protected void uninstallListeners(JComponent c) {
119        c.removePropertyChangeListener(this);
120    }
121
122    /**
123     * Uninstalls defaults from a viewport.
124     *
125     * @param c a {@code JViewport} object
126     */
127    protected void uninstallDefaults(JComponent c) {
128        SynthContext context = getContext(c, ENABLED);
129        style.uninstallDefaults(context);
130        style = null;
131    }
132
133    /**
134     * {@inheritDoc}
135     */
136    @Override
137    public SynthContext getContext(JComponent c) {
138        return getContext(c, SynthLookAndFeel.getComponentState(c));
139    }
140
141    private SynthContext getContext(JComponent c, int state) {
142        return SynthContext.getContext(c, style, state);
143    }
144
145    private Region getRegion(JComponent c) {
146        return SynthLookAndFeel.getRegion(c);
147    }
148
149    /**
150     * Notifies this UI delegate to repaint the specified component.
151     * This method paints the component background, then calls
152     * the {@link #paint(SynthContext,Graphics)} method.
153     *
154     * <p>In general, this method does not need to be overridden by subclasses.
155     * All Look and Feel rendering code should reside in the {@code paint} method.
156     *
157     * @param g the {@code Graphics} object used for painting
158     * @param c the component being painted
159     * @see #paint(SynthContext,Graphics)
160     */
161    @Override
162    public void update(Graphics g, JComponent c) {
163        SynthContext context = getContext(c);
164
165        SynthLookAndFeel.update(context, g);
166        context.getPainter().paintViewportBackground(context,
167                          g, 0, 0, c.getWidth(), c.getHeight());
168        paint(context, g);
169    }
170
171    /**
172     * Paints the border. The method is never called,
173     * because the {@code JViewport} class does not support a border.
174     * This implementation does nothing.
175     *
176     * @param context a component context
177     * @param g the {@code Graphics} to paint on
178     * @param x the X coordinate
179     * @param y the Y coordinate
180     * @param w width of the border
181     * @param h height of the border
182     */
183    @Override
184    public void paintBorder(SynthContext context, Graphics g, int x,
185                            int y, int w, int h) {
186    }
187
188    /**
189     * Paints the specified component according to the Look and Feel.
190     * <p>This method is not used by Synth Look and Feel.
191     * Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
192     *
193     * @param g the {@code Graphics} object used for painting
194     * @param c the component being painted
195     * @see #paint(SynthContext,Graphics)
196     */
197    @Override
198    public void paint(Graphics g, JComponent c) {
199        SynthContext context = getContext(c);
200
201        paint(context, g);
202    }
203
204    /**
205     * Paints the specified component. This implementation does nothing.
206     *
207     * @param context context for the component being painted
208     * @param g the {@code Graphics} object used for painting
209     * @see #update(Graphics,JComponent)
210     */
211    protected void paint(SynthContext context, Graphics g) {
212    }
213
214    /**
215     * {@inheritDoc}
216     */
217    @Override
218    public void propertyChange(PropertyChangeEvent e) {
219        if (SynthLookAndFeel.shouldUpdateStyle(e)) {
220            updateStyle((JComponent)e.getSource());
221        }
222    }
223}
224