很久沒來了,不是一位朋友給我發郵件問我關于swing的問題,才想起,然后翻看了之前的代碼,發現當年還實現了一個Vista風格的按鈕沒有放出來,現在補上,也許現在人們的swing水平對我這代碼不屑一顧,不過還是依然拋磚引玉,給未知的人們一個啟發。還是老慣例,上效果圖:
正常情況下:(和vista一樣具有焦點的按鈕的顏色漸深漸淺的循環變化)

鼠標在區域內時:

鼠標按下去:

然后是代碼:RButtonUI:
/**
* @(#)RButtonUI.java 0.2.0 2007-9-12
*
* Copyright2007 Rui Zhao, All rights reserved.
*/
package ruislan.rswing;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JComponent;
import javax.swing.Timer;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicButtonUI;
/**
*
* @version 0.2.0, 2007-9-12
* @author Rui Zhao <a href="mailto:z17520@gmail.com"/>
*/
public class RButtonUI extends BasicButtonUI {
private static final String TRANS_KEY = "trans";
public final static Color FOREGROUND_COLOR = new Color(0x001563);
public final static Color FOREGROUND_COLOR_DISABLE = new Color(0xC1C1C1);
public final static Color BORDER_COLOR_OUTER_NORMAL = new Color(0x707070);
public final static Color BORDER_COLOR_INNER_NORMAL = new Color(0xF3F3F3);
public final static Color BACKGROUD_UP_NORMAL_COLOR_1 = new Color(0xF2F2F2);
public final static Color BACKGROUD_UP_NORMAL_COLOR_2 = new Color(0xEBEBEB);
public final static Color BACKGROUD_DOWN_NORMAL_COLOR_1 = new Color(
0xD8D8D8);
public final static Color BACKGROUD_DOWN_NORMAL_COLOR_2 = new Color(
0xD0D0D0);
public final static Color BORDER_OUTER_HOVER_COLOR = new Color(0x4878A0);
public final static Color BORDER_INNER_HOVER_COLOR = new Color(0xF0F8F8);
public final static Color BACKGROUD_UP_HOVER_COLOR_1 = new Color(0xE0F0F8);
public final static Color BACKGROUD_UP_HOVER_COLOR_2 = new Color(0xC8E8F8);
public final static Color BACKGROUD_DOWN_HOVER_COLOR_1 = new Color(0xB8E0F8);
public final static Color BACKGROUD_DOWN_HOVER_COLOR_2 = new Color(0xB0E0F8);
public final static Color BORDER_OUTER_PRESS_COLOR = new Color(0x286088);
public final static Color BORDER_INNER_PRESS_COLOR_1 = new Color(0x88A8B0);
public final static Color BORDER_INNER_PRESS_COLOR_2 = new Color(0xB0C8E0);
public final static Color BACKGROUD_UP_PRESS_COLOR = new Color(0xC0E0F0);
public final static Color BACKGROUD_DOWN_PRESS_COLOR_1 = new Color(0xA8D8F0);
public final static Color BACKGROUD_DOWN_PRESS_COLOR_2 = new Color(0xA0D0F0);
public final static Color BORDER_OUTER_DISABLE_COLOR = new Color(0xA8B0B0);
public final static Color BORDER_INNER_DISABLE_COLOR = new Color(0xF8F8F8);
public final static Color BACKGROUD_DISABLE_COLOR = new Color(0xF0F0F0);
public final static Color BORDER_INNER_FOCUS_COLOR_1 = new Color(0x28D0F8);
public final static Color BORDER_INNER_FOCUS_COLOR_2 = new Color(0x58D8F8);
public final static Color BACKGROUD_UP_FOCUS_COLOR_1 = BACKGROUD_UP_HOVER_COLOR_1;
public final static Color BACKGROUD_UP_FOCUS_COLOR_2 = BACKGROUD_UP_HOVER_COLOR_2;
public final static Color BACKGROUD_DOWN_FOCUS_COLOR_1 = BACKGROUD_DOWN_HOVER_COLOR_1;
public final static Color BACKGROUD_DOWN_FOCUS_COLOR_2 = new Color(0xA8E0F8);
private final static RButtonUI rButtonUI = new RButtonUI();
public static ComponentUI createUI(JComponent c) {
return rButtonUI;
}
public void installDefaults(final AbstractButton b) {
super.installDefaults(b);
final Timer timer = new Timer(150, new ActionListener() {
private boolean forward = true;
private float trans;
public void actionPerformed(ActionEvent e) {
Object obj = b.getClientProperty(TRANS_KEY);
if (obj != null && obj instanceof Float) {
trans = (Float) obj;
} else {
trans = 1F;
}
if (trans <= 0F) {
forward = true;
} else if (trans >= 1F) {
forward = false;
}
if (forward) {
trans += 0.1F;
} else {
trans -= 0.1F;
}
if (trans < 0F) {
trans = 0F;
}
if (trans > 1F) {
trans = 1F;
}
b.putClientProperty(TRANS_KEY, trans);
b.repaint();
}
});
timer.setRepeats(true);
b.setBorderPainted(false);
b.setFocusPainted(false);
b.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
timer.stop();
b.putClientProperty(TRANS_KEY, 1F);
}
@Override
public void mouseExited(MouseEvent e) {
if (b.hasFocus()) {
timer.start();
}
}
});
b.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
timer.start();
}
public void focusLost(FocusEvent e) {
timer.stop();
b.putClientProperty(TRANS_KEY, 1F);
}
});
b.setPreferredSize(new Dimension(70, 22));
}
@Override
public void paint(Graphics g, JComponent c) {
AbstractButton button = (AbstractButton) c;
ButtonModel model = button.getModel();
if (button.isContentAreaFilled()) {
int h = c.getHeight();
int w = c.getWidth();
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0,
w - 1, h - 1, 8, 8);
Shape clip = g2d.getClip();
g2d.clip(r2d);
if (model.isEnabled()) {
button.setForeground(FOREGROUND_COLOR);
boolean rollOver = model.isRollover();
boolean pressed = model.isPressed() && model.isArmed();
boolean focused = button.hasFocus();
Paint gpUp = new GradientPaint(0.0F, 0.0F,
BACKGROUD_UP_NORMAL_COLOR_1, 0.0F, h / 2,
BACKGROUD_UP_NORMAL_COLOR_2);
Paint gpDown = new GradientPaint(0.0F, h / 2,
BACKGROUD_DOWN_NORMAL_COLOR_1, 0.0F, h,
BACKGROUD_DOWN_NORMAL_COLOR_2);
Paint borderInner = BORDER_COLOR_INNER_NORMAL;
Paint borderOuter = BORDER_COLOR_OUTER_NORMAL;
if (focused) {
g2d.setPaint(gpUp);
g2d.fillRect(0, 0, w, h / 2);
g2d.setPaint(gpDown);
g2d.fillRect(0, h / 2, w, h / 2);
Object obj = button.getClientProperty(TRANS_KEY);
float trans = 1F;
if (obj != null && obj instanceof Float) {
trans = (Float) obj;
}
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, trans));
borderInner = new GradientPaint(0.0F, 1F,
BORDER_INNER_FOCUS_COLOR_1, 0.0F, h - 3,
BORDER_INNER_FOCUS_COLOR_2);
borderOuter = BORDER_OUTER_HOVER_COLOR;
gpUp = new GradientPaint(0.0F, h / 2,
BACKGROUD_UP_FOCUS_COLOR_1, 0.0F, h,
BACKGROUD_UP_FOCUS_COLOR_2);
gpDown = new GradientPaint(0.0F, h / 2,
BACKGROUD_DOWN_FOCUS_COLOR_1, 0.0F, h / 2,
BACKGROUD_DOWN_FOCUS_COLOR_2);
}
if (rollOver) {
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 1F));
gpUp = new GradientPaint(0.0F, h / 2,
BACKGROUD_UP_HOVER_COLOR_1, 0.0F, h,
BACKGROUD_UP_HOVER_COLOR_2);
gpDown = new GradientPaint(0.0F, h / 2,
BACKGROUD_DOWN_HOVER_COLOR_1, 0.0F, h,
BACKGROUD_DOWN_HOVER_COLOR_2);
borderInner = BORDER_INNER_HOVER_COLOR;
borderOuter = BORDER_OUTER_HOVER_COLOR;
}
if (pressed) {
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 1F));
borderOuter = BORDER_OUTER_PRESS_COLOR;
borderInner = new GradientPaint(0.0F, 1F,
BORDER_INNER_PRESS_COLOR_1, 0.0F, h - 3,
BORDER_INNER_PRESS_COLOR_2);
gpDown = new GradientPaint(0.0F, h / 2,
BACKGROUD_DOWN_PRESS_COLOR_1, 0.0F, h / 2,
BACKGROUD_DOWN_PRESS_COLOR_2);
gpUp = BACKGROUD_UP_PRESS_COLOR;
}
g2d.setPaint(gpUp);
g2d.fillRect(0, 0, w, h / 2);
g2d.setPaint(gpDown);
g2d.fillRect(0, h / 2, w, h / 2);
g2d.setClip(clip);
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 1F));
g2d.setPaint(borderOuter);
g2d.drawRoundRect(0, 0, w - 1, h - 1, 8, 8);
g2d.setPaint(borderInner);
g2d.drawRoundRect(1, 1, w - 3, h - 3, 6, 6);
if (focused && !rollOver) {
g2d.drawRect(2, 2, w - 5, h - 5);
}
} else {
g2d.setPaint(BACKGROUD_DISABLE_COLOR);
g2d.fillRect(0, 0, w, h);
g2d.setClip(clip);
g2d.setPaint(BORDER_OUTER_DISABLE_COLOR);
g2d.drawRoundRect(0, 0, w - 1, h - 1, 8, 8);
g2d.setPaint(BORDER_INNER_DISABLE_COLOR);
g2d.drawRoundRect(1, 1, w - 3, h - 3, 6, 6);
button.setForeground(FOREGROUND_COLOR_DISABLE);
}
g2d.dispose();
}
super.paint(g, c);
}
}
使用代碼時,只需要在啟動時,加入如下代碼,然后new JButton()就行了,因為UIManager會在顯示時使用RButtonUI來顯示。
UIManager.getLookAndFeelDefaults().put("ButtonUI", "ruislan.rswing.RButtonUI");
UIManager.getLookAndFeelDefaults().put("Button.font", new Font("system", Font.PLAIN, 12));
posted on 2009-09-12 12:54
ruislan 閱讀(2485)
評論(3) 編輯 收藏