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