/*******************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.metal.MetalButtonUI;
import de.muntjak.tinylookandfeel.controlpanel.ColorRoutines;
/**
* TinyButtonUI. The UI delegate for JButton, JToggleButton and ArrowButtons for
* JSpinner.
*
* @version 1.3.04
* @author Hans Bickel
*/
@SuppressWarnings (
{ "all" } )
public class TinyButtonUI extends MetalButtonUI
{
// if a button has not the defined background, it will
// be darkened resp. lightened by BG_CHANGE amount if
// pressed or rollover
public static final int BG_CHANGE_AMOUNT = 10;
/**
* The Cached UI delegate.
*/
private static final TinyButtonUI buttonUI = new TinyButtonUI ();
/* the only instance of the stroke for the focus */
private static final BasicStroke focusStroke = new BasicStroke ( 1.0f,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 1.0f, new float []
{ 1.0f, 1.0f }, 0.0f );
private boolean graphicsTranslated;
private boolean isToolBarButton, isFileChooserButton;
private boolean isDefault;
public TinyButtonUI ()
{
}
public void installUI ( JComponent c )
{
super.installUI ( c );
if ( !Theme.buttonEnter [ Theme.style ] )
return;
if ( !c.isFocusable () )
return;
InputMap km = ( InputMap ) UIManager.get ( getPropertyPrefix ()
+ "focusInputMap" );
if ( km != null )
{
// replace SPACE with ENTER (but SPACE will still work, don't know why)
km.put ( KeyStroke.getKeyStroke ( KeyEvent.VK_ENTER, 0, false ),
"pressed" );
km.put ( KeyStroke.getKeyStroke ( KeyEvent.VK_ENTER, 0, true ),
"released" );
}
}
public void installDefaults ( AbstractButton button )
{
super.installDefaults ( button );
button.setRolloverEnabled ( true );
}
protected void paintFocus ( Graphics g, AbstractButton b, Rectangle viewRect,
Rectangle textRect, Rectangle iconRect )
{
if ( isFileChooserButton
|| ( isToolBarButton && !Theme.toolFocus [ Theme.style ] )
|| !Theme.buttonFocus [ Theme.style ] )
{
return;
}
Graphics2D g2d = ( Graphics2D ) g;
Rectangle focusRect = b.getBounds ();
g.setColor ( Color.black );
g2d.setStroke ( focusStroke );
int x1 = 2;
int y1 = 2;
int x2 = x1 + focusRect.width - 5;
int y2 = y1 + focusRect.height - 5;
if ( !isToolBarButton )
{
x1++ ;
y1++ ;
x2-- ;
y2-- ;
}
if ( graphicsTranslated )
{
g.translate ( -1, -1 );
}
g2d.drawLine ( x1, y1, x2, y1 );
g2d.drawLine ( x1, y1, x1, y2 );
g2d.drawLine ( x1, y2, x2, y2 );
g2d.drawLine ( x2, y1, x2, y2 );
}
/**
* 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 ( final JComponent c )
{
return buttonUI;
}
protected void paintButtonPressed ( Graphics g, AbstractButton button )
{
if ( isToolBarButton || isFileChooserButton )
return;
Color col = null;
if ( !button.getBackground ().equals (
Theme.buttonNormalColor [ Theme.style ].getColor () ) )
{
col = ColorRoutines.darken ( button.getBackground (), BG_CHANGE_AMOUNT );
}
else
{
col = Theme.buttonPressedColor [ Theme.style ].getColor ();
}
g.setColor ( col );
switch ( Theme.derivedStyle [ Theme.style ] )
{
case Theme.TINY_STYLE :
drawTinyButton ( g, button, col );
break;
case Theme.W99_STYLE :
drawWinButton ( g, button, col );
break;
case Theme.YQ_STYLE :
drawXpButton ( g, button, col, false );
break;
}
if ( ! ( button instanceof JToggleButton ) )
{
// Changed in 1.3.04: If button is icon-only
// then don't shift
if ( Theme.shiftButtonText [ Theme.style ] && button.getText () != null
&& !"".equals ( button.getText () ) )
{
g.translate ( 1, 1 );
graphicsTranslated = true;
}
}
}
public void paintToolBarButton ( Graphics g, AbstractButton b )
{
Color col = null;
// New in 1.3.7
boolean isRollover = b.getModel ().isRollover ()
|| b.getModel ().isArmed ();
Color toolButtColor = null;
if ( isFileChooserButton )
{
toolButtColor = b.getParent ().getBackground ();
}
else
{
toolButtColor = Theme.toolButtColor [ Theme.style ].getColor ();
}
if ( b.getModel ().isPressed () )
{
if ( isRollover )
{
col = Theme.toolButtPressedColor [ Theme.style ].getColor ();
}
else
{
if ( b.isSelected () )
{
col = Theme.toolButtSelectedColor [ Theme.style ].getColor ();
}
else
{
col = toolButtColor;
}
}
}
else if ( isRollover
&& Theme.derivedStyle [ Theme.style ] == Theme.YQ_STYLE )
{
if ( b.isSelected () )
{
col = Theme.toolButtSelectedColor [ Theme.style ].getColor ();
}
else
{
col = Theme.toolButtRolloverColor [ Theme.style ].getColor ();
}
}
else if ( b.isSelected () )
{
col = Theme.toolButtSelectedColor [ Theme.style ].getColor ();
}
else
{
col = toolButtColor;
}
g.setColor ( col );
switch ( Theme.derivedStyle [ Theme.style ] )
{
case Theme.TINY_STYLE :
drawTinyToolBarButton ( g, b, col, false );
break;
case Theme.W99_STYLE :
drawWinToolBarButton ( g, b, col, false );
break;
case Theme.YQ_STYLE :
drawXpToolBarButton ( g, b, col, false );
break;
}
}
public void paint ( Graphics g, JComponent c )
{
AbstractButton button = ( AbstractButton ) c;
if ( isToolBarButton || isFileChooserButton )
{
paintToolBarButton ( g, button );
// the base class may paint text and/or icons
super.paint ( g, c );
return;
}
if ( ( button instanceof JToggleButton ) && button.isSelected () )
{
paintButtonPressed ( g, button );
// the base class may paint text and/or icons
super.paint ( g, c );
return;
}
isDefault = ( c instanceof JButton )
&& ( ( ( JButton ) c ).isDefaultButton () );
boolean isRollover = button.getModel ().isRollover ()
&& Theme.buttonRollover [ Theme.derivedStyle [ Theme.style ] ];
boolean isDefinedBackground = c.getBackground ().equals (
Theme.buttonNormalColor [ Theme.style ].getColor () );
Color col = null;
if ( !button.isEnabled () )
{
col = Theme.buttonDisabledColor [ Theme.style ].getColor ();
}
else if ( button.getModel ().isPressed () )
{
if ( isRollover )
{
if ( isDefinedBackground )
{
col = Theme.buttonPressedColor [ Theme.style ].getColor ();
}
else
{
col = ColorRoutines.darken ( c.getBackground (), BG_CHANGE_AMOUNT );
}
}
else
{
// button pressed but mouse exited
col = c.getBackground ();
}
}
else if ( isRollover )
{
if ( isDefinedBackground )
{
col = Theme.buttonRolloverBgColor [ Theme.style ].getColor ();
}
else
{
col = ColorRoutines.lighten ( c.getBackground (), BG_CHANGE_AMOUNT );
}
}
else
{
col = c.getBackground ();
}
g.setColor ( col );
switch ( Theme.derivedStyle [ Theme.style ] )
{
case Theme.TINY_STYLE :
drawTinyButton ( g, button, col );
break;
case Theme.W99_STYLE :
drawWinButton ( g, button, col );
break;
case Theme.YQ_STYLE :
drawXpButton ( g, button, col, isRollover );
break;
}
// the base class may paint text and/or icons
super.paint ( g, c );
}
// this overrides BasicButtonUI.paintIcon(...)
protected void paintIcon ( Graphics g, JComponent c, Rectangle iconRect )
{
if ( c instanceof JToggleButton )
{
paintToggleButtonIcon ( g, c, iconRect );
}
else
{
super.paintIcon ( g, c, iconRect );
}
}
protected void paintToggleButtonIcon ( Graphics g, JComponent c,
Rectangle iconRect )
{
AbstractButton b = ( AbstractButton ) c;
ButtonModel model = b.getModel ();
Icon icon = null;
if ( !model.isEnabled () )
{
if ( model.isSelected () )
{
icon = ( Icon ) b.getDisabledSelectedIcon ();
}
else
{
icon = ( Icon ) b.getDisabledIcon ();
}
}
else if ( model.isPressed () && model.isArmed () )
{
icon = ( Icon ) b.getPressedIcon ();
if ( icon == null )
{
// Use selected icon
icon = ( Icon ) b.getSelectedIcon ();
}
}
else if ( model.isSelected () )
{
if ( b.isRolloverEnabled () && model.isRollover () )
{
icon = ( Icon ) b.getRolloverSelectedIcon ();
if ( icon == null )
{
icon = ( Icon ) b.getSelectedIcon ();
}
}
else
{
icon = ( Icon ) b.getSelectedIcon ();
}
}
else if ( model.isRollover ()
&& Theme.derivedStyle [ Theme.style ] == Theme.YQ_STYLE )
{
icon = ( Icon ) b.getRolloverIcon ();
}
if ( icon == null )
{
icon = ( Icon ) b.getIcon ();
}
icon.paintIcon ( b, g, iconRect.x, iconRect.y );
}
public void update ( Graphics g, JComponent c )
{
isToolBarButton = Boolean.TRUE.equals ( c
.getClientProperty ( TinyToolBarUI.IS_TOOL_BAR_BUTTON_KEY ) );
isFileChooserButton = Boolean.TRUE.equals ( c
.getClientProperty ( TinyFileChooserUI.IS_FILE_CHOOSER_BUTTON_KEY ) );
paint ( g, c );
graphicsTranslated = false;
}
private void drawTinyButton ( Graphics g, AbstractButton b, Color c )
{
}
private void drawWinButton ( Graphics g, AbstractButton b, Color c )
{
int w = b.getWidth ();
int h = b.getHeight ();
if ( b.isContentAreaFilled () && b.isOpaque () )
{
g.fillRect ( 1, 1, w - 2, h - 2 );
}
}
private void drawXpButton ( Graphics g, AbstractButton b, Color c,
boolean isRollover )
{
if ( !b.isContentAreaFilled () )
return;
if ( !b.isOpaque () )
return;
int w = b.getWidth ();
int h = b.getHeight ();
// paint border background
Color bg = b.getParent ().getBackground ();
g.setColor ( bg );
g.drawRect ( 0, 0, w - 1, h - 1 );
int spread1 = Theme.buttonSpreadLight [ Theme.style ];
int spread2 = Theme.buttonSpreadDark [ Theme.style ];
if ( !b.isEnabled () )
{
spread1 = Theme.buttonSpreadLightDisabled [ Theme.style ];
spread2 = Theme.buttonSpreadDarkDisabled [ Theme.style ];
}
float spreadStep1 = 10.0f * spread1 / ( h - 3 );
float spreadStep2 = 10.0f * spread2 / ( h - 3 );
int halfY = h / 2;
int yd;
for ( int y = 1 ; y < h - 1 ; 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 ( 2, y, w - 3, y );
if ( y == 1 )
{
// left vertical line
g.drawLine ( 1, 1, 1, h - 2 );
if ( isRollover || isDefault )
{
// right vertical line
g.drawLine ( w - 2, 1, w - 2, h - 2 );
}
}
else if ( y == h - 2 && !isRollover && !isDefault )
{
// right vertical line
g.drawLine ( w - 2, 1, w - 2, h - 2 );
}
}
// 1 pixel away from each corner
if ( isRollover )
{
g.setColor ( Theme.buttonRolloverColor [ Theme.style ].getColor () );
g.drawLine ( 1, h - 2, 1, h - 2 );
g.drawLine ( w - 2, h - 2, w - 2, h - 2 );
}
else if ( isDefault )
{
g.setColor ( Theme.buttonDefaultColor [ Theme.style ].getColor () );
g.drawLine ( 1, h - 2, 1, h - 2 );
g.drawLine ( w - 2, h - 2, w - 2, h - 2 );
}
}
private void drawTinyToolBarButton ( Graphics g, AbstractButton b, Color c,
boolean isPressed )
{
}
private void drawWinToolBarButton ( Graphics g, AbstractButton b, Color c,
boolean isPressed )
{
int w = b.getWidth ();
int h = b.getHeight ();
if ( b.isContentAreaFilled () )
{
g.fillRect ( 1, 1, w - 2, h - 2 );
}
}
private void drawXpToolBarButton ( Graphics g, AbstractButton b, Color c,
boolean isPressed )
{
int w = b.getWidth ();
int h = b.getHeight ();
if ( b.isContentAreaFilled () )
{
g.fillRect ( 1, 1, w - 2, h - 2 );
}
// paint border background
Color bg = b.getParent ().getBackground ();
g.setColor ( bg );
g.drawRect ( 0, 0, w - 1, h - 1 );
}
}