参考:http://flypig.iteye.com/blog/389253
swing的JButton如果要自定义样式:
方法1、可以重写BasicButtonUI然后给调用JButton的setUI;
方法2、可以继承JButton重写部分方法。原理就是重新绘制Jbutton包括按钮,边框等,也就是重写paintComponent(Graphics g)。
两者原理都一样。
StratorTest.java
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import com.gdite.skywalker.myswing.FileLinkButton;
import com.gdite.skywalker.myswing.ui.FileLinkButtonUI;
public class StratorTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(new FlowLayout(FlowLayout.LEFT));
frame.add(new FileLinkButton("文件"));
JButton btn = new JButton("测试");
btn.setUI(new FileLinkButtonUI());
frame.add(btn);
frame.setVisible(true);
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
BasicButton.java
public class BasicButton extends JButton {
/**
*
*/
private static final long serialVersionUID = 1L;
public static final Color BUTTON_COLOR1 = new Color(125, 161, 237);
public static final Color BUTTON_COLOR2 = new Color(91, 118, 173);
public static final Color BUTTON_BAK_COLOR1_1 = new Color(108, 135, 210,
179);
public static final Color BUTTON_BAK_COLOR1_2 = new Color(108, 135, 210,
255);
public static final Color BUTTON_BAK_COLOR2_1 = new Color(180, 230, 250,
179);
public static final Color BUTTON_BAK_COLOR2_2 = new Color(180, 230, 250,
255);
public static final Color BUTTON_FOREGROUND_COLOR = Color.BLACK;
private boolean hover;
public BasicButton(String text) {
super(text);
//步骤1
setBorderPainted(false);
setFocusPainted(false);
setContentAreaFilled(false);
setForeground(BUTTON_FOREGROUND_COLOR);
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
hover = true;
repaint();
}
@Override
public void mouseExited(MouseEvent e) {
hover = false;
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
int h = getHeight();
int w = getWidth();
// Color color2 = BUTTON_BAK_COLOR1_2;
// Color color1 = BUTTON_BAK_COLOR2_2;
float tran = 1F;
if (!hover) {
tran = 0.7F;
// color2 = BUTTON_BAK_COLOR1_1;
// color1 = BUTTON_BAK_COLOR2_1;
}
//步骤2
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
GradientPaint p1;
GradientPaint p2;
if (getModel().isPressed()) {
p1 = new GradientPaint(0, 0, new Color(0, 0, 0), 0, h - 1,
new Color(100, 100, 100));
p2 = new GradientPaint(0, 1, new Color(0, 0, 0, 50), 0, h - 3,
new Color(255, 255, 255, 100));
} else {
p1 = new GradientPaint(0, 0, new Color(100, 100, 100), 0, h - 1,
new Color(0, 0, 0));
p2 = new GradientPaint(0, 1, new Color(255, 255, 255, 100), 0,
h - 3, new Color(0, 0, 0, 50));
}
//设置透明度
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
tran));
Shape clip = g2d.getClip();
//绘制整个按钮
RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1,
h - 1, h, h);
g2d.clip(r2d);
GradientPaint gp = new GradientPaint(0.0F, 0.0F, BUTTON_COLOR1, 0.0F,
h, BUTTON_COLOR2, true);
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
//鼠标移入就绘制立体效果
if (hover) {
RoundRectangle2D.Float r2d2 = new RoundRectangle2D.Float(5, 2,
w - 10, h / 2 - 1, h / 2, h / 2);
g2d.clip(r2d2);
GradientPaint gp2 = new GradientPaint(0.0F, 0.0F, BUTTON_BAK_COLOR2_2, 0.0F,
h / 2, BUTTON_BAK_COLOR1_2, true);
g2d.setPaint(gp2);
g2d.fillRect(5, 2, w - 10, h / 2);
}
g2d.setClip(clip);
//绘制边框
g2d.setPaint(p1);
g2d.drawRoundRect(0, 0, w - 1, h - 1, h, h);
g2d.setPaint(p2);
g2d.drawRoundRect(1, 1, w - 3, h - 3, h - 2, h - 2);
g2d.dispose();
super.paintComponent(g);
}
}
基本步骤就是:
1.先调用父类的方法,让父类不用绘制边框、不用绘制焦点、不用绘制内容,我们自己来完成这些东西。
2.调用抗锯齿的api,让我们paint出来的线条平滑,要不然会有相当难看的锯齿。
3.设置透明度。这个主要是为了做出鼠标移入、移出的效果。我这里是移入按钮,按钮颜色加深并且会有视觉效果上的“凸起”立体感;移出就颜色变浅,凸起感消失,恢复原样了。
4.绘制整个按钮。生成一个圆角矩形,并用由上到下的渐进色填充,这就是按钮的整体效果。
5.如果鼠标移入就绘制立体效果。在这里我是先生成一个高度为按钮一半的圆角矩形,然后从上到下用渐进色填充,最下面的颜色就是按钮本身在中间位置的颜色,这样看起来上面是白的,好像反光的立体效果。
6.绘制边框。用于点击效果的显示。
如果要真正想apple那样的效果,就还需要用另外的区域来模糊化下半个按钮部分,需要涉及到调整颜色之类的,我这就没做了,大概的效果图如下:
正常状态
鼠标移上去
鼠标按下去
方法二:
FileLinkButtonUI
package com.gdite.skywalker.myswing.ui;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.plaf.basic.BasicButtonListener;
import javax.swing.plaf.basic.BasicButtonUI;
public class FileLinkButtonUI extends BasicButtonUI {
private boolean hover = false;
public static final Color BUTTON_COLOR1 = new Color(125, 161, 237);
public static final Color BUTTON_COLOR2 = new Color(91, 118, 173);
// public static final Color BUTTON_BAK_COLOR1_1 = new Color(108, 135, 210, 179);
public static final Color BUTTON_BAK_COLOR1_2 = new Color(108, 135, 210, 255);
// public static final Color BUTTON_BAK_COLOR2_1 = new Color(180, 230, 250, 179);
public static final Color BUTTON_BAK_COLOR2_2 = new Color(180, 230, 250, 255);
public FileLinkButtonUI() {
}
@Override
protected BasicButtonListener createButtonListener(AbstractButton b) {
// TODO Auto-generated method stub
b.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
hover = true;
System.out.println("mouseEntered");
super.mouseEntered(e);
}
@Override
public void mouseExited(MouseEvent e) {
hover = false;
System.out.println("mouseExited");
super.mouseExited(e);
}
});
return super.createButtonListener(b);
}
@Override
protected void installDefaults(AbstractButton b) {
b.setBorderPainted(false);
b.setFocusPainted(false);
b.setContentAreaFilled(false);
super.installDefaults(b);
}
@Override
public void paint(Graphics g, JComponent c) {
System.out.println("paint");
paintSelf(g, c);
super.paint(g, c);
}
@Override
protected void paintButtonPressed(Graphics g, AbstractButton b) {
paintSelf(g, b);
super.paintButtonPressed(g, b);
}
public void paintSelf(Graphics g, JComponent c) {
Graphics2D g2d = (Graphics2D) g.create();
int h = c.getHeight();
int w = c.getWidth();
// Color color2 = BUTTON_BAK_COLOR1_2;
// Color color1 = BUTTON_BAK_COLOR2_2;
float tran = 1F;
if (!hover) {
tran = 0.7F;
// color2 = BUTTON_BAK_COLOR1_1;
// color1 = BUTTON_BAK_COLOR2_1;
}
// 步骤2
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
GradientPaint p1;
GradientPaint p2;
if (((AbstractButton) c).getModel().isPressed()) {
p1 = new GradientPaint(0, 0, new Color(0, 0, 0), 0, h - 1,
new Color(100, 100, 100));
p2 = new GradientPaint(0, 1, new Color(0, 0, 0, 50), 0, h - 3,
new Color(255, 255, 255, 100));
} else {
p1 = new GradientPaint(0, 0, new Color(100, 100, 100), 0, h - 1,
new Color(0, 0, 0));
p2 = new GradientPaint(0, 1, new Color(255, 255, 255, 100), 0,
h - 3, new Color(0, 0, 0, 50));
}
// 设置透明度
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
tran));
Shape clip = g2d.getClip();
// 绘制整个按钮
RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1,
h - 1, h, h);
g2d.clip(r2d);
GradientPaint gp = new GradientPaint(0.0F, 0.0F, BUTTON_COLOR1, 0.0F,
h, BUTTON_COLOR2, true);
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
// 鼠标移入就绘制立体效果
if (hover) {
RoundRectangle2D.Float r2d2 = new RoundRectangle2D.Float(5, 2,
w - 10, h / 2 - 1, h / 2, h / 2);
g2d.clip(r2d2);
GradientPaint gp2 = new GradientPaint(0.0F, 0.0F,
BUTTON_BAK_COLOR2_2, 0.0F, h / 2, BUTTON_BAK_COLOR1_2, true);
g2d.setPaint(gp2);
g2d.fillRect(5, 2, w - 10, h / 2);
}
g2d.setClip(clip);
// 绘制边框
g2d.setPaint(p1);
g2d.drawRoundRect(0, 0, w - 1, h - 1, h, h);
g2d.setPaint(p2);
g2d.drawRoundRect(1, 1, w - 3, h - 3, h - 2, h - 2);
g2d.dispose();
}
}