|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package javax.swing.plaf.metal; |
|
|
|
import java.awt.Color; |
|
import java.awt.Dimension; |
|
import java.awt.Graphics; |
|
import java.awt.Rectangle; |
|
import java.beans.PropertyChangeEvent; |
|
import java.beans.PropertyChangeListener; |
|
|
|
import javax.swing.JButton; |
|
import javax.swing.JComponent; |
|
import javax.swing.JScrollBar; |
|
import javax.swing.UIManager; |
|
import javax.swing.plaf.ComponentUI; |
|
import javax.swing.plaf.basic.BasicScrollBarUI; |
|
|
|
import static sun.swing.SwingUtilities2.drawHLine; |
|
import static sun.swing.SwingUtilities2.drawRect; |
|
import static sun.swing.SwingUtilities2.drawVLine; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public class MetalScrollBarUI extends BasicScrollBarUI |
|
{ |
|
private static Color shadowColor; |
|
private static Color highlightColor; |
|
private static Color darkShadowColor; |
|
private static Color thumbColor; |
|
private static Color thumbShadow; |
|
private static Color thumbHighlightColor; |
|
|
|
|
|
protected MetalBumps bumps; |
|
|
|
protected MetalScrollButton increaseButton; |
|
protected MetalScrollButton decreaseButton; |
|
|
|
protected int scrollBarWidth; |
|
|
|
public static final String FREE_STANDING_PROP = "JScrollBar.isFreeStanding"; |
|
protected boolean isFreeStanding = true; |
|
|
|
public static ComponentUI createUI( JComponent c ) |
|
{ |
|
return new MetalScrollBarUI(); |
|
} |
|
|
|
protected void installDefaults() { |
|
scrollBarWidth = ((Integer)(UIManager.get( "ScrollBar.width" ))).intValue(); |
|
super.installDefaults(); |
|
bumps = new MetalBumps( 10, 10, thumbHighlightColor, thumbShadow, thumbColor ); |
|
} |
|
|
|
protected void installListeners(){ |
|
super.installListeners(); |
|
((ScrollBarListener)propertyChangeListener).handlePropertyChange( scrollbar.getClientProperty( FREE_STANDING_PROP ) ); |
|
} |
|
|
|
protected PropertyChangeListener createPropertyChangeListener(){ |
|
return new ScrollBarListener(); |
|
} |
|
|
|
protected void configureScrollBarColors() |
|
{ |
|
super.configureScrollBarColors(); |
|
shadowColor = UIManager.getColor("ScrollBar.shadow"); |
|
highlightColor = UIManager.getColor("ScrollBar.highlight"); |
|
darkShadowColor = UIManager.getColor("ScrollBar.darkShadow"); |
|
thumbColor = UIManager.getColor("ScrollBar.thumb"); |
|
thumbShadow = UIManager.getColor("ScrollBar.thumbShadow"); |
|
thumbHighlightColor = UIManager.getColor("ScrollBar.thumbHighlight"); |
|
|
|
|
|
} |
|
|
|
public Dimension getPreferredSize( JComponent c ) |
|
{ |
|
if ( scrollbar.getOrientation() == JScrollBar.VERTICAL ) |
|
{ |
|
return new Dimension( scrollBarWidth, scrollBarWidth * 3 + 10 ); |
|
} |
|
else |
|
{ |
|
return new Dimension( scrollBarWidth * 3 + 10, scrollBarWidth ); |
|
} |
|
|
|
} |
|
|
|
|
|
*/ |
|
protected JButton createDecreaseButton( int orientation ) |
|
{ |
|
decreaseButton = new MetalScrollButton( orientation, scrollBarWidth, isFreeStanding ); |
|
return decreaseButton; |
|
} |
|
|
|
|
|
protected JButton createIncreaseButton( int orientation ) |
|
{ |
|
increaseButton = new MetalScrollButton( orientation, scrollBarWidth, isFreeStanding ); |
|
return increaseButton; |
|
} |
|
|
|
protected void paintTrack( Graphics g, JComponent c, Rectangle trackBounds ) |
|
{ |
|
g.translate( trackBounds.x, trackBounds.y ); |
|
|
|
boolean leftToRight = MetalUtils.isLeftToRight(c); |
|
|
|
if ( scrollbar.getOrientation() == JScrollBar.VERTICAL ) |
|
{ |
|
if ( !isFreeStanding ) { |
|
trackBounds.width += 2; |
|
if ( !leftToRight ) { |
|
g.translate( -1, 0 ); |
|
} |
|
} |
|
|
|
if ( c.isEnabled() ) { |
|
g.setColor( darkShadowColor ); |
|
drawVLine(g, 0, 0, trackBounds.height - 1); |
|
drawVLine(g, trackBounds.width - 2, 0, trackBounds.height - 1); |
|
drawHLine(g, 2, trackBounds.width - 1, trackBounds.height - 1); |
|
drawHLine(g, 2, trackBounds.width - 2, 0); |
|
|
|
g.setColor( shadowColor ); |
|
|
|
drawVLine(g, 1, 1, trackBounds.height - 2); |
|
drawHLine(g, 1, trackBounds.width - 3, 1); |
|
if (scrollbar.getValue() != scrollbar.getMaximum()) { |
|
int y = thumbRect.y + thumbRect.height - trackBounds.y; |
|
drawHLine(g, 1, trackBounds.width - 1, y); |
|
} |
|
g.setColor(highlightColor); |
|
drawVLine(g, trackBounds.width - 1, 0, trackBounds.height - 1); |
|
} else { |
|
MetalUtils.drawDisabledBorder(g, 0, 0, trackBounds.width, trackBounds.height ); |
|
} |
|
|
|
if ( !isFreeStanding ) { |
|
trackBounds.width -= 2; |
|
if ( !leftToRight ) { |
|
g.translate( 1, 0 ); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
if ( !isFreeStanding ) { |
|
trackBounds.height += 2; |
|
} |
|
|
|
if ( c.isEnabled() ) { |
|
g.setColor( darkShadowColor ); |
|
drawHLine(g, 0, trackBounds.width - 1, 0); |
|
drawVLine(g, 0, 2, trackBounds.height - 2); |
|
drawHLine(g, 0, trackBounds.width - 1, trackBounds.height - 2 ); |
|
drawVLine(g, trackBounds.width - 1, 2, trackBounds.height - 1 ); |
|
|
|
g.setColor( shadowColor ); |
|
// g.setColor( Color.red); |
|
drawHLine(g, 1, trackBounds.width - 2, 1 ); |
|
drawVLine(g, 1, 1, trackBounds.height - 3 ); |
|
drawHLine(g, 0, trackBounds.width - 1, trackBounds.height - 1 ); |
|
if (scrollbar.getValue() != scrollbar.getMaximum()) { |
|
int x = thumbRect.x + thumbRect.width - trackBounds.x; |
|
drawVLine(g, x, 1, trackBounds.height-1); |
|
} |
|
} else { |
|
MetalUtils.drawDisabledBorder(g, 0, 0, trackBounds.width, trackBounds.height ); |
|
} |
|
|
|
if ( !isFreeStanding ) { |
|
trackBounds.height -= 2; |
|
} |
|
} |
|
|
|
g.translate( -trackBounds.x, -trackBounds.y ); |
|
} |
|
|
|
protected void paintThumb( Graphics g, JComponent c, Rectangle thumbBounds ) |
|
{ |
|
if (!c.isEnabled()) { |
|
return; |
|
} |
|
|
|
if (MetalLookAndFeel.usingOcean()) { |
|
oceanPaintThumb(g, c, thumbBounds); |
|
return; |
|
} |
|
|
|
boolean leftToRight = MetalUtils.isLeftToRight(c); |
|
|
|
g.translate( thumbBounds.x, thumbBounds.y ); |
|
|
|
if ( scrollbar.getOrientation() == JScrollBar.VERTICAL ) |
|
{ |
|
if ( !isFreeStanding ) { |
|
thumbBounds.width += 2; |
|
if ( !leftToRight ) { |
|
g.translate( -1, 0 ); |
|
} |
|
} |
|
|
|
g.setColor( thumbColor ); |
|
g.fillRect( 0, 0, thumbBounds.width - 2, thumbBounds.height - 1 ); |
|
|
|
g.setColor( thumbShadow ); |
|
drawRect(g, 0, 0, thumbBounds.width - 2, thumbBounds.height - 1); |
|
|
|
g.setColor( thumbHighlightColor ); |
|
drawHLine(g, 1, thumbBounds.width - 3, 1); |
|
drawVLine(g, 1, 1, thumbBounds.height - 2); |
|
|
|
bumps.setBumpArea( thumbBounds.width - 6, thumbBounds.height - 7 ); |
|
bumps.paintIcon( c, g, 3, 4 ); |
|
|
|
if ( !isFreeStanding ) { |
|
thumbBounds.width -= 2; |
|
if ( !leftToRight ) { |
|
g.translate( 1, 0 ); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
if ( !isFreeStanding ) { |
|
thumbBounds.height += 2; |
|
} |
|
|
|
g.setColor( thumbColor ); |
|
g.fillRect( 0, 0, thumbBounds.width - 1, thumbBounds.height - 2 ); |
|
|
|
g.setColor( thumbShadow ); |
|
drawRect(g, 0, 0, thumbBounds.width - 1, thumbBounds.height - 2); |
|
|
|
g.setColor( thumbHighlightColor ); |
|
drawHLine(g, 1, thumbBounds.width - 3, 1); |
|
drawVLine(g, 1, 1, thumbBounds.height - 3); |
|
|
|
bumps.setBumpArea( thumbBounds.width - 7, thumbBounds.height - 6 ); |
|
bumps.paintIcon( c, g, 4, 3 ); |
|
|
|
if ( !isFreeStanding ) { |
|
thumbBounds.height -= 2; |
|
} |
|
} |
|
|
|
g.translate( -thumbBounds.x, -thumbBounds.y ); |
|
} |
|
|
|
private void oceanPaintThumb(Graphics g, JComponent c, |
|
Rectangle thumbBounds) { |
|
boolean leftToRight = MetalUtils.isLeftToRight(c); |
|
|
|
g.translate(thumbBounds.x, thumbBounds.y); |
|
|
|
if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { |
|
if (!isFreeStanding) { |
|
thumbBounds.width += 2; |
|
if (!leftToRight) { |
|
g.translate(-1, 0); |
|
} |
|
} |
|
|
|
if (thumbColor != null) { |
|
g.setColor(thumbColor); |
|
g.fillRect(0, 0, thumbBounds.width - 2,thumbBounds.height - 1); |
|
} |
|
|
|
g.setColor(thumbShadow); |
|
drawRect(g, 0, 0, thumbBounds.width - 2, thumbBounds.height - 1); |
|
|
|
g.setColor(thumbHighlightColor); |
|
drawHLine(g, 1, thumbBounds.width - 3, 1); |
|
drawVLine(g, 1, 1, thumbBounds.height - 2); |
|
|
|
MetalUtils.drawGradient(c, g, "ScrollBar.gradient", 2, 2, |
|
thumbBounds.width - 4, |
|
thumbBounds.height - 3, false); |
|
|
|
int gripSize = thumbBounds.width - 8; |
|
if (gripSize > 2 && thumbBounds.height >= 10) { |
|
g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow()); |
|
int gripY = thumbBounds.height / 2 - 2; |
|
for (int counter = 0; counter < 6; counter += 2) { |
|
g.fillRect(4, counter + gripY, gripSize, 1); |
|
} |
|
|
|
g.setColor(MetalLookAndFeel.getWhite()); |
|
gripY++; |
|
for (int counter = 0; counter < 6; counter += 2) { |
|
g.fillRect(5, counter + gripY, gripSize, 1); |
|
} |
|
} |
|
if (!isFreeStanding) { |
|
thumbBounds.width -= 2; |
|
if (!leftToRight) { |
|
g.translate(1, 0); |
|
} |
|
} |
|
} |
|
else { |
|
if (!isFreeStanding) { |
|
thumbBounds.height += 2; |
|
} |
|
|
|
if (thumbColor != null) { |
|
g.setColor(thumbColor); |
|
g.fillRect(0, 0, thumbBounds.width - 1,thumbBounds.height - 2); |
|
} |
|
|
|
g.setColor(thumbShadow); |
|
drawRect(g, 0, 0, thumbBounds.width - 1, thumbBounds.height - 2); |
|
|
|
g.setColor(thumbHighlightColor); |
|
drawHLine(g, 1, thumbBounds.width - 2, 1); |
|
drawVLine(g, 1, 1, thumbBounds.height - 3); |
|
|
|
MetalUtils.drawGradient(c, g, "ScrollBar.gradient", 2, 2, |
|
thumbBounds.width - 3, |
|
thumbBounds.height - 4, true); |
|
|
|
int gripSize = thumbBounds.height - 8; |
|
if (gripSize > 2 && thumbBounds.width >= 10) { |
|
g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow()); |
|
int gripX = thumbBounds.width / 2 - 2; |
|
for (int counter = 0; counter < 6; counter += 2) { |
|
g.fillRect(gripX + counter, 4, 1, gripSize); |
|
} |
|
|
|
g.setColor(MetalLookAndFeel.getWhite()); |
|
gripX++; |
|
for (int counter = 0; counter < 6; counter += 2) { |
|
g.fillRect(gripX + counter, 5, 1, gripSize); |
|
} |
|
} |
|
|
|
if (!isFreeStanding) { |
|
thumbBounds.height -= 2; |
|
} |
|
} |
|
|
|
g.translate( -thumbBounds.x, -thumbBounds.y ); |
|
} |
|
|
|
protected Dimension getMinimumThumbSize() |
|
{ |
|
return new Dimension( scrollBarWidth, scrollBarWidth ); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
protected void setThumbBounds(int x, int y, int width, int height) |
|
{ |
|
|
|
*/ |
|
if ((thumbRect.x == x) && |
|
(thumbRect.y == y) && |
|
(thumbRect.width == width) && |
|
(thumbRect.height == height)) { |
|
return; |
|
} |
|
|
|
|
|
|
|
*/ |
|
int minX = Math.min(x, thumbRect.x); |
|
int minY = Math.min(y, thumbRect.y); |
|
int maxX = Math.max(x + width, thumbRect.x + thumbRect.width); |
|
int maxY = Math.max(y + height, thumbRect.y + thumbRect.height); |
|
|
|
thumbRect.setBounds(x, y, width, height); |
|
scrollbar.repaint(minX, minY, (maxX - minX)+1, (maxY - minY)+1); |
|
} |
|
|
|
|
|
|
|
class ScrollBarListener extends BasicScrollBarUI.PropertyChangeHandler |
|
{ |
|
public void propertyChange(PropertyChangeEvent e) |
|
{ |
|
String name = e.getPropertyName(); |
|
if ( name.equals( FREE_STANDING_PROP ) ) |
|
{ |
|
handlePropertyChange( e.getNewValue() ); |
|
} |
|
else { |
|
super.propertyChange( e ); |
|
} |
|
} |
|
|
|
public void handlePropertyChange( Object newValue ) |
|
{ |
|
if ( newValue != null ) |
|
{ |
|
boolean temp = ((Boolean)newValue).booleanValue(); |
|
boolean becameFlush = temp == false && isFreeStanding == true; |
|
boolean becameNormal = temp == true && isFreeStanding == false; |
|
|
|
isFreeStanding = temp; |
|
|
|
if ( becameFlush ) { |
|
toFlush(); |
|
} |
|
else if ( becameNormal ) { |
|
toFreeStanding(); |
|
} |
|
} |
|
else |
|
{ |
|
|
|
if ( !isFreeStanding ) { |
|
isFreeStanding = true; |
|
toFreeStanding(); |
|
} |
|
|
|
// This commented-out block is used for testing flush scrollbars. |
|
/* |
|
if ( isFreeStanding ) { |
|
isFreeStanding = false; |
|
toFlush(); |
|
} |
|
*/ |
|
} |
|
|
|
if ( increaseButton != null ) |
|
{ |
|
increaseButton.setFreeStanding( isFreeStanding ); |
|
} |
|
if ( decreaseButton != null ) |
|
{ |
|
decreaseButton.setFreeStanding( isFreeStanding ); |
|
} |
|
} |
|
|
|
protected void toFlush() { |
|
scrollBarWidth -= 2; |
|
} |
|
|
|
protected void toFreeStanding() { |
|
scrollBarWidth += 2; |
|
} |
|
} // end class ScrollBarListener |
|
} |