56 |
/** |
/** |
57 |
* A UI delegate for the {@link JScrollBar} component. |
* A UI delegate for the {@link JScrollBar} component. |
58 |
*/ |
*/ |
59 |
public class MetalScrollBarUI |
public class MetalScrollBarUI extends BasicScrollBarUI |
|
extends BasicScrollBarUI |
|
60 |
{ |
{ |
61 |
|
|
62 |
/** |
/** |
74 |
*/ |
*/ |
75 |
public MetalScrollBarPropertyChangeHandler() |
public MetalScrollBarPropertyChangeHandler() |
76 |
{ |
{ |
77 |
|
// Nothing to do here. |
78 |
} |
} |
79 |
|
|
80 |
/** |
/** |
90 |
{ |
{ |
91 |
Boolean prop = (Boolean) e.getNewValue(); |
Boolean prop = (Boolean) e.getNewValue(); |
92 |
isFreeStanding = (prop == null ? true : prop.booleanValue()); |
isFreeStanding = (prop == null ? true : prop.booleanValue()); |
93 |
increaseButton.setFreeStanding(isFreeStanding); |
if (increaseButton != null) |
94 |
decreaseButton.setFreeStanding(isFreeStanding); |
increaseButton.setFreeStanding(isFreeStanding); |
95 |
|
if (decreaseButton != null) |
96 |
|
decreaseButton.setFreeStanding(isFreeStanding); |
97 |
} |
} |
98 |
|
else |
99 |
|
super.propertyChange(e); |
100 |
} |
} |
101 |
} |
} |
102 |
|
|
103 |
/** The name for the 'free standing' property. */ |
/** The name for the 'free standing' property. */ |
104 |
public static final String FREE_STANDING_PROP = "JScrollBar.isFreeStanding"; |
public static final String FREE_STANDING_PROP = "JScrollBar.isFreeStanding"; |
105 |
|
|
106 |
/** The minimum thumb size */ |
/** The minimum thumb size for a scroll bar that is not free standing. */ |
107 |
private static final Dimension MIN_THUMB_SIZE = new Dimension(17, 17); |
private static final Dimension MIN_THUMB_SIZE = new Dimension(15, 15); |
108 |
|
|
109 |
|
/** The minimum thumb size for a scroll bar that is free standing. */ |
110 |
|
private static final Dimension MIN_THUMB_SIZE_FREE_STANDING |
111 |
|
= new Dimension(17, 17); |
112 |
|
|
113 |
/** The button that increases the value in the scroll bar. */ |
/** The button that increases the value in the scroll bar. */ |
114 |
protected MetalScrollButton increaseButton; |
protected MetalScrollButton increaseButton; |
115 |
|
|
116 |
/** The button that decreases the value in the scroll bar. */ |
/** The button that decreases the value in the scroll bar. */ |
117 |
protected MetalScrollButton decreaseButton; |
protected MetalScrollButton decreaseButton; |
118 |
|
|
119 |
/** The scroll bar width. */ |
/** |
120 |
|
* The scroll bar width. |
121 |
|
*/ |
122 |
protected int scrollBarWidth; |
protected int scrollBarWidth; |
123 |
|
|
124 |
/** |
/** |
127 |
* scroll bar which is not free standing has borders missing from one |
* scroll bar which is not free standing has borders missing from one |
128 |
* side, and relies on being part of another container with its own borders |
* side, and relies on being part of another container with its own borders |
129 |
* to look right visually. */ |
* to look right visually. */ |
130 |
protected boolean isFreeStanding; |
protected boolean isFreeStanding = true; |
131 |
|
|
132 |
|
/** |
133 |
|
* The color for the scroll bar shadow (this is read from the UIDefaults in |
134 |
|
* the installDefaults() method). |
135 |
|
*/ |
136 |
|
Color scrollBarShadowColor; |
137 |
|
|
138 |
/** |
/** |
139 |
* Constructs a new instance of MetalScrollBarUI. |
* Constructs a new instance of <code>MetalScrollBarUI</code>, with no |
140 |
|
* specific initialisation. |
141 |
*/ |
*/ |
142 |
public MetalScrollBarUI() |
public MetalScrollBarUI() |
143 |
{ |
{ |
145 |
} |
} |
146 |
|
|
147 |
/** |
/** |
148 |
* Returns an instance of MetalScrollBarUI. |
* Returns a new instance of <code>MetalScrollBarUI</code>. |
149 |
* |
* |
150 |
* @param component the component for which we return an UI instance |
* @param component the component for which we return an UI instance |
151 |
* |
* |
152 |
* @return an instance of MetalScrollBarUI |
* @return An instance of MetalScrollBarUI |
153 |
*/ |
*/ |
154 |
public static ComponentUI createUI(JComponent component) |
public static ComponentUI createUI(JComponent component) |
155 |
{ |
{ |
167 |
// that we can do this). |
// that we can do this). |
168 |
Boolean prop = (Boolean) scrollbar.getClientProperty(FREE_STANDING_PROP); |
Boolean prop = (Boolean) scrollbar.getClientProperty(FREE_STANDING_PROP); |
169 |
isFreeStanding = (prop == null ? true : prop.booleanValue()); |
isFreeStanding = (prop == null ? true : prop.booleanValue()); |
170 |
|
scrollBarShadowColor = UIManager.getColor("ScrollBar.shadow"); |
171 |
super.installDefaults(); |
super.installDefaults(); |
172 |
} |
} |
173 |
|
|
197 |
{ |
{ |
198 |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
199 |
scrollBarWidth = defaults.getInt("ScrollBar.width"); |
scrollBarWidth = defaults.getInt("ScrollBar.width"); |
200 |
return new MetalScrollButton(orientation, scrollBarWidth, isFreeStanding); |
decreaseButton = new MetalScrollButton(orientation, scrollBarWidth, |
201 |
|
isFreeStanding); |
202 |
|
return decreaseButton; |
203 |
} |
} |
204 |
|
|
205 |
/** |
/** |
215 |
{ |
{ |
216 |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
217 |
scrollBarWidth = defaults.getInt("ScrollBar.width"); |
scrollBarWidth = defaults.getInt("ScrollBar.width"); |
218 |
return new MetalScrollButton(orientation, scrollBarWidth, isFreeStanding); |
increaseButton = new MetalScrollButton(orientation, scrollBarWidth, |
219 |
|
isFreeStanding); |
220 |
|
return increaseButton; |
221 |
} |
} |
222 |
|
|
223 |
/** |
/** |
261 |
g.drawLine(x, y, x + w - 1, y); |
g.drawLine(x, y, x + w - 1, y); |
262 |
g.drawLine(x + w - 1, y, x + w - 1, y + h - 1); |
g.drawLine(x + w - 1, y, x + w - 1, y + h - 1); |
263 |
|
|
264 |
g.setColor(MetalLookAndFeel.getControlShadow()); |
g.setColor(scrollBarShadowColor); |
265 |
g.drawLine(x + 1, y + 1, x + 1, y + h - 1); |
g.drawLine(x + 1, y + 1, x + 1, y + h - 1); |
266 |
g.drawLine(x + 1, y + 1, x + w - 2, y + 1); |
g.drawLine(x + 1, y + 1, x + w - 2, y + 1); |
267 |
|
|
269 |
{ |
{ |
270 |
g.setColor(MetalLookAndFeel.getControlDarkShadow()); |
g.setColor(MetalLookAndFeel.getControlDarkShadow()); |
271 |
g.drawLine(x, y + h - 2, x + w - 1, y + h - 2); |
g.drawLine(x, y + h - 2, x + w - 1, y + h - 2); |
272 |
g.setColor(MetalLookAndFeel.getControlShadow()); |
g.setColor(scrollBarShadowColor); |
273 |
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1); |
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1); |
274 |
} |
} |
275 |
} |
} |
276 |
else |
else |
277 |
{ |
{ |
278 |
g.setColor(MetalLookAndFeel.getControlDisabled()); |
g.setColor(MetalLookAndFeel.getControlDisabled()); |
279 |
g.drawRect(x, y, w - 1, h - 1); |
if (isFreeStanding) |
280 |
|
g.drawRect(x, y, w - 1, h - 1); |
281 |
|
else |
282 |
|
{ |
283 |
|
g.drawLine(x, y, x + w - 1, y); |
284 |
|
g.drawLine(x, y, x, y + h - 1); |
285 |
|
g.drawLine(x + w - 1, y, x + w - 1, y + h - 1); |
286 |
|
} |
287 |
} |
} |
288 |
} |
} |
289 |
|
|
297 |
* @param w the width for the track bounds. |
* @param w the width for the track bounds. |
298 |
* @param h the height for the track bounds. |
* @param h the height for the track bounds. |
299 |
*/ |
*/ |
300 |
protected void paintTrackVertical(Graphics g, JComponent c, |
private void paintTrackVertical(Graphics g, JComponent c, |
301 |
int x, int y, int w, int h) |
int x, int y, int w, int h) |
302 |
{ |
{ |
303 |
if (c.isEnabled()) |
if (c.isEnabled()) |
307 |
g.drawLine(x, y, x + w - 1, y); |
g.drawLine(x, y, x + w - 1, y); |
308 |
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1); |
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1); |
309 |
|
|
310 |
g.setColor(MetalLookAndFeel.getControlShadow()); |
g.setColor(scrollBarShadowColor); |
311 |
g.drawLine(x + 1, y + 1, x + w - 1, y + 1); |
g.drawLine(x + 1, y + 1, x + w - 1, y + 1); |
312 |
g.drawLine(x + 1, y + 1, x + 1, y + h - 2); |
g.drawLine(x + 1, y + 1, x + 1, y + h - 2); |
|
g.drawLine(x + 1, y + h - 2, x + w - 1, y + h - 2); |
|
313 |
|
|
314 |
if (isFreeStanding) |
if (isFreeStanding) |
315 |
{ |
{ |
322 |
else |
else |
323 |
{ |
{ |
324 |
g.setColor(MetalLookAndFeel.getControlDisabled()); |
g.setColor(MetalLookAndFeel.getControlDisabled()); |
325 |
g.drawRect(x, y, w - 1, h - 1); |
if (isFreeStanding) |
326 |
|
g.drawRect(x, y, w - 1, h - 1); |
327 |
|
else |
328 |
|
{ |
329 |
|
g.drawLine(x, y, x + w - 1, y); |
330 |
|
g.drawLine(x, y, x, y + h - 1); |
331 |
|
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1); |
332 |
|
} |
333 |
} |
} |
334 |
} |
} |
335 |
|
|
345 |
// a disabled scrollbar has no thumb in the metal look and feel |
// a disabled scrollbar has no thumb in the metal look and feel |
346 |
if (!c.isEnabled()) |
if (!c.isEnabled()) |
347 |
return; |
return; |
348 |
|
if (scrollbar.getOrientation() == HORIZONTAL) |
349 |
|
paintThumbHorizontal(g, c, thumbBounds); |
350 |
|
else |
351 |
|
paintThumbVertical(g, c, thumbBounds); |
352 |
|
|
353 |
|
// draw the pattern |
354 |
|
MetalUtils.fillMetalPattern(c, g, thumbBounds.x + 3, thumbBounds.y + 3, |
355 |
|
thumbBounds.width - 6, thumbBounds.height - 6, |
356 |
|
thumbHighlightColor, thumbLightShadowColor); |
357 |
|
} |
358 |
|
|
359 |
|
/** |
360 |
|
* Paints the thumb for a horizontal scroll bar. |
361 |
|
* |
362 |
|
* @param g the graphics device. |
363 |
|
* @param c the scroll bar component. |
364 |
|
* @param thumbBounds the thumb bounds. |
365 |
|
*/ |
366 |
|
private void paintThumbHorizontal(Graphics g, JComponent c, |
367 |
|
Rectangle thumbBounds) |
368 |
|
{ |
369 |
|
int x = thumbBounds.x; |
370 |
|
int y = thumbBounds.y; |
371 |
|
int w = thumbBounds.width; |
372 |
|
int h = thumbBounds.height; |
373 |
|
|
374 |
// first we fill the background |
// first we fill the background |
375 |
g.setColor(thumbColor); |
g.setColor(thumbColor); |
376 |
g.fillRect(thumbBounds.x, thumbBounds.y, thumbBounds.width, |
if (isFreeStanding) |
377 |
thumbBounds.height); |
g.fillRect(x, y, w, h - 1); |
|
|
|
|
// draw the outer dark line |
|
|
int hAdj = 1; |
|
|
int wAdj = 1; |
|
|
if (scrollbar.getOrientation() == HORIZONTAL) |
|
|
hAdj++; |
|
378 |
else |
else |
379 |
wAdj++; |
g.fillRect(x, y, w, h); |
380 |
|
|
381 |
g.setColor(new Color(102, 102, 153)); |
// then draw the dark box |
382 |
g.drawRect(thumbBounds.x, thumbBounds.y, thumbBounds.width - wAdj, |
g.setColor(thumbLightShadowColor); |
383 |
thumbBounds.height - hAdj); |
if (isFreeStanding) |
384 |
|
g.drawRect(x, y, w - 1, h - 2); |
385 |
// draw the inner light line |
else |
386 |
|
{ |
387 |
|
g.drawLine(x, y, x + w - 1, y); |
388 |
|
g.drawLine(x, y, x, y + h - 1); |
389 |
|
g.drawLine(x + w - 1, y, x + w - 1, y + h -1); |
390 |
|
} |
391 |
|
|
392 |
|
// then the highlight |
393 |
g.setColor(thumbHighlightColor); |
g.setColor(thumbHighlightColor); |
394 |
g.drawLine(thumbBounds.x + 1, thumbBounds.y + 1, |
if (isFreeStanding) |
395 |
thumbBounds.x + thumbBounds.width - 2, |
{ |
396 |
thumbBounds.y + 1); |
g.drawLine(x + 1, y + 1, x + w - 3, y + 1); |
397 |
g.drawLine(thumbBounds.x + 1, thumbBounds.y + 1, |
g.drawLine(x + 1, y + 1, x + 1, y + h - 3); |
398 |
thumbBounds.x + 1, |
} |
399 |
thumbBounds.y + thumbBounds.height - 2); |
else |
400 |
|
{ |
401 |
|
g.drawLine(x + 1, y + 1, x + w - 3, y + 1); |
402 |
|
g.drawLine(x + 1, y + 1, x + 1, y + h - 1); |
403 |
|
} |
404 |
|
|
405 |
// draw the shadow line |
// draw the shadow line |
406 |
UIDefaults def = UIManager.getLookAndFeelDefaults(); |
UIDefaults def = UIManager.getLookAndFeelDefaults(); |
407 |
g.setColor(def.getColor("ScrollBar.shadow")); |
g.setColor(def.getColor("ScrollBar.shadow")); |
408 |
g.drawLine(thumbBounds.x + 1, thumbBounds.y + thumbBounds.height, |
g.drawLine(x + w, y + 1, x + w, y + h - 1); |
|
thumbBounds.x + thumbBounds.width, |
|
|
thumbBounds.y + thumbBounds.height); |
|
409 |
|
|
|
// draw the pattern |
|
|
MetalUtils.fillMetalPattern(g, thumbBounds.x + 3, thumbBounds.y + 3, |
|
|
thumbBounds.width - 6, thumbBounds.height - 6, |
|
|
thumbHighlightColor, new Color(102, 102, 153)); |
|
410 |
} |
} |
411 |
|
|
412 |
|
/** |
413 |
|
* Paints the thumb for a vertical scroll bar. |
414 |
|
* |
415 |
|
* @param g the graphics device. |
416 |
|
* @param c the scroll bar component. |
417 |
|
* @param thumbBounds the thumb bounds. |
418 |
|
*/ |
419 |
|
private void paintThumbVertical(Graphics g, JComponent c, |
420 |
|
Rectangle thumbBounds) |
421 |
|
{ |
422 |
|
int x = thumbBounds.x; |
423 |
|
int y = thumbBounds.y; |
424 |
|
int w = thumbBounds.width; |
425 |
|
int h = thumbBounds.height; |
426 |
|
|
427 |
|
// first we fill the background |
428 |
|
g.setColor(thumbColor); |
429 |
|
if (isFreeStanding) |
430 |
|
g.fillRect(x, y, w - 1, h); |
431 |
|
else |
432 |
|
g.fillRect(x, y, w, h); |
433 |
|
|
434 |
|
// then draw the dark box |
435 |
|
g.setColor(thumbLightShadowColor); |
436 |
|
if (isFreeStanding) |
437 |
|
g.drawRect(x, y, w - 2, h - 1); |
438 |
|
else |
439 |
|
{ |
440 |
|
g.drawLine(x, y, x + w - 1, y); |
441 |
|
g.drawLine(x, y, x, y + h - 1); |
442 |
|
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1); |
443 |
|
} |
444 |
|
|
445 |
|
// then the highlight |
446 |
|
g.setColor(thumbHighlightColor); |
447 |
|
if (isFreeStanding) |
448 |
|
{ |
449 |
|
g.drawLine(x + 1, y + 1, x + w - 3, y + 1); |
450 |
|
g.drawLine(x + 1, y + 1, x + 1, y + h - 3); |
451 |
|
} |
452 |
|
else |
453 |
|
{ |
454 |
|
g.drawLine(x + 1, y + 1, x + w - 1, y + 1); |
455 |
|
g.drawLine(x + 1, y + 1, x + 1, y + h - 3); |
456 |
|
} |
457 |
|
|
458 |
|
// draw the shadow line |
459 |
|
UIDefaults def = UIManager.getLookAndFeelDefaults(); |
460 |
|
g.setColor(def.getColor("ScrollBar.shadow")); |
461 |
|
g.drawLine(x + 1, y + h, x + w - 2, y + h); |
462 |
|
} |
463 |
|
|
464 |
/** |
/** |
465 |
* This method returns the minimum thumb size. |
* Returns the minimum thumb size. For a free standing scroll bar the |
466 |
|
* minimum size is <code>17 x 17</code> pixels, whereas for a non free |
467 |
|
* standing scroll bar the minimum size is <code>15 x 15</code> pixels. |
468 |
* |
* |
469 |
* @return The minimum thumb size. |
* @return The minimum thumb size. |
470 |
*/ |
*/ |
471 |
protected Dimension getMinimumThumbSize() |
protected Dimension getMinimumThumbSize() |
472 |
{ |
{ |
473 |
return MIN_THUMB_SIZE; |
if (isFreeStanding) |
474 |
|
return MIN_THUMB_SIZE_FREE_STANDING; |
475 |
|
else |
476 |
|
return MIN_THUMB_SIZE; |
477 |
} |
} |
478 |
|
|
479 |
} |
} |