You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
445 lines
12 KiB
445 lines
12 KiB
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
* 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.GradientPaint; |
|
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 |
|
*/ |
|
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 |
|
if (b.getParent() != null) { |
|
Color bg = b.getParent().getBackground(); |
|
g.setColor(bg); |
|
} |
|
g.drawRect(0, 0, w - 1, h - 1); |
|
|
|
Color normalLightColor = Theme.normalLightColor[Theme.style].getColor(); |
|
Color normalDarkColor = Theme.normalDarkColor[Theme.style].getColor(); |
|
Graphics2D g2 = (Graphics2D)g; |
|
drawHighLightButton(g2, normalLightColor, normalDarkColor, w, h); |
|
|
|
// 1 pixel away from each corner |
|
if(isRollover) { |
|
g2.setColor(Theme.buttonRolloverColor[Theme.style].getColor()); |
|
g2.drawLine(1, h - 2, 1, h - 2); |
|
g2.drawLine(w - 2, h - 2, w - 2, h - 2); |
|
Color rolloverLightColor = Theme.rolloverLightColor[Theme.style].getColor(); |
|
Color rolloverDarkColor = Theme.rolloverDarkColor[Theme.style].getColor(); |
|
drawHighLightButton(g2, rolloverLightColor, rolloverDarkColor, w, h); |
|
|
|
} |
|
else if(isDefault) { |
|
g2.setColor(Theme.buttonDefaultColor[Theme.style].getColor()); |
|
g2.drawLine(1, h - 2, 1, h - 2); |
|
g2.drawLine(w - 2, h - 2, w - 2, h - 2); |
|
Color defaultLightColor = Theme.defaultLightColor[Theme.style].getColor(); |
|
Color defaultDarkColor = Theme.defaultDarkColor[Theme.style].getColor(); |
|
drawHighLightButton(g2, defaultLightColor, defaultDarkColor, w, h); |
|
} |
|
} |
|
|
|
//harry: 画带有高光的按钮 |
|
private void drawHighLightButton(Graphics2D g2, Color color1, Color color2, int w, int h){ |
|
GradientPaint buttonPaint = new GradientPaint(0, 0, color1, 0, h-1, color2); |
|
GradientPaint buttonHighLightPaint = new GradientPaint(0, 0, new Color(1.0f, 1.0f, 1.0f, 0.6f), 0, h/2, new Color(1.0f, 1.0f, 1.0f, 0.2f)); |
|
GradientPaint buttonHighLightLinePaint = new GradientPaint(1, 1, new Color(1.0f, 1.0f, 1.0f, 0.8f), 0, h/2, new Color(1.0f, 1.0f, 1.0f, 0.4f)); |
|
g2.setPaint(buttonPaint); |
|
g2.fillRoundRect(0, 0, w-1, h-1, 3, 3); |
|
g2.setPaint(buttonHighLightLinePaint); |
|
g2.drawRoundRect(1, 1, w-3, h-3, 2, 2); |
|
g2.setPaint(buttonHighLightPaint); |
|
g2.fillRoundRect(0, 0, w-1, h/2, 3, 3); |
|
} |
|
|
|
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(); |
|
b.setOpaque(false); |
|
|
|
if(b.isContentAreaFilled()) { |
|
g.fillRect(1, 1, w - 2, h - 2); |
|
} |
|
|
|
} |
|
} |