Java Swing 自定义图片按钮

一个按钮,如下:


已经实现了,鼠标滑过变色,鼠标单击变色,如下:

 

如果在上面设置文本button.setText("ABCDEFGHIJKLMNOPQ"),如下:


那么问题来了

(1)设置很长的文本,button不会自动伸长

(2)文本覆盖了左边的图片

解决办法:将图片切成三块


重写paintComponent方法。但是问题如下:

button.setText("ABC");
button.setFont(new Font("SansSerif", Font.BOLD, 50));

,水平可以拉伸,竖直根据算法可以拉伸,但是由于水平切成三幅图,竖直拉伸时上下线条变粗了!

所以为了美观需要切成9格图片:


另外,重写paintComponent方法时,需要注意算法,一方面考虑到字体大小对图片的拉伸,还要考虑到setPreferredSize()等方法对其影响。


代码如下:


import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import twaver.TWaverUtil;

public class ImageButton9 extends JButton {
	private static final long serialVersionUID = 1L;

	protected boolean isEnable = true;

	private Color color;
	private Color txtBgColor = Color.BLACK;
	private Color txtOverColor = Color.BLACK;
	private Color txtDisColor = Color.GRAY;
	private Color txtPressColor = Color.WHITE;
	private Color txtSelColor = Color.WHITE;

    private int txtW;
    private int txtH;
    private int txtDescent;
	
	private String path;
	
	private Map map = new HashMap();

	public static final String ICON = "icon_";
	
	public static final String BG = "bg_";
	public static final String SEL = "sel_";
	public static final String OVER = "over_";
	public static final String PRESS = "press_";
	public static final String DIS = "dis_";

	public static final String LEFT_TOP = "left_top.png";
	public static final String TOP = "top.png";
	public static final String RIGHT_TOP = "right_top.png";
	public static final String LEFT = "left.png";
	public static final String CENTER = "center.png";
	public static final String RIGHT = "right.png";
	public static final String LEFT_BOTTOM = "left_bottom.png";
	public static final String BOTTOM = "bottom.png";
	public static final String RIGHT_BOTTOM = "right_bottom.png";
	
	
	public ImageButton9(String path) {
		this.path = path;
		init();
		invalidate();
		repaint();
	}

	private void init() {
		initMap();
		initUI();
		mouseListener();
		propertyListener();
	}

	private void initMap() {
		putIcon(BG);
		putIcon(SEL);
		putIcon(OVER);
		putIcon(PRESS);
		putIcon(DIS);
		setIcon(BG);
	}

	private void putIcon(String key) {
		map.put(key + LEFT_TOP, getIcon(key + LEFT_TOP, path));
		map.put(key + TOP, getIcon(key + TOP, path));
		map.put(key + RIGHT_TOP, getIcon(key + RIGHT_TOP, path));
		map.put(key + LEFT, getIcon(key + LEFT, path));
		map.put(key + CENTER, getIcon(key + CENTER, path));
		map.put(key + RIGHT, getIcon(key + RIGHT, path));
		map.put(key + LEFT_BOTTOM, getIcon(key + LEFT_BOTTOM, path));
		map.put(key + BOTTOM, getIcon(key + BOTTOM, path));
		map.put(key + RIGHT_BOTTOM, getIcon(key + RIGHT_BOTTOM, path));
	}

	private ImageIcon getIcon(String key, String path) {
		ImageIcon icon = map.get(key);

		if (icon != null) {
			return icon;
		}

		icon = TWaverUtil.getImageIcon(path + "/" + key);


		return icon;
	}

	private void setIcon(String key) {
		changeTxtColor(key);
		
		String prefix = ICON;
		map.put(prefix + LEFT_TOP, getIcon(key + LEFT_TOP, path));
		map.put(prefix + TOP, getIcon(key + TOP, path));
		map.put(prefix + RIGHT_TOP, getIcon(key + RIGHT_TOP, path));
		map.put(prefix + LEFT, getIcon(key + LEFT, path));
		map.put(prefix + CENTER, getIcon(key + CENTER, path));
		map.put(prefix + RIGHT, getIcon(key + RIGHT, path));
		map.put(prefix + LEFT_BOTTOM, getIcon(key + LEFT_BOTTOM, path));
		map.put(prefix + BOTTOM, getIcon(key + BOTTOM, path));
		map.put(prefix + RIGHT_BOTTOM, getIcon(key + RIGHT_BOTTOM, path));
	}
	
	private void changeTxtColor(String key) {
		if(BG.equals(key)) {
			color = txtBgColor;
		} else if(SEL.equals(key)) {
			color = txtSelColor;
		} else if(OVER.equals(key)) {
			color = txtOverColor;
		} else if(PRESS.equals(key)) {
			color = txtPressColor;
		} else if(DIS.equals(key)) {
			color = txtDisColor;
		}
	}

	private void initUI() {
		setMargin(new Insets(0, 0, 0, 0));

		setOpaque(false);
		setFocusable(false);
		setFocusPainted(false);
		setBorder(null);
	}

	public void mouseListener() {
		addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				if (isEnable) {
					setIcon(OVER);
					repaint();
				}
			}

			@Override
			public void mouseExited(MouseEvent e) {
				if (isEnable) {
					if (isSelected()) {
						setIcon(SEL);
					} else {
						setIcon(BG);
					}
					repaint();
				}
			}

			@Override
			public void mousePressed(MouseEvent e) {
				if (isEnable) {
					setIcon(PRESS);
					repaint();
				}
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (isEnable) {
					if(e.getX() >= 0 && e.getX() <= getWidth()
							&& e.getY() >= 0 && e.getY() <= getHeight()) {
						setIcon(OVER);
					} else {
						if (isSelected()) {
							setIcon(SEL);
						} else {
							setIcon(BG);
						}
					}
					repaint();
				}
			}
		});
	}
	
	private void propertyListener() {
		addPropertyChangeListener(new PropertyChangeListener() {
			@Override
			public void propertyChange(PropertyChangeEvent e) {
				if("font".equals(e.getPropertyName())
						|| "text".equals(e.getPropertyName())) {
					FontMetrics metrics = getFontMetrics(getFont());
					txtW = metrics.stringWidth(getText());
					txtH = metrics.getAscent() + metrics.getDescent();
					txtDescent = metrics.getDescent();
				}
			}
		});
	}
	
	@Override
	public void setSelected(boolean b) {
		super.setSelected(b);
		setIcon(SEL);
	}

	@Override
	public void setEnabled(boolean b) {
		isEnable = b;
		if (b) {
			if (isSelected()) {
				setIcon(SEL);
			} else {
				setIcon(BG);
			}
		} else {
			setIcon(DIS);
		}
		super.setEnabled(b);
	}
	
	public void setTxtOverColor(Color txtOverColor) {
		this.txtOverColor = txtOverColor;
	}
	
	public void setTxtDisColor(Color txtDisColor) {
		this.txtDisColor = txtDisColor;
	}

	public void setTxtPressColor(Color txtPressColor) {
		this.txtPressColor = txtPressColor;
	}
	
	public void setTxtSelColor(Color txtSelColor) {
		this.txtSelColor = txtSelColor;
	}
	
	@Override
	public void setForeground(Color color) {
		super.setForeground(color);
		txtBgColor = color;
		this.color = color;
	}

	@Override
	public Dimension getPreferredSize() {
		Dimension d = super.getPreferredSize();
		
		ImageIcon left_top = map.get(ICON + LEFT_TOP);
		ImageIcon right_top = map.get(ICON + RIGHT_TOP);
		ImageIcon left_bottom = map.get(ICON + LEFT_BOTTOM);
		
		if(left_top != null 
				&& right_top != null 
				&& left_bottom != null) {
			int calW = txtW + left_top.getIconWidth() + right_top.getIconWidth();
			int calH = txtH + left_top.getIconHeight() + left_bottom.getIconHeight();
			
			int w = (int)d.getWidth();
			w = (w < calW) ? calW : w;
			
			int h = (int)d.getHeight();
			h = (h < calH) ? calH : h;
			
			d.setSize(w, h);
		}
		
		return d;
	}
	
	private boolean checkIconIsNull() {
		String prefix = ICON;
		return map.get(prefix + LEFT_TOP) == null ||
		        map.get(prefix + TOP) == null ||
		        map.get(prefix + RIGHT_TOP) == null ||
		        map.get(prefix + LEFT) == null ||
		        map.get(prefix + CENTER) == null ||
		        map.get(prefix + RIGHT) == null ||
		        map.get(prefix + LEFT_BOTTOM) == null ||
		        map.get(prefix + BOTTOM) == null ||
		        map.get(prefix + RIGHT_BOTTOM) == null;
	}

	@Override
	public void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		
		ImageIcon left_top = map.get(ICON + LEFT_TOP);
		ImageIcon top = map.get(ICON + TOP);
		ImageIcon right_top = map.get(ICON + RIGHT_TOP);
		ImageIcon left = map.get(ICON + LEFT);
		ImageIcon center = map.get(ICON + CENTER);
		ImageIcon right = map.get(ICON + RIGHT);
		ImageIcon left_bottom = map.get(ICON + LEFT_BOTTOM);
		ImageIcon bottom = map.get(ICON + BOTTOM);
		ImageIcon right_bottom = map.get(ICON + RIGHT_BOTTOM);

		int centerW = (int)getSize().getWidth();
		int centerH = (int)getSize().getHeight();
		
		if(!checkIconIsNull()) {
			centerW = (int)getSize().getWidth() - left_top.getIconWidth() - right_top.getIconWidth();
			centerH = (int)getSize().getHeight() - left_top.getIconHeight() - left_bottom.getIconHeight();
			
			g2.drawImage(center.getImage(), 
					left_top.getIconWidth(), 
					left_top.getIconHeight(), 
					centerW, 
					centerH, null);
			g2.drawImage(top.getImage(), 
					left_top.getIconWidth(), 0,
					centerW, 
					left_top.getIconHeight(), null);
			g2.drawImage(bottom.getImage(), 
					left_top.getIconWidth(), 
					left_top.getIconHeight() + centerH, 
					centerW,
					left_bottom.getIconHeight(), null);
			g2.drawImage(left.getImage(), 
					0, 
					left_top.getIconHeight(),
					left_top.getIconWidth(), 
					centerH, null);
			g2.drawImage(right.getImage(), 
					left_top.getIconWidth() + centerW, 
					left_top.getIconHeight(), 
					right_top.getIconWidth(), 
					centerH, null);
			g2.drawImage(left_top.getImage(), 
					0, 
					0, 
					left_top.getIconWidth(), 
					left_top.getIconHeight(), null);
			g2.drawImage(right_top.getImage(), 
					left_top.getIconWidth() + centerW, 
					0, 
					right_top.getIconWidth(), 
					right_top.getIconHeight(), null);
			g2.drawImage(left_bottom.getImage(), 
					0, 
					left_top.getIconHeight() + centerH, 
					left_bottom.getIconWidth(), 
					left_bottom.getIconHeight(), null);
			g2.drawImage(right_bottom.getImage(), 
					left_top.getIconWidth() + centerW, 
					left_top.getIconHeight() + centerH, 
					right_bottom.getIconWidth(), 
					right_bottom.getIconHeight(), null);
		}

		if (getText() != null) {
			g2.setColor(isEnable ? color : txtDisColor);
			
			int left_position = left_top == null ? 0 : left_top.getIconWidth();
			int top_position = top == null ? 0 : top.getIconHeight();
			
			g2.drawString(getText(), 
					(centerW - txtW) / 2 + left_position, 
					(centerH + txtH) / 2 - txtDescent + top_position);
		}
	}
	
	public static void main(String[] args) {
		 
		 JButton btn = new JButton();
		 btn.setText("ABC");

		ImageButton9 button = new ImageButton9("/images/actions");
		ImageButton9 button2 = new ImageButton9("/images/actions");
		ImageButton9 button3 = new ImageButton9("/images/actions");
		ImageButton9 button4 = new ImageButton9("/images/actions");
		ImageButton9 button5 = new ImageButton9("/images/actions");
		ImageButton9 button6 = new ImageButton9("/images/actions");

		JPanel panel = new JPanel();
		panel.setLayout(new FlowLayout());
		panel.add(btn);
		panel.add(button);
		panel.add(button2);
		panel.add(button3);
		panel.add(button4);
		panel.add(button5);
		panel.add(button6);

		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(new Dimension(1000, 400));
		frame.setLocationRelativeTo(null);
		frame.getContentPane().add(panel);
		frame.setVisible(true);
			
		button.setText("ABC");
		
		button2.setText("ABC ABC ABC ABCABC");
		button2.setForeground(Color.BLUE);
		button2.setTxtSelColor(Color.WHITE);
		button2.setTxtPressColor(Color.GREEN);
		button2.setTxtOverColor(Color.RED);
		
		button3.setText("ABC ABC ABC ABC ABC");
		button3.setEnabled(false);
		
		button4.setText("ABC");
		button4.setFont(new Font("SansSerif", Font.BOLD, 22));
	
		button5.setText("ABC");
		button5.setSelected(true);

	}
}
PS:这实际上是我导师写的,我写的太渣了,感觉好厉害!

你可能感兴趣的:(JAVA)