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