/*
* CaptionButtonUI.java
*
* Created on June 9, 2007, 8:56 AM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package dyno.swing.beans;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
/**
* 这个类时CaptionButton组建的UI类。
* 该UI类是个有状态UI类。
*
* @author William Chen
*/
public class CaptionButtonUI extends ComponentUI implements MouseMotionListener,
MouseListener, FocusListener {
//缺省前景色和缺省字体
private static final Color DEFAULT_FOREGROUND = new Color(33, 93, 198);
//定义一些缺省属性的值,比如颜色、字体、尺寸、间隙、缺省图标、虚线框的stroke等等。
private static final Color LIGHTER = new Color(255, 255, 255);
private static final Color DARKER = new Color(198, 211, 247);
private static final int TEXT_LEADING_GAP = 14;
private static final int IMAGE_TAILING_GAP = 12;
private static final Color HOVERED_COLOR = new Color(66, 142, 255);
private static Stroke DASHED_STROKE = new BasicStroke(1,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 1 },
0);
private static Icon iconExpanded;
private static Icon iconFoldered;
private static Icon hoveredExpanded;
private static Icon hoveredFoldered;
static {
//初始化
iconExpanded = new ImageIcon(CaptionButtonUI.class.getResource(
"resources/expanded.png"));
iconFoldered = new ImageIcon(CaptionButtonUI.class.getResource(
"resources/foldered.png"));
hoveredExpanded = new ImageIcon(CaptionButtonUI.class.getResource(
"resources/hovered_expanded.png"));
hoveredFoldered = new ImageIcon(CaptionButtonUI.class.getResource(
"resources/hovered_foldered.png"));
}
//是否画虚线框
private boolean armed;
//文字左边间隙
private int textLeadingGap = TEXT_LEADING_GAP;
//图像邮编间隙
private int p_w_picpathTailingGap = IMAGE_TAILING_GAP;
//渐变色起始色
private Color lightColor = LIGHTER;
//渐变色结束色
private Color darkColor = DARKER;
//当前鼠标是否浮动在上面
private boolean hovered;
//鼠标浮动在标题上方时标题的颜色
private Color hoveredColor = HOVERED_COLOR;
//该UI实例对应的CaptionButton
protected CaptionButton button;
/** Creates a new instance of CaptionButtonUI */
public CaptionButtonUI() {
}
public static ComponentUI createUI(JComponent c) {
return new CaptionButtonUI();
}
//安装CaptionButton的LAF
public void installUI(JComponent c) {
//设置缺省属性
button = (CaptionButton) c;
button.setForeground(DEFAULT_FOREGROUND);
button.setFocusable(true);
//添加事件处理器
button.addMouseListener(this);
button.addMouseMotionListener(this);
button.addFocusListener(this);
}
//卸载UI
public void uninstallUI(JComponent c) {
//卸载事件处理器
button.removeMouseListener(this);
button.removeMouseMotionListener(this);
button.removeFocusListener(this);
}
//画CaptionButton的背景。继承CaptionButtonUI的子类可以覆盖该方法自定义背景
protected void paintBackground(Graphics g) {
int w = button.getWidth();
int h = button.getHeight();
Graphics2D g2d = (Graphics2D) g;
GradientPaint gp = new GradientPaint(1, 1, lightColor, w - 2, 1,
darkColor);
g2d.setPaint(gp);
g2d.fillRect(1, 1, w - 2, h - 1);
gp = new GradientPaint(2, 0, lightColor, w - 4, 0, darkColor);
g2d.setPaint(gp);
g2d.fillRect(2, 0, w - 4, 1);
g2d.setColor(lightColor);
g2d.drawLine(0, 2, 0, h - 1);
g2d.setColor(darkColor);
g2d.drawLine(w - 1, 2, w - 1, h - 1);
}
public void paint(Graphics g, JComponent c) {
paintBackground(g);
paintCaptionText(g);
paintIcon(g);
if (armed) {
paintArmed(g);
}
}
//画虚线框,继承CaptionButtonUI的子类可以覆盖该方法自定义焦点获得外观
protected void paintArmed(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
g2d.setStroke(DASHED_STROKE);
g2d.drawRoundRect(1, 1, button.getWidth() - 3, button.getHeight() - 3,
2, 2);
}
//画标题栏展开、关闭图标,继承CaptionButtonUI的子类可以覆盖该方法自定义展开、关闭图标
protected void paintIcon(Graphics g) {
Icon icon = null;
if (hovered) {
icon = button.isExpanded() ? hoveredExpanded : hoveredFoldered;
} else {
icon = button.isExpanded() ? iconExpanded : iconFoldered;
}
int x = button.getWidth() - p_w_picpathTailingGap - icon.getIconWidth();
int y = (button.getHeight() - icon.getIconHeight()) / 2;
icon.paintIcon(button, g, x, y);
}
//画标题栏文字,继承CaptionButtonUI的子类可以覆盖该方法自定义文字的外观
protected void paintCaptionText(Graphics g) {
FontMetrics fm = g.getFontMetrics();
if (button.getText() != null) {
Color foreground = button.getForeground();
Color color = hovered ? hoveredColor : foreground;
g.setColor(color);
int y = ((button.getHeight() - fm.getHeight()) / 2) +
fm.getAscent();
g.drawString(button.getText(), textLeadingGap, y);
}
}
//处理按下鼠标事件
public void mousePressed(MouseEvent e) {
//改换外观
setArmed(true);
//折叠或者展开
button.setExpanded(!button.isExpanded());
//触发选择事件
ItemEvent evt = new ItemEvent(button, button.isExpanded() ? 0 : 1,
button.getText(),
button.isExpanded() ? ItemEvent.SELECTED : ItemEvent.DESELECTED);
button.fireItemStateChanged(evt);
//获得焦点
button.requestFocus();
}
//鼠标进入事件、浮动事件
public void mouseEntered(MouseEvent e) {
//浮动
setHovered(true);
//改鼠标外观
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
//鼠标退出事件
public void mouseExited(MouseEvent e) {
//浮动消失
setHovered(false);
}
void setHovered(boolean b) {
hovered = b;
button.repaint();
}
//焦点消失事件
public void focusLost(FocusEvent e) {
setArmed(false);
}
void setArmed(boolean b) {
armed = b;
button.repaint();
}
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void focusGained(FocusEvent e) {
}
}