001 /*
002 * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.swing.plaf.synth;
027
028 import java.awt.*;
029 import java.awt.event.*;
030
031 import java.beans.*;
032
033 import javax.swing.*;
034 import javax.swing.event.*;
035 import javax.swing.plaf.*;
036 import javax.swing.plaf.basic.*;
037 import sun.swing.plaf.synth.SynthUI;
038
039 /**
040 * Synth's ScrollBarUI.
041 *
042 * @version 1.38, 05/05/07
043 * @author Scott Violet
044 */
045 class SynthScrollBarUI extends BasicScrollBarUI implements
046 PropertyChangeListener, SynthUI {
047
048 private SynthStyle style;
049 private SynthStyle thumbStyle;
050 private SynthStyle trackStyle;
051
052 private boolean validMinimumThumbSize;
053 private int scrollBarWidth;
054
055 public static ComponentUI createUI(JComponent c) {
056 return new SynthScrollBarUI();
057 }
058
059 protected void installDefaults() {
060 trackHighlight = NO_HIGHLIGHT;
061 if (scrollbar.getLayout() == null
062 || (scrollbar.getLayout() instanceof UIResource)) {
063 scrollbar.setLayout(this );
064 }
065 updateStyle(scrollbar);
066 }
067
068 protected void configureScrollBarColors() {
069 }
070
071 private void updateStyle(JScrollBar c) {
072 SynthStyle oldStyle = style;
073 SynthContext context = getContext(c, ENABLED);
074 style = SynthLookAndFeel.updateStyle(context, this );
075 if (style != oldStyle) {
076 scrollBarWidth = style.getInt(context,
077 "ScrollBar.thumbHeight", 14);
078 minimumThumbSize = (Dimension) style.get(context,
079 "ScrollBar.minimumThumbSize");
080 if (minimumThumbSize == null) {
081 minimumThumbSize = new Dimension();
082 validMinimumThumbSize = false;
083 } else {
084 validMinimumThumbSize = true;
085 }
086 maximumThumbSize = (Dimension) style.get(context,
087 "ScrollBar.maximumThumbSize");
088 if (maximumThumbSize == null) {
089 maximumThumbSize = new Dimension(4096, 4097);
090 }
091 if (oldStyle != null) {
092 uninstallKeyboardActions();
093 installKeyboardActions();
094 }
095 }
096 context.dispose();
097
098 context = getContext(c, Region.SCROLL_BAR_TRACK, ENABLED);
099 trackStyle = SynthLookAndFeel.updateStyle(context, this );
100 context.dispose();
101
102 context = getContext(c, Region.SCROLL_BAR_THUMB, ENABLED);
103 thumbStyle = SynthLookAndFeel.updateStyle(context, this );
104 context.dispose();
105 }
106
107 protected void installListeners() {
108 super .installListeners();
109 scrollbar.addPropertyChangeListener(this );
110 }
111
112 protected void uninstallListeners() {
113 super .uninstallListeners();
114 scrollbar.removePropertyChangeListener(this );
115 }
116
117 protected void uninstallDefaults() {
118 SynthContext context = getContext(scrollbar, ENABLED);
119 style.uninstallDefaults(context);
120 context.dispose();
121 style = null;
122
123 context = getContext(scrollbar, Region.SCROLL_BAR_TRACK,
124 ENABLED);
125 trackStyle.uninstallDefaults(context);
126 context.dispose();
127 trackStyle = null;
128
129 context = getContext(scrollbar, Region.SCROLL_BAR_THUMB,
130 ENABLED);
131 thumbStyle.uninstallDefaults(context);
132 context.dispose();
133 thumbStyle = null;
134
135 super .uninstallDefaults();
136 }
137
138 public SynthContext getContext(JComponent c) {
139 return getContext(c, getComponentState(c));
140 }
141
142 private SynthContext getContext(JComponent c, int state) {
143 return SynthContext.getContext(SynthContext.class, c,
144 SynthLookAndFeel.getRegion(c), style, state);
145 }
146
147 private Region getRegion(JComponent c) {
148 return SynthLookAndFeel.getRegion(c);
149 }
150
151 private int getComponentState(JComponent c) {
152 return SynthLookAndFeel.getComponentState(c);
153 }
154
155 private SynthContext getContext(JComponent c, Region region) {
156 return getContext(c, region, getComponentState(c, region));
157 }
158
159 private SynthContext getContext(JComponent c, Region region,
160 int state) {
161 SynthStyle style = trackStyle;
162
163 if (region == Region.SCROLL_BAR_THUMB) {
164 style = thumbStyle;
165 }
166 return SynthContext.getContext(SynthContext.class, c, region,
167 style, state);
168 }
169
170 private int getComponentState(JComponent c, Region region) {
171 if (region == Region.SCROLL_BAR_THUMB && isThumbRollover()
172 && c.isEnabled()) {
173 return MOUSE_OVER;
174 }
175 return SynthLookAndFeel.getComponentState(c);
176 }
177
178 public boolean getSupportsAbsolutePositioning() {
179 SynthContext context = getContext(scrollbar);
180 boolean value = style.getBoolean(context,
181 "ScrollBar.allowsAbsolutePositioning", false);
182 context.dispose();
183 return value;
184 }
185
186 public void update(Graphics g, JComponent c) {
187 SynthContext context = getContext(c);
188
189 SynthLookAndFeel.update(context, g);
190 context.getPainter()
191 .paintScrollBarBackground(context, g, 0, 0,
192 c.getWidth(), c.getHeight(),
193 scrollbar.getOrientation());
194 paint(context, g);
195 context.dispose();
196 }
197
198 public void paint(Graphics g, JComponent c) {
199 SynthContext context = getContext(c);
200
201 paint(context, g);
202 context.dispose();
203 }
204
205 protected void paint(SynthContext context, Graphics g) {
206 SynthContext subcontext = getContext(scrollbar,
207 Region.SCROLL_BAR_TRACK);
208 paintTrack(subcontext, g, getTrackBounds());
209 subcontext.dispose();
210
211 subcontext = getContext(scrollbar, Region.SCROLL_BAR_THUMB);
212 paintThumb(subcontext, g, getThumbBounds());
213 subcontext.dispose();
214 }
215
216 public void paintBorder(SynthContext context, Graphics g, int x,
217 int y, int w, int h) {
218 context.getPainter().paintScrollBarBorder(context, g, x, y, w,
219 h, scrollbar.getOrientation());
220 }
221
222 protected void paintTrack(SynthContext ss, Graphics g,
223 Rectangle trackBounds) {
224 SynthLookAndFeel.updateSubregion(ss, g, trackBounds);
225 ss.getPainter().paintScrollBarTrackBackground(ss, g,
226 trackBounds.x, trackBounds.y, trackBounds.width,
227 trackBounds.height, scrollbar.getOrientation());
228 ss.getPainter().paintScrollBarTrackBorder(ss, g, trackBounds.x,
229 trackBounds.y, trackBounds.width, trackBounds.height,
230 scrollbar.getOrientation());
231 }
232
233 protected void paintThumb(SynthContext ss, Graphics g,
234 Rectangle thumbBounds) {
235 SynthLookAndFeel.updateSubregion(ss, g, thumbBounds);
236 int orientation = scrollbar.getOrientation();
237 ss.getPainter().paintScrollBarThumbBackground(ss, g,
238 thumbBounds.x, thumbBounds.y, thumbBounds.width,
239 thumbBounds.height, orientation);
240 ss.getPainter().paintScrollBarThumbBorder(ss, g, thumbBounds.x,
241 thumbBounds.y, thumbBounds.width, thumbBounds.height,
242 orientation);
243 }
244
245 /**
246 * A vertical scrollbar's preferred width is the maximum of
247 * preferred widths of the (non <code>null</code>)
248 * increment/decrement buttons,
249 * and the minimum width of the thumb. The preferred height is the
250 * sum of the preferred heights of the same parts. The basis for
251 * the preferred size of a horizontal scrollbar is similar.
252 * <p>
253 * The <code>preferredSize</code> is only computed once, subsequent
254 * calls to this method just return a cached size.
255 *
256 * @param c the <code>JScrollBar</code> that's delegating this method to us
257 * @return the preferred size of a Basic JScrollBar
258 * @see #getMaximumSize
259 * @see #getMinimumSize
260 */
261 public Dimension getPreferredSize(JComponent c) {
262 Insets insets = c.getInsets();
263 return (scrollbar.getOrientation() == JScrollBar.VERTICAL) ? new Dimension(
264 scrollBarWidth + insets.left + insets.right, 48)
265 : new Dimension(48, scrollBarWidth + insets.top
266 + insets.bottom);
267 }
268
269 protected Dimension getMinimumThumbSize() {
270 if (!validMinimumThumbSize) {
271 if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
272 minimumThumbSize.width = scrollBarWidth;
273 minimumThumbSize.height = 7;
274 } else {
275 minimumThumbSize.width = 7;
276 minimumThumbSize.height = scrollBarWidth;
277 }
278 }
279 return minimumThumbSize;
280
281 }
282
283 protected JButton createDecreaseButton(int orientation) {
284 SynthArrowButton synthArrowButton = new SynthArrowButton(
285 orientation);
286 synthArrowButton.setName("ScrollBar.button");
287 return synthArrowButton;
288 }
289
290 protected JButton createIncreaseButton(int orientation) {
291 SynthArrowButton synthArrowButton = new SynthArrowButton(
292 orientation);
293 synthArrowButton.setName("ScrollBar.button");
294 return synthArrowButton;
295 }
296
297 protected void setThumbRollover(boolean active) {
298 if (isThumbRollover() != active) {
299 scrollbar.repaint(getThumbBounds());
300 super .setThumbRollover(active);
301 }
302 }
303
304 private void updateButtonDirections() {
305 int orient = scrollbar.getOrientation();
306 if (scrollbar.getComponentOrientation().isLeftToRight()) {
307 ((SynthArrowButton) incrButton)
308 .setDirection(orient == HORIZONTAL ? EAST : SOUTH);
309 ((SynthArrowButton) decrButton)
310 .setDirection(orient == HORIZONTAL ? WEST : NORTH);
311 } else {
312 ((SynthArrowButton) incrButton)
313 .setDirection(orient == HORIZONTAL ? WEST : SOUTH);
314 ((SynthArrowButton) decrButton)
315 .setDirection(orient == HORIZONTAL ? EAST : NORTH);
316 }
317 }
318
319 //
320 // PropertyChangeListener
321 //
322 public void propertyChange(PropertyChangeEvent e) {
323 String propertyName = e.getPropertyName();
324
325 if (SynthLookAndFeel.shouldUpdateStyle(e)) {
326 updateStyle((JScrollBar) e.getSource());
327 }
328
329 if ("orientation" == propertyName) {
330 updateButtonDirections();
331 } else if ("componentOrientation" == propertyName) {
332 updateButtonDirections();
333 }
334 }
335 }
|