/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Tiny Look and Feel *
* *
* (C) Copyright 2003 - 2007 Hans Bickel *
* *
* For licensing information and credits, please refer to the *
* comment in file de.muntjak.tinylookandfeel.TinyLookAndFeel *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package de.muntjak.tinylookandfeel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.beans.*;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicScrollBarUI;
import de.muntjak.tinylookandfeel.controlpanel.*;
/**
* TinyScrollBarUI
*
* @version 1.0
* @author Hans Bickel
*/
public class TinyScrollBarUI extends BasicScrollBarUI {
static final int alpha = 92; // 255 is full opaque
/** true if thumb is in rollover state */
protected boolean isRollover=false;
/** true if thumb was in rollover state */
protected boolean wasRollover=false;
/**
* The free standing property of this scrollbar UI delegate.
*/
private boolean freeStanding = false;
private int scrollBarWidth;
public TinyScrollBarUI() {}
/**
* Installs some default values.
*/
protected void installDefaults() {
scrollBarWidth = TinyScrollButton.size[Theme.derivedStyle[Theme.style]].width;
super.installDefaults();
scrollbar.setBorder(null);
minimumThumbSize = new Dimension(17, 17);
}
protected Dimension getMaximumThumbSize() {
return maximumThumbSize;
}
/**
* Creates the UI delegate for the given component.
*
* @param mainColor The component to create its UI delegate.
* @return The UI delegate for the given component.
*/
public static ComponentUI createUI(JComponent c) {
return new TinyScrollBarUI();
}
/**
* Creates the decrease button of the scrollbar.
*
* @param orientation The button's orientation.
* @return The created button.
*/
protected JButton createDecreaseButton(int orientation) {
return new TinyScrollButton(orientation, this);
}
/**
* Creates the increase button of the scrollbar.
*
* @param orientation The button's orientation.
* @return The created button.
*/
protected JButton createIncreaseButton(int orientation) {
return new TinyScrollButton(orientation, this);
}
/// From MetalUI
public Dimension getPreferredSize(JComponent c) {
if(scrollbar.getOrientation() == JScrollBar.VERTICAL) {
return new Dimension(scrollBarWidth, scrollBarWidth * 3 + 10);
} else // Horizontal
{
return new Dimension(scrollBarWidth * 3 + 10, scrollBarWidth);
}
}
public void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) {
// borders depend on the scrollbar's style
switch(Theme.derivedStyle[Theme.style]) {
case Theme.TINY_STYLE:
drawTinyTrack(g, trackBounds);
break;
case Theme.W99_STYLE:
drawWinTrack(g, trackBounds);
break;
case Theme.YQ_STYLE:
drawXpTrack(g, trackBounds);
break;
}
}
private void drawTinyTrack(Graphics g, Rectangle t) {
if(isThumbVisible()) {
g.setColor(Theme.scrollTrackColor[Theme.style].getColor());
}
else {
g.setColor(Theme.scrollTrackDisabledColor[Theme.style].getColor());
}
g.fillRect(t.x, t.y, t.width, t.height);
g.setColor(Color.BLACK);
if(scrollbar.getOrientation() == JScrollBar.VERTICAL) {
// links
g.drawLine(t.x, t.y, t.x, t.y + t.height - 1);
}
else {
// oben
g.drawLine(t.x, t.y, t.x + t.width - 1, t.y);
}
if(!isThumbVisible()) return;
if(scrollbar.getOrientation() == JScrollBar.VERTICAL) {
g.setColor(ColorRoutines.darken(Theme.scrollTrackColor[Theme.style].getColor(), 30));
g.drawLine(t.x + 1, t.y + 1, t.x + t.width - 3, t.y + 1);
g.drawLine(t.x + 1, t.y + 1, t.x + 1, t.y + t.height - 1);
g.setColor(ColorRoutines.darken(Theme.scrollTrackColor[Theme.style].getColor(), 20));
g.drawLine(t.x + 2, t.y + 2, t.x + t.width - 4, t.y + 2);
g.drawLine(t.x + 2, t.y + 2, t.x + 2, t.y + t.height - 1);
g.setColor(ColorRoutines.lighten(Theme.scrollTrackColor[Theme.style].getColor(), 40));
g.drawLine(t.x + t.width - 2, t.y + 1, t.x + t.width - 2, t.y + t.height - 1);
g.setColor(ColorRoutines.lighten(Theme.scrollTrackColor[Theme.style].getColor(), 20));
g.drawLine(t.x + t.width - 3, t.y + 2, t.x + t.width - 3, t.y + t.height - 1);
}
else {
g.setColor(ColorRoutines.darken(Theme.scrollTrackColor[Theme.style].getColor(), 30));
g.drawLine(t.x + 1, t.y + 1, t.x + t.width - 1, t.y + 1);
g.drawLine(t.x + 1, t.y + 1, t.x + 1, t.y + t.height - 3);
g.setColor(ColorRoutines.darken(Theme.scrollTrackColor[Theme.style].getColor(), 20));
g.drawLine(t.x + 2, t.y + 2, t.x + t.width - 1, t.y + 2);
g.drawLine(t.x + 2, t.y + 2, t.x + 2, t.y + t.height - 4);
g.setColor(ColorRoutines.lighten(Theme.scrollTrackColor[Theme.style].getColor(), 40));
g.drawLine(t.x + 1, t.y + t.height - 2, t.x + t.width - 1, t.y + t.height - 2);
g.setColor(ColorRoutines.lighten(Theme.scrollTrackColor[Theme.style].getColor(), 20));
g.drawLine(t.x + 2, t.y + t.height - 3, t.x + t.width - 1, t.y + t.height - 3);
}
}
private void drawWinTrack(Graphics g, Rectangle trackBounds) {
if(isThumbVisible()) {
g.setColor(Theme.scrollTrackColor[Theme.style].getColor());
}
else {
g.setColor(Theme.scrollTrackDisabledColor[Theme.style].getColor());
}
g.fillRect(trackBounds.x, trackBounds.y, trackBounds.width, trackBounds.height);
// no border
}
private void drawXpTrack(Graphics g, Rectangle t) {
if(isThumbVisible()) {
g.setColor(Theme.scrollTrackColor[Theme.style].getColor());
}
else {
g.setColor(Theme.scrollTrackDisabledColor[Theme.style].getColor());
}
g.fillRect(t.x, t.y, t.width, t.height);
if(isThumbVisible()) {
g.setColor(Theme.scrollTrackBorderColor[Theme.style].getColor());
}
else {
g.setColor(Theme.scrollTrackBorderDisabledColor[Theme.style].getColor());
}
if(scrollbar.getOrientation() == JScrollBar.VERTICAL) {
g.drawLine(t.x, t.y, t.x, t.y + t.height - 1);
g.drawLine(t.x + t.width - 1, t.y, t.x + t.width - 1, t.y + t.height - 1);
}
else {
g.drawLine(t.x, t.y, t.x + t.width - 1, t.y);
g.drawLine(t.x, t.y + t.height - 1, t.x + t.width - 1, t.y + t.height - 1);
}
}
public void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
switch(Theme.derivedStyle[Theme.style]) {
case Theme.TINY_STYLE:
drawTinyThumb(g, thumbBounds);
break;
case Theme.W99_STYLE:
drawWinThumb(g, thumbBounds);
break;
case Theme.YQ_STYLE:
drawXpThumb(g, thumbBounds);
break;
}
}
private void drawTinyThumb(Graphics g, Rectangle t) {
}
private void drawWinThumb(Graphics g, Rectangle t) {
if(isDragging)
g.setColor(Theme.scrollThumbPressedColor[Theme.style].getColor());
else if(isRollover && Theme.scrollRollover[Theme.style])
g.setColor(Theme.scrollThumbRolloverColor[Theme.style].getColor());
else
g.setColor(Theme.scrollThumbColor[Theme.style].getColor());
int x2 = t.x + t.width;
int y2 = t.y + t.height;
g.fillRect(t.x , t.y, t.width - 1, t.height - 1);
g.setColor(Theme.scrollLightColor[Theme.style].getColor());
g.drawLine(t.x + 1, t.y + 1, x2 - 3, t.y + 1);
g.drawLine(t.x + 1, t.y + 1, t.x + 1, y2 - 3);
g.setColor(Theme.scrollDarkColor[Theme.style].getColor());
g.drawLine(x2 - 2, t.y + 1, x2 - 2, y2 - 3);
g.drawLine(t.x + 1, y2 - 2, x2 - 2, y2 - 2);
g.setColor(Theme.scrollBorderColor[Theme.style].getColor());
g.drawLine(x2 - 1, t.y, x2 - 1, y2 - 2);
g.drawLine(t.x, y2 - 1, x2 - 1, y2 - 1);
}
private void drawXpThumb(Graphics g, Rectangle t) {
Color c = null;
if(isDragging && isRollover) {
c = Theme.scrollThumbPressedColor[Theme.style].getColor();
}
else if(isRollover && Theme.scrollRollover[Theme.style]) {
c = Theme.scrollThumbRolloverColor[Theme.style].getColor();
}
else {
c = Theme.scrollThumbColor[Theme.style].getColor();
}
g.setColor(c);
int x2 = t.x + t.width - 1;
int y2 = t.y + t.height - 1;
int spread1 = Theme.scrollSpreadLight[Theme.style];
int spread2 = Theme.scrollSpreadDark[Theme.style];
int h = 15;
float spreadStep1 = 10.0f * spread1 / 10;
float spreadStep2 = 10.0f * spread2 / 10;
int halfY = h / 2;
int yd;
switch (scrollbar.getOrientation()) {
case JScrollBar.VERTICAL:
for(int y = 1; y < h; y++) {
if(y < halfY) {
yd = halfY - y;
g.setColor(ColorRoutines.lighten(c, (int)(yd * spreadStep1)));
}
else if(y == halfY) {
g.setColor(c);
}
else {
yd = y - halfY;
g.setColor(ColorRoutines.darken(c, (int)(yd * spreadStep2)));
}
g.drawLine(t.x + y, t.y + 2, t.x + y, y2 - 1);
}
g.setColor(Theme.scrollLightColor[Theme.style].getColor());
g.drawLine(t.x + 3, t.y + 1, t.x + 14, t.y + 1);
g.drawLine(t.x + 15, t.y + 2, t.x + 15, y2 - 2);
g.setColor(Theme.scrollBorderColor[Theme.style].getColor());
g.drawRect(t.x + 1, t.y, 15, y2 - t.y);
// edges - blend borderColor with lightColor
Color a = Theme.scrollBorderColor[Theme.style].getColor();
g.setColor(new Color(a.getRed(), a.getGreen(), a.getBlue(), alpha));
g.drawLine(t.x + 2, t.y + 1, t.x + 2, t.y + 1);
g.drawLine(t.x + 15, t.y + 1, t.x + 15, t.y + 1);
g.drawLine(t.x + 2, y2 - 1, t.x + 2, y2 - 1);
g.drawLine(t.x + 15, y2 - 1, t.x + 15, y2 - 1);
// blend lightColor with borderColor
a = Theme.scrollLightColor[Theme.style].getColor();
g.setColor(new Color(a.getRed(), a.getGreen(), a.getBlue(), alpha));
g.drawLine(t.x + 1, t.y, t.x + 1, t.y);
g.drawLine(t.x + 16, t.y, t.x + 16, t.y);
g.drawLine(t.x + 1, y2, t.x + 1, y2);
g.drawLine(t.x + 16, y2, t.x + 16, y2);
break;
case JScrollBar.HORIZONTAL:
for(int y = 1; y < h; y++) {
if(y < halfY) {
yd = halfY - y;
g.setColor(ColorRoutines.lighten(c, (int)(yd * spreadStep1)));
}
else if(y == halfY) {
g.setColor(c);
}
else {
yd = y - halfY;
g.setColor(ColorRoutines.darken(c, (int)(yd * spreadStep2)));
}
g.drawLine(t.x + 1, t.y + y, x2 - 2, t.y + y);
}
g.setColor(Theme.scrollLightColor[Theme.style].getColor());
g.drawLine(t.x + 2, t.y + 15, x2 - 2, t.y + 15);
g.drawLine(x2 - 1, t.y + 3, x2 - 1, t.y + 14);
g.setColor(Theme.scrollBorderColor[Theme.style].getColor());
g.drawRect(t.x, t.y + 1, x2 - t.x, 15);
g.setColor(Theme.scrollTrackBorderColor[Theme.style].getColor());
g.drawLine(t.x, t.y, x2, t.y);
// edges - blend borderColor with lightColor
a = Theme.scrollBorderColor[Theme.style].getColor();
g.setColor(new Color(a.getRed(), a.getGreen(), a.getBlue(), alpha));
g.drawLine(t.x + 1, t.y + 2, t.x + 1, t.y + 2);
g.drawLine(t.x + 1, t.y + 15, t.x + 1, t.y + 15);
g.drawLine(x2 - 1, t.y + 2, x2 - 1, t.y + 2);
g.drawLine(x2 - 1, t.y + 15, x2 - 1, t.y + 15);
// blend lightColor with borderColor
a = Theme.scrollLightColor[Theme.style].getColor();
g.setColor(new Color(a.getRed(), a.getGreen(), a.getBlue(), alpha));
g.drawLine(t.x, t.y + 1, t.x, t.y + 1);
g.drawLine(t.x, t.y + 16, t.x, t.y + 16);
g.drawLine(x2, t.y + 1, x2, t.y + 1);
g.drawLine(x2, t.y + 16, x2, t.y + 16);
break;
}
// draw Grip
if(t.height < 11) return;
if(scrollbar.getOrientation() == JScrollBar.VERTICAL) {
int y1 = t.y + (t.height) / 2 - 4;
y2 = Math.min(y1 + 8, t.y + t.height - 5);
int y = y1;
// we take only saturation & brightness and apply them
// to the background color (normal/rollover/pressed)
g.setColor(SBChooser.getAdjustedColor(c,
Theme.scrollGripLightColor[Theme.style].getSaturation(),
Theme.scrollGripLightColor[Theme.style].getBrightness()));
while(y < y2) {
g.drawLine(5, y, 11, y);
y += 2;
}
y = y1 + 1;
g.setColor(SBChooser.getAdjustedColor(c,
Theme.scrollGripDarkColor[Theme.style].getSaturation(),
Theme.scrollGripDarkColor[Theme.style].getBrightness()));
while(y < y2) {
g.drawLine(6, y, 12, y);
y += 2;
}
}
else {
int x1 = t.x + (t.width) / 2 - 4;
x2 = Math.min(x1 + 8, t.x + t.width - 5);
int x = x1 + 1;
// we take only saturation & brightness and apply them
// to the background color (normal/rollover/pressed)
g.setColor(SBChooser.getAdjustedColor(c,
Theme.scrollGripLightColor[Theme.style].getSaturation(),
Theme.scrollGripLightColor[Theme.style].getBrightness()));
while(x < x2) {
g.drawLine(x, 5, x, 11);
x += 2;
}
x = x1;
g.setColor(SBChooser.getAdjustedColor(c,
Theme.scrollGripDarkColor[Theme.style].getSaturation(),
Theme.scrollGripDarkColor[Theme.style].getBrightness()));
while(x < x2) {
g.drawLine(x, 6, x, 12);
x += 2;
}
}
}
public boolean isThumbVisible() {
if(scrollbar.getOrientation() == JScrollBar.VERTICAL) {
return getThumbBounds().height > 0;
} else {
return getThumbBounds().width > 0;
}
}
// From BasicUI
protected TrackListener createTrackListener(){
return new MyTrackListener();
}
/**
* Basically does BasicScrollBarUI.TrackListener the right job, it just needs
* an additional repaint and rollover management
*/
protected class MyTrackListener extends BasicScrollBarUI.TrackListener {
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
scrollbar.repaint();
}
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
scrollbar.repaint();
}
public void mouseEntered(MouseEvent e) {
isRollover=false;
wasRollover=false;
if(getThumbBounds().contains(e.getPoint())) {
isRollover = true;
wasRollover = isRollover;
scrollbar.repaint();
}
}
public void mouseExited(MouseEvent e) {
isRollover=false;
if (isRollover != wasRollover) {
wasRollover = isRollover;
scrollbar.repaint();
}
}
public void mouseDragged(MouseEvent e) {
if(getThumbBounds().contains(e.getPoint())) {
isDragging=true;
}
super.mouseDragged(e);
}
public void mouseMoved(MouseEvent e) {
if(getThumbBounds().contains(e.getPoint())) {
isRollover=true;
if (isRollover != wasRollover) {
scrollbar.repaint();
wasRollover = isRollover;
}
} else {
isRollover=false;
if (isRollover != wasRollover) {
scrollbar.repaint();
wasRollover = isRollover;
}
}
}
}
protected class OrientationChangeListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
Integer orient = (Integer)e.getNewValue();
if (scrollbar.getComponentOrientation().isLeftToRight()) {
if (incrButton instanceof TinyScrollButton) {
((TinyScrollButton)incrButton).setDirection(orient.intValue() == HORIZONTAL?
EAST : SOUTH);
}
if (decrButton instanceof TinyScrollButton) {
((TinyScrollButton)decrButton).setDirection(orient.intValue() == HORIZONTAL?
WEST : NORTH);
}
} else {
if (incrButton instanceof TinyScrollButton) {
((TinyScrollButton)incrButton).setDirection(orient.intValue() == HORIZONTAL?
WEST : SOUTH);
}
if (decrButton instanceof TinyScrollButton) {
((TinyScrollButton)decrButton).setDirection(orient.intValue() == HORIZONTAL?
EAST : NORTH);
}
}
}
}
}