KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > java > swing > plaf > windows > WindowsScrollBarUI


1 /*
2  * @(#)WindowsScrollBarUI.java 1.21 06/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.java.swing.plaf.windows;
9
10 import java.awt.*;
11 import java.awt.image.*;
12 import java.lang.ref.*;
13 import java.util.*;
14 import javax.swing.plaf.basic.*;
15 import javax.swing.*;
16 import javax.swing.plaf.ComponentUI JavaDoc;
17
18 import com.sun.java.swing.plaf.windows.TMSchema.*;
19 import com.sun.java.swing.plaf.windows.XPStyle.Skin;
20
21
22 /**
23  * Windows rendition of the component.
24  * <p>
25  * <strong>Warning:</strong>
26  * Serialized objects of this class will not be compatible with
27  * future Swing releases. The current serialization support is appropriate
28  * for short term storage or RMI between applications running the same
29  * version of Swing. A future release of Swing will provide support for
30  * long term persistence.
31  */

32 public class WindowsScrollBarUI extends BasicScrollBarUI {
33     private Grid thumbGrid;
34     private Grid highlightGrid;
35
36     /**
37      * Creates a UI for a JScrollBar.
38      *
39      * @param c the text field
40      * @return the UI
41      */

42     public static ComponentUI JavaDoc createUI(JComponent c) {
43         return new WindowsScrollBarUI();
44     }
45
46     protected void installDefaults() {
47     super.installDefaults();
48
49     if (XPStyle.getXP() != null) {
50         scrollbar.setBorder(null);
51     }
52     }
53
54     public void uninstallUI(JComponent c) {
55         super.uninstallUI(c);
56         thumbGrid = highlightGrid = null;
57     }
58
59     protected void configureScrollBarColors() {
60         super.configureScrollBarColors();
61     Color color = UIManager.getColor("ScrollBar.trackForeground");
62         if (color != null && trackColor != null) {
63             thumbGrid = Grid.getGrid(color, trackColor);
64         }
65
66     color = UIManager.getColor("ScrollBar.trackHighlightForeground");
67         if (color != null && trackHighlightColor != null) {
68             highlightGrid = Grid.getGrid(color, trackHighlightColor);
69         }
70     }
71
72     protected JButton createDecreaseButton(int orientation) {
73         return new WindowsArrowButton(orientation,
74                     UIManager.getColor("ScrollBar.thumb"),
75                     UIManager.getColor("ScrollBar.thumbShadow"),
76                     UIManager.getColor("ScrollBar.thumbDarkShadow"),
77                     UIManager.getColor("ScrollBar.thumbHighlight"));
78     }
79
80     protected JButton createIncreaseButton(int orientation) {
81         return new WindowsArrowButton(orientation,
82                     UIManager.getColor("ScrollBar.thumb"),
83                     UIManager.getColor("ScrollBar.thumbShadow"),
84                     UIManager.getColor("ScrollBar.thumbDarkShadow"),
85                     UIManager.getColor("ScrollBar.thumbHighlight"));
86     }
87
88
89     protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds){
90     boolean v = (scrollbar.getOrientation() == JScrollBar.VERTICAL);
91
92     XPStyle xp = XPStyle.getXP();
93     if (xp != null) {
94         JScrollBar sb = (JScrollBar)c;
95             State state = State.NORMAL;
96             // Pending: Implement rollover (hot) and pressed
97
if (!sb.isEnabled()) {
98                 state = State.DISABLED;
99         }
100             Part part = v ? Part.SBP_LOWERTRACKVERT : Part.SBP_LOWERTRACKHORZ;
101             xp.getSkin(sb, part).paintSkin(g, trackBounds, state);
102     } else if (thumbGrid == null) {
103             super.paintTrack(g, c, trackBounds);
104         }
105         else {
106             thumbGrid.paint(g, trackBounds.x, trackBounds.y, trackBounds.width,
107                             trackBounds.height);
108             if (trackHighlight == DECREASE_HIGHLIGHT) {
109                 paintDecreaseHighlight(g);
110             }
111             else if (trackHighlight == INCREASE_HIGHLIGHT) {
112                 paintIncreaseHighlight(g);
113             }
114         }
115     }
116
117     protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
118     boolean v = (scrollbar.getOrientation() == JScrollBar.VERTICAL);
119
120     XPStyle xp = XPStyle.getXP();
121     if (xp != null) {
122         JScrollBar sb = (JScrollBar)c;
123             State state = State.NORMAL;
124         if (!sb.isEnabled()) {
125                 state = State.DISABLED;
126         } else if (isDragging) {
127                 state = State.PRESSED;
128         } else if (isThumbRollover()) {
129                 state = State.HOT;
130         }
131         // Paint thumb
132
Part thumbPart = v ? Part.SBP_THUMBBTNVERT : Part.SBP_THUMBBTNHORZ;
133             xp.getSkin(sb, thumbPart).paintSkin(g, thumbBounds, state);
134         // Paint gripper
135
Part gripperPart = v ? Part.SBP_GRIPPERVERT : Part.SBP_GRIPPERHORZ;
136             Skin skin = xp.getSkin(sb, gripperPart);
137             Insets gripperInsets = xp.getMargin(c, thumbPart, null,
138                 Prop.CONTENTMARGINS);
139             if (gripperInsets == null ||
140                     (v && (thumbBounds.height - gripperInsets.top -
141                             gripperInsets.bottom >= skin.getHeight())) ||
142                     (!v && (thumbBounds.width - gripperInsets.left -
143                             gripperInsets.right >= skin.getWidth()))) {
144                 skin.paintSkin(g,
145                                thumbBounds.x + (thumbBounds.width - skin.getWidth()) / 2,
146                                thumbBounds.y + (thumbBounds.height - skin.getHeight()) / 2,
147                                skin.getWidth(), skin.getHeight(), state);
148             }
149     } else {
150         super.paintThumb(g, c, thumbBounds);
151     }
152     }
153
154
155     protected void paintDecreaseHighlight(Graphics g) {
156         if (highlightGrid == null) {
157             super.paintDecreaseHighlight(g);
158         }
159         else {
160             Insets insets = scrollbar.getInsets();
161             Rectangle thumbR = getThumbBounds();
162             int x, y, w, h;
163
164             if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
165                 x = insets.left;
166                 y = decrButton.getY() + decrButton.getHeight();
167                 w = scrollbar.getWidth() - (insets.left + insets.right);
168                 h = thumbR.y - y;
169             }
170             else {
171                 x = decrButton.getX() + decrButton.getHeight();
172                 y = insets.top;
173                 w = thumbR.x - x;
174                 h = scrollbar.getHeight() - (insets.top + insets.bottom);
175             }
176             highlightGrid.paint(g, x, y, w, h);
177     }
178     }
179     
180
181     protected void paintIncreaseHighlight(Graphics g) {
182         if (highlightGrid == null) {
183             super.paintDecreaseHighlight(g);
184         }
185         else {
186             Insets insets = scrollbar.getInsets();
187             Rectangle thumbR = getThumbBounds();
188             int x, y, w, h;
189
190             if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
191                 x = insets.left;
192                 y = thumbR.y + thumbR.height;
193                 w = scrollbar.getWidth() - (insets.left + insets.right);
194                 h = incrButton.getY() - y;
195             }
196             else {
197                 x = thumbR.x + thumbR.width;
198                 y = insets.top;
199                 w = incrButton.getX() - x;
200                 h = scrollbar.getHeight() - (insets.top + insets.bottom);
201             }
202             highlightGrid.paint(g, x, y, w, h);
203         }
204     }
205
206
207     /**
208      * WindowsArrowButton is used for the buttons to position the
209      * document up/down. It differs from BasicArrowButton in that the
210      * preferred size is always a square.
211      */

212     private class WindowsArrowButton extends BasicArrowButton {
213
214         public WindowsArrowButton(int direction, Color background, Color shadow,
215              Color darkShadow, Color highlight) {
216         super(direction, background, shadow, darkShadow, highlight);
217     }
218
219         public WindowsArrowButton(int direction) {
220             super(direction);
221         }
222
223     public void paint(Graphics g) {
224         XPStyle xp = XPStyle.getXP();
225         if (xp != null) {
226         ButtonModel model = getModel();
227                 Skin skin = xp.getSkin(scrollbar, Part.SBP_ARROWBTN);
228                 State state = null;
229
230         // normal, rollover, pressed, disabled
231
if (model.isArmed() && model.isPressed()) {
232                     switch (direction) {
233                     case NORTH: state = State.UPPRESSED; break;
234                     case SOUTH: state = State.DOWNPRESSED; break;
235                     case WEST: state = State.LEFTPRESSED; break;
236                     case EAST: state = State.RIGHTPRESSED; break;
237                     }
238         } else if (!model.isEnabled()) {
239                     switch (direction) {
240                     case NORTH: state = State.UPDISABLED; break;
241                     case SOUTH: state = State.DOWNDISABLED; break;
242                     case WEST: state = State.LEFTDISABLED; break;
243                     case EAST: state = State.RIGHTDISABLED; break;
244                     }
245         } else if (model.isRollover() || model.isPressed()) {
246                     switch (direction) {
247                     case NORTH: state = State.UPHOT; break;
248                     case SOUTH: state = State.DOWNHOT; break;
249                     case WEST: state = State.LEFTHOT; break;
250                     case EAST: state = State.RIGHTHOT; break;
251                     }
252                 } else {
253                   switch (direction) {
254                   case NORTH: state = State.UPNORMAL; break;
255                   case SOUTH: state = State.DOWNNORMAL; break;
256                   case WEST: state = State.LEFTNORMAL; break;
257                   case EAST: state = State.RIGHTNORMAL; break;
258                   }
259         }
260
261                 skin.paintSkin(g, 0, 0, getWidth(), getHeight(), state);
262         } else {
263         super.paint(g);
264         }
265     }
266
267         public Dimension getPreferredSize() {
268             int size = 16;
269             if (scrollbar != null) {
270                 switch (scrollbar.getOrientation()) {
271                 case JScrollBar.VERTICAL:
272                     size = scrollbar.getWidth();
273                     break;
274                 case JScrollBar.HORIZONTAL:
275                     size = scrollbar.getHeight();
276                     break;
277                 }
278                 size = Math.max(size, 5);
279             }
280             return new Dimension(size, size);
281         }
282     }
283
284
285     /**
286      * This should be pulled out into its own class if more classes need to
287      * use it.
288      * <p>
289      * Grid is used to draw the track for windows scrollbars. Grids
290      * are cached in a HashMap, with the key being the rgb components
291      * of the foreground/background colors. Further the Grid is held through
292      * a WeakRef so that it can be freed when no longer needed. As the
293      * Grid is rather expensive to draw, it is drawn in a BufferedImage.
294      */

295     private static class Grid {
296         private static final int BUFFER_SIZE = 64;
297         private static HashMap map;
298
299         private BufferedImage image;
300
301         static {
302             map = new HashMap();
303         }
304
305         public static Grid getGrid(Color fg, Color bg) {
306             String JavaDoc key = fg.getRGB() + " " + bg.getRGB();
307             WeakReference ref = (WeakReference)map.get(key);
308             Grid grid = (ref == null) ? null : (Grid)ref.get();
309             if (grid == null) {
310                 grid = new Grid(fg, bg);
311                 map.put(key, new WeakReference(grid));
312             }
313             return grid;
314         }
315
316         public Grid(Color fg, Color bg) {
317             int cmap[] = { fg.getRGB(), bg.getRGB() };
318             IndexColorModel icm = new IndexColorModel(8, 2, cmap, 0, false, -1,
319                                                       DataBuffer.TYPE_BYTE);
320             image = new BufferedImage(BUFFER_SIZE, BUFFER_SIZE,
321                                       BufferedImage.TYPE_BYTE_INDEXED, icm);
322             Graphics g = image.getGraphics();
323             try {
324                 g.setClip(0, 0, BUFFER_SIZE, BUFFER_SIZE);
325                 paintGrid(g, fg, bg);
326             }
327             finally {
328                 g.dispose();
329             }
330         }
331
332         /**
333          * Paints the grid into the specified Graphics at the specified
334          * location.
335          */

336         public void paint(Graphics g, int x, int y, int w, int h) {
337             Rectangle clipRect = g.getClipBounds();
338             int minX = Math.max(x, clipRect.x);
339             int minY = Math.max(y, clipRect.y);
340             int maxX = Math.min(clipRect.x + clipRect.width, x + w);
341             int maxY = Math.min(clipRect.y + clipRect.height, y + h);
342
343             if (maxX <= minX || maxY <= minY) {
344                 return;
345             }
346             int xOffset = (minX - x) % 2;
347             for (int xCounter = minX; xCounter < maxX;
348                  xCounter += BUFFER_SIZE) {
349                 int yOffset = (minY - y) % 2;
350                 int width = Math.min(BUFFER_SIZE - xOffset,
351                                      maxX - xCounter);
352
353                 for (int yCounter = minY; yCounter < maxY;
354                      yCounter += BUFFER_SIZE) {
355                     int height = Math.min(BUFFER_SIZE - yOffset,
356                                           maxY - yCounter);
357
358                     g.drawImage(image, xCounter, yCounter,
359                                 xCounter + width, yCounter + height,
360                                 xOffset, yOffset,
361                                 xOffset + width, yOffset + height, null);
362                     if (yOffset != 0) {
363                         yCounter -= yOffset;
364                         yOffset = 0;
365                     }
366                 }
367                 if (xOffset != 0) {
368                     xCounter -= xOffset;
369                     xOffset = 0;
370                 }
371             }
372         }
373
374         /**
375          * Actually renders the grid into the Graphics <code>g</code>.
376          */

377         private void paintGrid(Graphics g, Color fg, Color bg) {
378             Rectangle clipRect = g.getClipBounds();
379             g.setColor(bg);
380             g.fillRect(clipRect.x, clipRect.y, clipRect.width,
381                        clipRect.height);
382             g.setColor(fg);
383             g.translate(clipRect.x, clipRect.y);
384             int width = clipRect.width;
385             int height = clipRect.height;
386             int xCounter = clipRect.x % 2;
387             for (int end = width - height; xCounter < end; xCounter += 2) {
388                 g.drawLine(xCounter, 0, xCounter + height, height);
389             }
390             for (int end = width; xCounter < end; xCounter += 2) {
391                 g.drawLine(xCounter, 0, width, width - xCounter);
392             }
393
394             int yCounter = ((clipRect.x % 2) == 0) ? 2 : 1;
395             for (int end = height - width; yCounter < end; yCounter += 2) {
396                 g.drawLine(0, yCounter, width, yCounter + width);
397             }
398             for (int end = height; yCounter < end; yCounter += 2) {
399                 g.drawLine(0, yCounter, height - yCounter, height);
400             }
401             g.translate(-clipRect.x, -clipRect.y);
402         }
403     }
404 }
405
Popular Tags