/*******************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.image.BufferedImage;
import javax.swing.CellRendererPane;
import javax.swing.DefaultButtonModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.UIManager;
import de.muntjak.tinylookandfeel.controlpanel.ColorRoutines;
/**
* TinyComboBoxButton
*
* @version 1.3
* @author Hans Bickel
*/
@SuppressWarnings (
{ "all" } )
public class TinyComboBoxButton extends JButton
{
protected JComboBox comboBox;
protected JList listBox;
protected CellRendererPane rendererPane;
protected Icon comboIcon;
protected boolean iconOnly = false;
private static BufferedImage focusImg;
public final JComboBox getComboBox ()
{
return comboBox;
}
public final void setComboBox ( JComboBox cb )
{
comboBox = cb;
}
public final Icon getComboIcon ()
{
return comboIcon;
}
public final void setComboIcon ( Icon i )
{
comboIcon = i;
}
public final boolean isIconOnly ()
{
return iconOnly;
}
public final void setIconOnly ( boolean isIconOnly )
{
iconOnly = isIconOnly;
}
TinyComboBoxButton ()
{
super ( "" );
DefaultButtonModel model = new DefaultButtonModel ()
{
public void setArmed ( boolean armed )
{
super.setArmed ( isPressed () ? true : armed );
}
};
setModel ( model );
// Set the background and foreground to the combobox colors.
setBackground ( UIManager.getColor ( "ComboBox.background" ) );
setForeground ( UIManager.getColor ( "ComboBox.foreground" ) );
if ( focusImg == null )
{
ImageIcon icon = TinyLookAndFeel.loadIcon ( "ComboBoxFocus.png", this );
if ( icon != null )
{
focusImg = new BufferedImage ( 2, 2, BufferedImage.TYPE_INT_RGB );
Graphics g = focusImg.getGraphics ();
icon.paintIcon ( this, g, 0, 0 );
}
}
}
public TinyComboBoxButton ( JComboBox cb, Icon i, boolean onlyIcon,
CellRendererPane pane, JList list )
{
this ();
comboBox = cb;
comboIcon = i;
rendererPane = pane;
listBox = list;
setEnabled ( comboBox.isEnabled () );
}
/**
* Mostly taken from the swing sources
*
* @see javax.swing.JComponent#paintComponent(Graphics)
*/
public void paintComponent ( Graphics g )
{
// Note: border was already painted in TinyButtonBorder
boolean leftToRight = getComponentOrientation ().isLeftToRight ();
if ( comboBox.isEnabled () )
{
if ( comboBox.isEditable () )
{
g.setColor ( Theme.textBgColor [ Theme.style ].getColor () );
}
else
{
g.setColor ( comboBox.getBackground () );
}
}
else
{
g.setColor ( Theme.textDisabledBgColor [ Theme.style ].getColor () );
}
g.fillRect ( 1, 1, getWidth () - 2, getHeight () - 2 );
// paint border background - next parent is combo box
Color bg = getParent ().getParent ().getBackground ();
g.setColor ( bg );
g.drawRect ( 0, 0, getWidth () - 1, getHeight () - 1 );
Color col = null;
if ( !isEnabled () )
{
col = Theme.comboButtDisabledColor [ Theme.style ].getColor ();
}
else if ( model.isPressed () )
{
col = Theme.comboButtPressedColor [ Theme.style ].getColor ();
}
else if ( model.isRollover () )
{
col = Theme.comboButtRolloverColor [ Theme.style ].getColor ();
}
else
{
col = Theme.comboButtColor [ Theme.style ].getColor ();
}
g.setColor ( col );
Rectangle buttonRect = new Rectangle ( getWidth ()
- Theme.comboButtonWidth [ Theme.derivedStyle [ Theme.style ] ], 1,
Theme.comboButtonWidth [ Theme.derivedStyle [ Theme.style ] ],
getHeight () - 2 );
switch ( Theme.derivedStyle [ Theme.style ] )
{
case Theme.TINY_STYLE :
drawTinyButton ( g, buttonRect );
break;
case Theme.W99_STYLE :
drawWinButton ( g, buttonRect );
break;
case Theme.YQ_STYLE :
drawXpButton ( g, buttonRect, col );
break;
}
// draw arrow
if ( isEnabled () )
{
g.setColor ( Theme.comboArrowColor [ Theme.style ].getColor () );
}
else
{
g.setColor ( Theme.comboArrowDisabledColor [ Theme.style ].getColor () );
}
switch ( Theme.derivedStyle [ Theme.style ] )
{
case Theme.TINY_STYLE :
drawTinyArrow ( g, buttonRect );
break;
case Theme.W99_STYLE :
drawWinArrow ( g, buttonRect );
break;
case Theme.YQ_STYLE :
drawXpArrow ( g, buttonRect );
break;
}
Insets insets = new Insets ( Theme.comboInsets [ Theme.style ].top,
Theme.comboInsets [ Theme.style ].left,
Theme.comboInsets [ Theme.style ].bottom, 0 );
int width = getWidth () - ( insets.left + insets.right );
int widthFocus = width;
int height = getHeight () - ( insets.top + insets.bottom );
if ( height <= 0 || width <= 0 )
{
return;
}
int left = insets.left;
int top = insets.top;
int right = left + ( width - 1 );
int bottom = top + ( height - 1 );
int iconWidth = Theme.comboButtonWidth [ Theme.derivedStyle [ Theme.style ] ];
int iconLeft = ( leftToRight ) ? right : left;
// Let the renderer paint
Component c = null;
boolean mustResetOpaque = false;
boolean savedOpaque = false;
boolean paintFocus = false;
if ( !iconOnly && comboBox != null )
{
ListCellRenderer renderer = comboBox.getRenderer ();
boolean renderPressed = getModel ().isPressed ();
c = renderer.getListCellRendererComponent ( listBox, comboBox
.getSelectedItem (), -1, renderPressed, false );
c.setFont ( rendererPane.getFont () );
if ( model.isArmed () && model.isPressed () )
{
if ( isOpaque () )
{
c.setBackground ( UIManager.getColor ( "Button.select" ) );
}
c.setForeground ( comboBox.getForeground () );
}
else if ( !comboBox.isEnabled () )
{
if ( isOpaque () )
{
c.setBackground ( Theme.textDisabledBgColor [ Theme.style ]
.getColor () );
}
else
{
comboBox.setBackground ( Theme.textDisabledBgColor [ Theme.style ]
.getColor () );
}
c.setForeground ( UIManager.getColor ( "ComboBox.disabledForeground" ) );
}
else if ( comboBox.hasFocus () && !comboBox.isPopupVisible () )
{
if ( comboBox.isEditable () )
{
c.setForeground ( Theme.mainColor [ Theme.style ].getColor () );
}
else
{
c.setForeground ( UIManager
.getColor ( "ComboBox.selectionForeground" ) );
}
c.setBackground ( UIManager.getColor ( "ComboBox.focusBackground" ) );
if ( c instanceof JComponent )
{
mustResetOpaque = true;
JComponent jc = ( JComponent ) c;
savedOpaque = jc.isOpaque ();
jc.setOpaque ( true );
paintFocus = true;
}
}
else
{
c.setForeground ( comboBox.getForeground () );
c.setBackground ( comboBox.getBackground () );
}
int cWidth = width - ( insets.right + iconWidth );
// Fix for 4238829: should lay out the JPanel.
boolean shouldValidate = false;
if ( c instanceof JPanel )
{
shouldValidate = true;
}
if ( leftToRight )
{
rendererPane.paintComponent ( g, c, this, left, top, cWidth, height,
shouldValidate );
}
else
{
rendererPane.paintComponent ( g, c, this, left + iconWidth, top,
cWidth, height, shouldValidate );
}
if ( paintFocus && Theme.derivedStyle [ Theme.style ] == Theme.YQ_STYLE
&& Theme.comboFocus [ Theme.style ] )
{
g.setColor ( Color.black );
Graphics2D g2d = ( Graphics2D ) g;
Rectangle r = new Rectangle ( left, top, 2, 2 );
TexturePaint tp = new TexturePaint ( focusImg, r );
g2d.setPaint ( tp );
g2d.draw ( new Rectangle ( left, top, cWidth, height ) );
}
}
if ( mustResetOpaque )
{
JComponent jc = ( JComponent ) c;
jc.setOpaque ( savedOpaque );
}
}
private void drawTinyButton ( Graphics g, Rectangle r )
{
}
private void drawWinButton ( Graphics g, Rectangle r )
{
int x2 = r.x + r.width - 1;
int y2 = r.y + r.height - 1;
g.fillRect ( r.x, r.y, r.width - 2, r.height - 2 );
if ( model.isPressed () )
{
g.setColor ( Theme.comboButtDarkColor [ Theme.style ].getColor () );
g.drawRect ( r.x, r.y + 1, r.width - 2, r.height - 3 );
}
else
{
if ( !isEnabled () )
{
g.setColor ( Theme.comboButtLightDisabledColor [ Theme.style ]
.getColor () );
}
else
{
g.setColor ( Theme.comboButtLightColor [ Theme.style ].getColor () );
}
g.drawLine ( r.x + 1, r.y + 2, x2 - 3, r.y + 2 );
g.drawLine ( r.x + 1, r.y + 2, r.x + 1, y2 - 3 );
if ( !isEnabled () )
{
g.setColor ( Theme.comboButtDarkDisabledColor [ Theme.style ]
.getColor () );
}
else
{
g.setColor ( Theme.comboButtDarkColor [ Theme.style ].getColor () );
}
g.drawLine ( x2 - 2, r.y + 2, x2 - 2, y2 - 3 );
g.drawLine ( r.x + 1, y2 - 2, x2 - 2, y2 - 2 );
if ( !isEnabled () )
{
g.setColor ( Theme.comboButtBorderDisabledColor [ Theme.style ]
.getColor () );
}
else
{
g.setColor ( Theme.comboButtBorderColor [ Theme.style ].getColor () );
}
g.drawLine ( x2 - 1, r.y + 1, x2 - 1, y2 - 2 );
g.drawLine ( r.x, y2 - 1, x2 - 1, y2 - 1 );
}
}
private void drawXpButton ( Graphics g, Rectangle r, Color c )
{
int x2 = r.x + r.width;
int y2 = r.y + r.height;
int spread1 = Theme.comboSpreadLight [ Theme.style ];
int spread2 = Theme.comboSpreadDark [ Theme.style ];
if ( !isEnabled () )
{
spread1 = Theme.comboSpreadLightDisabled [ Theme.style ];
spread2 = Theme.comboSpreadDarkDisabled [ Theme.style ];
}
int h = r.height - 2;
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 ( r.x + 1, r.y + y + 1, r.x + r.width - 3, r.y + y + 1 );
}
// draw the button border
Color col = null;
if ( !isEnabled () )
{
col = Theme.comboButtBorderDisabledColor [ Theme.style ].getColor ();
}
else
{
col = Theme.comboButtBorderColor [ Theme.style ].getColor ();
}
g.setColor ( col );
g.drawLine ( r.x + 2, r.y + 1, x2 - 4, r.y + 1 );
g.drawLine ( r.x + 1, r.y + 2, r.x + 1, y2 - 3 );
g.drawLine ( x2 - 3, r.y + 2, x2 - 3, y2 - 3 );
g.drawLine ( r.x + 2, y2 - 2, x2 - 4, y2 - 2 );
// ecken
col = new Color ( col.getRed (), col.getGreen (), col.getBlue (), 128 );
g.setColor ( col );
g.drawLine ( r.x + 1, r.y + 1, r.x + 1, r.y + 1 );
g.drawLine ( x2 - 3, r.y + 1, x2 - 3, r.y + 1 );
g.drawLine ( r.x + 1, y2 - 2, r.x + 1, y2 - 2 );
g.drawLine ( x2 - 3, y2 - 2, x2 - 3, y2 - 2 );
}
private void drawTinyArrow ( Graphics g, Rectangle r )
{
}
private void drawWinArrow ( Graphics g, Rectangle r )
{
int x = r.x + ( r.width - 6 ) / 2 - 2;
int y = r.y + ( r.height - 4 ) / 2;
if ( model.isPressed () )
{
x++ ;
y++ ;
}
g.drawLine ( x, y, x + 6, y );
g.drawLine ( x + 1, y + 1, x + 5, y + 1 );
g.drawLine ( x + 2, y + 2, x + 4, y + 2 );
g.drawLine ( x + 3, y + 3, x + 3, y + 3 );
if ( !isEnabled () )
{
g.setColor ( ColorRoutines.lighten (
Theme.comboArrowDisabledColor [ Theme.style ].getColor (), 60 ) );
g.drawLine ( x + 4, y + 4, x + 4, y + 4 );
g.drawLine ( x + 4, y + 3, x + 5, y + 3 );
g.drawLine ( x + 5, y + 2, x + 6, y + 2 );
g.drawLine ( x + 6, y + 1, x + 7, y + 1 );
}
}
private void drawXpArrow ( Graphics g, Rectangle r )
{
int x = r.x + ( r.width - 8 ) / 2 - 1;
int y = r.y + ( r.height - 6 ) / 2 + 1;
g.drawLine ( x + 1, y, x + 1, y );
g.drawLine ( x + 7, y, x + 7, y );
g.drawLine ( x, y + 1, x + 2, y + 1 );
g.drawLine ( x + 6, y + 1, x + 8, y + 1 );
g.drawLine ( x + 1, y + 2, x + 3, y + 2 );
g.drawLine ( x + 5, y + 2, x + 7, y + 2 );
g.drawLine ( x + 2, y + 3, x + 6, y + 3 );
g.drawLine ( x + 3, y + 4, x + 5, y + 4 );
g.drawLine ( x + 4, y + 5, x + 4, y + 5 );
}
}