/******************************************************************************* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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; } } }