/*******************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import javax.swing.JComponent;
import javax.swing.JProgressBar;
import javax.swing.LookAndFeel;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicProgressBarUI;
import de.muntjak.tinylookandfeel.controlpanel.ColorRoutines;
/**
* TinyProgressBarUI
*
* @version 1.1
* @author Hans Bickel
*/
@SuppressWarnings (
{ "all" } )
public class TinyProgressBarUI extends BasicProgressBarUI
{
static HashMap cache = new HashMap ();
/* "Override" the dimensions from BasicProgressBarUI */
private static final Dimension PREFERRED_YQ_HORIZONTAL = new Dimension ( 146,
7 );
private static final Dimension PREFERRED_YQ_VERTICAL = new Dimension ( 7, 146 );
private static final Dimension PREFERRED_99_HORIZONTAL = new Dimension ( 146,
6 );
private static final Dimension PREFERRED_99_VERTICAL = new Dimension ( 6, 146 );
protected Dimension getPreferredInnerHorizontal ()
{
if ( Theme.derivedStyle [ Theme.style ] == Theme.YQ_STYLE )
{
return PREFERRED_YQ_HORIZONTAL;
}
return PREFERRED_99_HORIZONTAL;
}
protected Dimension getPreferredInnerVertical ()
{
if ( Theme.derivedStyle [ Theme.style ] == Theme.YQ_STYLE )
{
return PREFERRED_YQ_VERTICAL;
}
return PREFERRED_99_VERTICAL;
}
/**
* 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 TinyProgressBarUI ();
}
protected void paintDeterminate ( Graphics g, JComponent c )
{
Insets b = progressBar.getInsets (); // area for border
int barRectWidth = progressBar.getWidth () - ( b.right + b.left );
int barRectHeight = progressBar.getHeight () - ( b.top + b.bottom );
if ( progressBar.getOrientation () == JProgressBar.HORIZONTAL )
{
int amountFull = getAmountFull ( b, barRectWidth, barRectHeight );
switch ( Theme.derivedStyle [ Theme.style ] )
{
case Theme.TINY_STYLE :
drawTinyHorzProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
amountFull );
break;
case Theme.W99_STYLE :
drawWinHorzProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
amountFull );
break;
case Theme.YQ_STYLE :
drawXpHorzProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
amountFull );
break;
}
// Deal with possible text painting
if ( progressBar.isStringPainted () )
{
g.setFont ( c.getFont () );
paintString ( g, b.left, b.top, barRectWidth, barRectHeight,
amountFull, b );
}
}
else
{ // VERTICAL
int amountFull = getAmountFull ( b, barRectWidth, barRectHeight );
switch ( Theme.derivedStyle [ Theme.style ] )
{
case Theme.TINY_STYLE :
drawTinyVertProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
amountFull );
break;
case Theme.W99_STYLE :
drawWinVertProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
amountFull );
break;
case Theme.YQ_STYLE :
drawXpVertProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
amountFull );
break;
}
// Deal with possible text painting
if ( progressBar.isStringPainted () )
{
g.setFont ( c.getFont () );
paintString ( g, b.left, b.top, barRectWidth, barRectHeight,
amountFull, b );
}
}
}
private void drawTinyHorzProgress ( Graphics g, int x, int y,
int barRectWidth, int barRectHeight, int amountFull )
{
}
private void drawWinHorzProgress ( Graphics g, int x, int y, int w, int h,
int amountFull )
{
// paint the track
g.translate ( x, y );
g.setColor ( Theme.progressTrackColor [ Theme.style ].getColor () );
g.fillRect ( 1, 1, w - 1, h - 1 );
g.setColor ( Theme.progressColor [ Theme.style ].getColor () );
int mx = 0;
while ( mx < amountFull )
{
if ( mx + 6 > w )
{
// paint partially
g.fillRect ( mx, 0, w - mx, h );
}
else
{
g.fillRect ( mx, 0, 6, h );
}
mx += 8;
}
g.translate ( -x, -y );
}
// draw determinate
private void drawXpHorzProgress ( Graphics g, int x, int y, int w, int h,
int amountFull )
{
g.translate ( x, y );
// paint the track
if ( !progressBar.isOpaque () )
{
g.setColor ( progressBar.getBackground () );
g.fillRect ( 0, 0, w, h );
}
ProgressKey key = new ProgressKey ( progressBar.getForeground (), true, h );
Object value = cache.get ( key );
if ( value == null )
{
// create new image
Image img = new BufferedImage ( 6, h, BufferedImage.TYPE_INT_ARGB );
Graphics imgGraphics = img.getGraphics ();
// draw into image graphics
Color c = progressBar.getForeground ();
Color c2 = ColorRoutines.lighten ( c, 15 );
Color c3 = ColorRoutines.lighten ( c, 35 );
Color c4 = ColorRoutines.lighten ( c, 60 );
imgGraphics.setColor ( c4 );
imgGraphics.drawLine ( 0, 0, 5, 0 );
imgGraphics.drawLine ( 0, h - 1, 5, h - 1 );
imgGraphics.setColor ( c3 );
imgGraphics.drawLine ( 0, 1, 5, 1 );
imgGraphics.drawLine ( 0, h - 2, 5, h - 2 );
imgGraphics.setColor ( c2 );
imgGraphics.drawLine ( 0, 2, 5, 2 );
imgGraphics.drawLine ( 0, h - 3, 5, h - 3 );
imgGraphics.setColor ( c );
imgGraphics.fillRect ( 0, 3, 6, h - 6 );
// dispose of image graphics
imgGraphics.dispose ();
cache.put ( key, img );
value = img;
}
int mx = 0;
while ( mx < amountFull )
{
if ( mx + 6 > w )
{
// paint partially
g.drawImage ( ( Image ) value, mx, 0, w - mx, h, progressBar );
}
else
{
g.drawImage ( ( Image ) value, mx, 0, progressBar );
}
mx += 8;
}
g.translate ( -x, -y );
}
private void drawTinyVertProgress ( Graphics g, int x, int y,
int barRectWidth, int barRectHeight, int amountFull )
{
}
private void drawWinVertProgress ( Graphics g, int x, int y, int w, int h,
int amountFull )
{
// paint the track
g.translate ( x, y );
g.setColor ( Theme.progressTrackColor [ Theme.style ].getColor () );
g.fillRect ( 1, 1, w - 1, h - 1 );
g.setColor ( Theme.progressColor [ Theme.style ].getColor () );
int my = 0;
while ( my < amountFull )
{
if ( my + 6 > h )
{
// paint partially
g.fillRect ( 0, 0, w, h - my );
}
else
{
g.fillRect ( 0, h - my - 6, w, 6 );
}
my += 8;
}
g.translate ( -x, -y );
}
// draw determinate
private void drawXpVertProgress ( Graphics g, int x, int y, int w, int h,
int amountFull )
{
g.translate ( x, y );
// paint the track
if ( !progressBar.isOpaque () )
{
g.setColor ( progressBar.getBackground () );
g.fillRect ( 0, 0, w, h );
}
ProgressKey key = new ProgressKey ( progressBar.getForeground (), false, w );
Object value = cache.get ( key );
if ( value == null )
{
// create new image
Image img = new BufferedImage ( w, 6, BufferedImage.TYPE_INT_ARGB );
Graphics imgGraphics = img.getGraphics ();
// draw into image graphics
Color c = progressBar.getForeground ();
Color c2 = ColorRoutines.lighten ( c, 15 );
Color c3 = ColorRoutines.lighten ( c, 35 );
Color c4 = ColorRoutines.lighten ( c, 60 );
imgGraphics.setColor ( c4 );
imgGraphics.drawLine ( 0, 0, 0, 5 );
imgGraphics.drawLine ( w - 1, 0, w - 1, 5 );
imgGraphics.setColor ( c3 );
imgGraphics.drawLine ( 1, 0, 1, 5 );
imgGraphics.drawLine ( w - 2, 0, w - 2, 5 );
imgGraphics.setColor ( c2 );
imgGraphics.drawLine ( 2, 0, 2, 5 );
imgGraphics.drawLine ( w - 3, 0, w - 3, 5 );
imgGraphics.setColor ( c );
imgGraphics.fillRect ( 3, 0, w - 6, 6 );
// dispose of image graphics
imgGraphics.dispose ();
cache.put ( key, img );
value = img;
}
// paints bottom to top...
int my = 0;
while ( my < amountFull )
{
if ( my + 6 > h )
{
// paint partially
g.drawImage ( ( Image ) value, 0, 0, w, h - my, progressBar );
}
else
{
g.drawImage ( ( Image ) value, 0, h - my - 6, progressBar );
}
my += 8;
}
g.translate ( -x, -y );
}
protected void paintIndeterminate ( Graphics g, JComponent c )
{
Insets b = progressBar.getInsets (); // area for border
int barRectWidth = progressBar.getWidth () - ( b.right + b.left );
int barRectHeight = progressBar.getHeight () - ( b.top + b.bottom );
Rectangle boxRect = new Rectangle ();
try
{
boxRect = getBox ( boxRect );
}
catch ( NullPointerException ignore )
{
}
if ( progressBar.getOrientation () == JProgressBar.HORIZONTAL )
{
switch ( Theme.derivedStyle [ Theme.style ] )
{
case Theme.TINY_STYLE :
drawTinyHorzProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
boxRect );
break;
case Theme.W99_STYLE :
drawWinHorzProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
boxRect );
break;
case Theme.YQ_STYLE :
drawXpHorzProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
boxRect );
break;
}
}
else
{
switch ( Theme.derivedStyle [ Theme.style ] )
{
case Theme.TINY_STYLE :
drawTinyVertProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
boxRect );
break;
case Theme.W99_STYLE :
drawWinVertProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
boxRect );
break;
case Theme.YQ_STYLE :
drawXpVertProgress ( g, b.left, b.top, barRectWidth, barRectHeight,
boxRect );
break;
}
}
// Deal with possible text painting
if ( progressBar.isStringPainted () )
{
if ( progressBar.getOrientation () == JProgressBar.HORIZONTAL )
{
paintString ( g, b.left, b.top, barRectWidth, barRectHeight, boxRect.x,
boxRect.width, b );
}
else
{
paintString ( g, b.left, b.top, barRectWidth, barRectHeight, boxRect.y,
boxRect.height, b );
}
}
}
private void paintString ( Graphics g, int x, int y, int width, int height,
int fillStart, int amountFull, Insets b )
{
if ( ! ( g instanceof Graphics2D ) )
{
return;
}
Graphics2D g2 = ( Graphics2D ) g;
String progressString = progressBar.getString ();
g2.setFont ( progressBar.getFont () );
Point renderLocation = getStringPlacement ( g2, progressString, x, y,
width, height );
Rectangle oldClip = g2.getClipBounds ();
if ( progressBar.getOrientation () == JProgressBar.HORIZONTAL )
{
g2.setColor ( getSelectionBackground () );
g2.drawString ( progressString, renderLocation.x, renderLocation.y );
g2.setColor ( getSelectionForeground () );
g2.clipRect ( fillStart, y, amountFull, height );
g.drawString ( progressString, renderLocation.x, renderLocation.y );
}
else
{ // VERTICAL
g2.setColor ( getSelectionBackground () );
AffineTransform rotate = AffineTransform.getRotateInstance ( Math.PI / 2 );
g2.setFont ( progressBar.getFont ().deriveFont ( rotate ) );
renderLocation = getStringPlacement ( g2, progressString, x, y, width,
height );
g2.drawString ( progressString, renderLocation.x, renderLocation.y );
g2.setColor ( getSelectionForeground () );
g2.clipRect ( x, fillStart, width, amountFull );
g2.drawString ( progressString, renderLocation.x, renderLocation.y );
}
g2.setClip ( oldClip );
}
/*
* Inserted this to fix a bug that came with 1.4.2_02 and caused NPE at
* javax.swing.plaf.basic.BasicProgressBarUI.updateSizes(BasicProgressBarUI.java:439).
*
* @see javax.swing.plaf.basic.BasicProgressBarUI#paintString(java.awt.Graphics,
* int, int, int, int, int, java.awt.Insets)
*/
protected void paintString ( Graphics g, int x, int y, int width, int height,
int amountFull, Insets b )
{
Rectangle boxRect = new Rectangle (); // *
try
{ // * The Fix
boxRect = getBox ( boxRect ); // *
}
catch ( NullPointerException ignore )
{
} // *
if ( progressBar.getOrientation () == JProgressBar.HORIZONTAL )
{
if ( progressBar.getComponentOrientation ().isLeftToRight () )
{
if ( progressBar.isIndeterminate () )
{
paintString ( g, x, y, width, height, boxRect.x, boxRect.width, b );
}
else
{
paintString ( g, x, y, width, height, x, amountFull, b );
}
}
else
{
paintString ( g, x, y, width, height, x + width - amountFull,
amountFull, b );
}
}
else
{
if ( progressBar.isIndeterminate () )
{
paintString ( g, x, y, width, height, boxRect.y, boxRect.height, b );
}
else
{
paintString ( g, x, y, width, height, y + height - amountFull,
amountFull, b );
}
}
}
private void drawTinyHorzProgress ( Graphics g, int x, int y,
int barRectWidth, int barRectHeight, Rectangle boxRect )
{
}
private void drawWinHorzProgress ( Graphics g, int x, int y, int w, int h,
Rectangle boxRect )
{
// paint the track
g.setColor ( Theme.progressTrackColor [ Theme.style ].getColor () );
g.fillRect ( x + 1, y + 1, w - 1, h - 1 );
g.translate ( boxRect.x, boxRect.y );
g.setColor ( Theme.progressColor [ Theme.style ].getColor () );
int mx = 0;
while ( mx + 6 < boxRect.width )
{
g.fillRect ( mx, 0, 6, h );
mx += 8;
}
g.translate ( -boxRect.x, -boxRect.y );
}
// draw indeterminate
private void drawXpHorzProgress ( Graphics g, int x, int y, int w, int h,
Rectangle boxRect )
{
// paint the track
if ( !progressBar.isOpaque () )
{
g.setColor ( progressBar.getBackground () );
g.fillRect ( x, y, w, h );
}
g.translate ( boxRect.x, boxRect.y );
ProgressKey key = new ProgressKey ( progressBar.getForeground (), true, h );
Object value = cache.get ( key );
if ( value == null )
{
// create new image
Image img = new BufferedImage ( 6, h, BufferedImage.TYPE_INT_ARGB );
Graphics imgGraphics = img.getGraphics ();
// draw into image graphics
Color c = progressBar.getForeground ();
Color c2 = ColorRoutines.lighten ( c, 15 );
Color c3 = ColorRoutines.lighten ( c, 35 );
Color c4 = ColorRoutines.lighten ( c, 60 );
imgGraphics.setColor ( c4 );
imgGraphics.drawLine ( 0, 0, 5, 0 );
imgGraphics.drawLine ( 0, h - 1, 5, h - 1 );
imgGraphics.setColor ( c3 );
imgGraphics.drawLine ( 0, 1, 5, 1 );
imgGraphics.drawLine ( 0, h - 2, 5, h - 2 );
imgGraphics.setColor ( c2 );
imgGraphics.drawLine ( 0, 2, 5, 2 );
imgGraphics.drawLine ( 0, h - 3, 5, h - 3 );
imgGraphics.setColor ( c );
imgGraphics.fillRect ( 0, 3, 6, h - 6 );
// dispose of image graphics
imgGraphics.dispose ();
cache.put ( key, img );
value = img;
}
int mx = 0;
while ( mx + 6 < boxRect.width )
{
g.drawImage ( ( Image ) value, mx, 0, progressBar );
mx += 8;
}
g.translate ( -boxRect.x, -boxRect.y );
}
private void drawTinyVertProgress ( Graphics g, int x, int y, int w, int h,
Rectangle boxRect )
{
}
private void drawWinVertProgress ( Graphics g, int x, int y, int w, int h,
Rectangle boxRect )
{
// paint the track
g.setColor ( Theme.progressTrackColor [ Theme.style ].getColor () );
g.fillRect ( x + 1, y + 1, w - 1, h - 1 );
g.translate ( boxRect.x, boxRect.y );
g.setColor ( Theme.progressColor [ Theme.style ].getColor () );
int my = 0;
while ( my + 6 < boxRect.height )
{
g.fillRect ( 0, my, w, 6 );
my += 8;
}
g.translate ( -boxRect.x, -boxRect.y );
}
// draw indeterminate
private void drawXpVertProgress ( Graphics g, int x, int y, int w, int h,
Rectangle boxRect )
{
// paint the track
if ( !progressBar.isOpaque () )
{
g.setColor ( progressBar.getBackground () );
g.fillRect ( x, y, w, h );
}
g.translate ( boxRect.x, boxRect.y );
ProgressKey key = new ProgressKey ( progressBar.getForeground (), false, w );
Object value = cache.get ( key );
if ( value == null )
{
// create new image
Image img = new BufferedImage ( w, 6, BufferedImage.TYPE_INT_ARGB );
Graphics imgGraphics = img.getGraphics ();
// draw into image graphics
Color c = progressBar.getForeground ();
Color c2 = ColorRoutines.lighten ( c, 15 );
Color c3 = ColorRoutines.lighten ( c, 35 );
Color c4 = ColorRoutines.lighten ( c, 60 );
imgGraphics.setColor ( c4 );
imgGraphics.drawLine ( 0, 0, 0, 5 );
imgGraphics.drawLine ( w - 1, 0, w - 1, 5 );
imgGraphics.setColor ( c3 );
imgGraphics.drawLine ( 1, 0, 1, 5 );
imgGraphics.drawLine ( w - 2, 0, w - 2, 5 );
imgGraphics.setColor ( c2 );
imgGraphics.drawLine ( 2, 0, 2, 5 );
imgGraphics.drawLine ( w - 3, 0, w - 3, 5 );
imgGraphics.setColor ( c );
imgGraphics.fillRect ( 3, 0, w - 6, 6 );
// dispose of image graphics
imgGraphics.dispose ();
cache.put ( key, img );
value = img;
}
int my = 0;
while ( my + 6 < boxRect.height )
{
g.drawImage ( ( Image ) value, 0, my, progressBar );
my += 8;
}
g.translate ( -boxRect.x, -boxRect.y );
}
protected Color getSelectionForeground ()
{
return Theme.progressSelectForeColor [ Theme.style ].getColor ();
}
protected Color getSelectionBackground ()
{
return Theme.progressSelectBackColor [ Theme.style ].getColor ();
}
protected void installDefaults ()
{
// Note: Omitting the following line was a bug from v1.3.01 until v1.3.04
// Note: The following method turned out to be new in 1.5. Therefore
// replaced with progressBar.setOpaque(true)
// LookAndFeel.installProperty(progressBar, "opaque", Boolean.TRUE);
// removed again in 1.3.7 (because opaque progress bar
// fills bounds with track [background] color)
// progressBar.setOpaque(true);
LookAndFeel.installBorder ( progressBar, "ProgressBar.border" );
LookAndFeel.installColorsAndFont ( progressBar, "ProgressBar.background",
"ProgressBar.foreground", "ProgressBar.font" );
}
/*
* ProgressKey is used as key in the cache HashMap. Overrides equals() and
* hashCode().
*/
static class ProgressKey
{
private Color c;
private boolean horizontal;
private int size;
ProgressKey ( Color c, boolean horizontal, int size )
{
this.c = c;
this.horizontal = horizontal;
this.size = size;
}
public boolean equals ( Object o )
{
if ( o == null )
return false;
if ( ! ( o instanceof ProgressKey ) )
return false;
ProgressKey other = ( ProgressKey ) o;
return size == other.size && horizontal == other.horizontal
&& c.equals ( other.c );
}
public int hashCode ()
{
return c.hashCode () * ( horizontal ? 1 : 2 ) * size;
}
}
}