使用paintComponent()方法绘制的各种Button:
正常状态:
获得焦点状态:
被按下状态:
被释放状态:
实现代码:
package com.han; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RadialGradientPaint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.LineMetrics; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.UnsupportedLookAndFeelException; @SuppressWarnings("serial") public class JButton_Bg extends JFrame { public JButton_Bg() { for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { if (laf.getName().equals("Nimbus")) { try { UIManager.setLookAndFeel(laf.getClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // TODO Auto-generated constructor stub Container c = getContentPane(); c.setLayout(new FlowLayout()); final JButton button = new MyButton("button 2"); c.add(button); JButton button2 = new JButton("button 2"); c.add(button2); button2.setBackground(Color.blue); JButton button3 = new MyButton2("Cancel"); c.add(button3); // 完全重绘的Button,其Text的HTML设置特性消失 // JButton button4 = new // MyButton3("<html><font size=12>Sub</font></html>"); JButton button4 = new MyButton3("Sub"); // button4.setFont(new Font("Serif", Font.PLAIN, 14)); c.add(button4); } private class MyButton extends JButton { private String text; private String state = "normal"; // private String state = "focused"; // private String state = "pressed"; // private String state = "released"; Shape shape; // 无参构造继承时自动调用,而有参构造继承时则需手动重写 MyButton(String text) { // super("<html><font size=5>" + text + "</font></html>"); super(text); this.text = text; // 下 面的代码块若是放到下面的paintComponent()方法里则Swing界面初始化时, // 布局管理器还是采用的是系统默认的PreferredSize。因为构造函数要优先于 // paintComponent()方法执行。 Dimension preferredSize = getPreferredSize(); Dimension preferredSizeNew = new Dimension(preferredSize.width, preferredSize.width); setPreferredSize(preferredSizeNew); } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int width = this.getPreferredSize().width; int height = this.getPreferredSize().height; if (state.equals("normal")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); shape = new Ellipse2D.Double(width / 2 - height / 2, 0, height, height); g2.fill(shape); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("focused")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new Ellipse2D.Double(width / 2 - height / 2, 0, height, height)); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("pressed")) { // draw background pattern int offsetCenter = 1; Point2D center = new Point2D.Float(width / 2 + offsetCenter, height / 2 + offsetCenter); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new Ellipse2D.Double(width / 2 - height / 2 + offsetCenter, offsetCenter, height, height)); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2) + offsetCenter, (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent())) + offsetCenter); } else if (state.equals("released")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new Ellipse2D.Double(width / 2 - height / 2, 0, height, height)); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移入组件"); state = "focused"; repaint(); } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移出组件"); state = "normal"; repaint(); } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被按下,"); state = "pressed"; repaint(); } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被释放,"); state = "released"; repaint(); } }); } // Gives the UI delegate an opportunity to define the precise shape of // this component for the sake of mouse processing. @Override public boolean contains(int x, int y) { if (shape.contains(x, y)) { return true; } else { return false; } } } private class MyButton2 extends JButton { private String text; private String state = "normal"; // private String state = "focused"; // private String state = "pressed"; // private String state = "released"; Shape shape; // Initialize the size of the button according to the length and width // of the text string MyButton2(String text) { super(text); this.text = text; } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int width = this.getWidth(); int height = this.getHeight(); if (state.equals("normal")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("focused")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("pressed")) { Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("released")) { Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移入组件"); state = "focused"; repaint(); } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移出组件"); state = "normal"; repaint(); } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被按下,"); state = "pressed"; repaint(); } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被释放,"); state = "released"; repaint(); } }); } @Override public boolean contains(int x, int y) { if (shape.contains(x, y)) { return true; } else { return false; } } } private class MyButton3 extends JButton { private String text; private String state = "normal"; // private String state = "focused"; // private String state = "pressed"; // private String state = "released"; Shape shape; // Initialize the size of the button according to the length and width // of the text string MyButton3(String text) { super(text); this.text = text; } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int width = this.getWidth(); int height = this.getHeight(); if (state.equals("normal")) { Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("focused")) { Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("pressed")) { g2.setColor(new Color(0, 147, 255)); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); double borderWidth = 2.0f; // 2 pixels g2.fill(new RoundRectangle2D.Double(borderWidth, borderWidth, width - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("released")) { Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移入组件"); state = "focused"; repaint(); } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移出组件"); state = "normal"; repaint(); } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被按下,"); state = "pressed"; repaint(); } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被释放,"); state = "released"; repaint(); } }); } @Override public boolean contains(int x, int y) { if (shape.contains(x, y)) { return true; } else { return false; } } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub JButton_Bg frame = new JButton_Bg(); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
添加了背景图片的Button:
显然当按钮大小改变时,背景图片有失真。
实现代码:
package com.han; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RadialGradientPaint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.LineMetrics; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.UnsupportedLookAndFeelException; @SuppressWarnings("serial") public class JButton_Bg extends JFrame { public JButton_Bg() { for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { if (laf.getName().equals("Nimbus")) { try { UIManager.setLookAndFeel(laf.getClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // TODO Auto-generated constructor stub Container c = getContentPane(); c.setLayout(new FlowLayout()); final JButton button = new MyButton("button 2"); c.add(button); JButton button2 = new JButton("button 2"); c.add(button2); button2.setBackground(Color.blue); JButton button3 = new MyButton2("Cancel"); c.add(button3); // 完全重绘的Button,其Text的HTML设置特性消失 // JButton button4 = new // MyButton3("<html><font size=12>Sub</font></html>"); JButton button4 = new MyButton3("Sub"); // button4.setFont(new Font("Serif", Font.PLAIN, 14)); c.add(button4); } private class MyButton extends JButton { private String text; private String state = "normal"; // private String state = "focused"; // private String state = "pressed"; // private String state = "released"; Shape shape; // 无参构造继承时自动调用,而有参构造继承时则需手动重写 MyButton(String text) { // super("<html><font size=5>" + text + "</font></html>"); super(text); this.text = text; // 下 面的代码块若是放到下面的paintComponent()方法里则Swing界面初始化时, // 布局管理器还是采用的是系统默认的PreferredSize。因为构造函数要优先于 // paintComponent()方法执行。 Dimension preferredSize = getPreferredSize(); Dimension preferredSizeNew = new Dimension(preferredSize.width, preferredSize.width); setPreferredSize(preferredSizeNew); } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int width = this.getPreferredSize().width; int height = this.getPreferredSize().height; BufferedImage img; try { img = ImageIO.read(this.getClass().getResource( "/images/icon.jpg")); g2.drawImage(img, 0, 0, width, height, this); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } if (state.equals("normal")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); shape = new Ellipse2D.Double(width / 2 - height / 2, 0, height, height); g2.fill(shape); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("focused")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new Ellipse2D.Double(width / 2 - height / 2, 0, height, height)); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("pressed")) { // draw background pattern int offsetCenter = 1; Point2D center = new Point2D.Float(width / 2 + offsetCenter, height / 2 + offsetCenter); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new Ellipse2D.Double(width / 2 - height / 2 + offsetCenter, offsetCenter, height, height)); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2) + offsetCenter, (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent())) + offsetCenter); } else if (state.equals("released")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new Ellipse2D.Double(width / 2 - height / 2, 0, height, height)); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移入组件"); state = "focused"; repaint(); } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移出组件"); state = "normal"; repaint(); } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被按下,"); state = "pressed"; repaint(); } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被释放,"); state = "released"; repaint(); } }); } // Gives the UI delegate an opportunity to define the precise shape of // this component for the sake of mouse processing. @Override public boolean contains(int x, int y) { if (shape.contains(x, y)) { return true; } else { return false; } } } private class MyButton2 extends JButton { private String text; private String state = "normal"; // private String state = "focused"; // private String state = "pressed"; // private String state = "released"; Shape shape; // Initialize the size of the button according to the length and width // of the text string MyButton2(String text) { super(text); this.text = text; } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int width = this.getWidth(); int height = this.getHeight(); if (state.equals("normal")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("focused")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("pressed")) { Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("released")) { Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移入组件"); state = "focused"; repaint(); } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移出组件"); state = "normal"; repaint(); } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被按下,"); state = "pressed"; repaint(); } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被释放,"); state = "released"; repaint(); } }); } @Override public boolean contains(int x, int y) { if (shape.contains(x, y)) { return true; } else { return false; } } } private class MyButton3 extends JButton { private String text; private String state = "normal"; // private String state = "focused"; // private String state = "pressed"; // private String state = "released"; Shape shape; // Initialize the size of the button according to the length and width // of the text string MyButton3(String text) { super(text); this.text = text; } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int width = this.getWidth(); int height = this.getHeight(); if (state.equals("normal")) { Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("focused")) { Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("pressed")) { g2.setColor(new Color(0, 147, 255)); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); double borderWidth = 2.0f; // 2 pixels g2.fill(new RoundRectangle2D.Double(borderWidth, borderWidth, width - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("released")) { Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移入组件"); state = "focused"; repaint(); } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移出组件"); state = "normal"; repaint(); } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被按下,"); state = "pressed"; repaint(); } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub System.out.print("鼠标按键被释放,"); state = "released"; repaint(); } }); } @Override public boolean contains(int x, int y) { if (shape.contains(x, y)) { return true; } else { return false; } } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub JButton_Bg frame = new JButton_Bg(); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
使用基于Nimbus包的Customize出属于自己的Look and Feel:
使用Painter可以保留按钮的HTML特性(因为自己不需要重画 Text)
package com.han; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.RadialGradientPaint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.awt.geom.RoundRectangle2D; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.Painter; import javax.swing.UIDefaults; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.UIManager.LookAndFeelInfo; /** * 使用了Nimbus的个性化组件方法。使用Painter可以保留按钮的HTML特性(因为自己不需要重画 Text)。 * * @see JButton_Bg * @author HAN * */ @SuppressWarnings("serial") public class JButton_Bg_2 extends JFrame { static JButton button; static JButton buttonBg; static JButton buttonExtended1; static JButton buttonExtended2; static JButton buttonExtended3; public JButton_Bg_2() { for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { if (laf.getName().equals("Nimbus")) { try { UIManager.setLookAndFeel(laf.getClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } Container c = getContentPane(); c.setLayout(new FlowLayout()); button = new JButton("button"); c.add(button); buttonBg = new JButton("button"); c.add(buttonBg); buttonBg.setBackground(Color.blue); buttonExtended1 = new JButtonExtended1("OK"); buttonExtended1.setForeground(Color.GREEN); c.add(buttonExtended1); buttonExtended2 = new JButtonExtended2("<html><u>C</u>ancel</html>"); c.add(buttonExtended2); buttonExtended3 = new JButtonExtended3("Sub"); c.add(buttonExtended3); } private class JButtonExtended1 extends JButton { Shape shape; JButtonExtended1(String text) { super(text); // 设置按钮默认文本颜色为红色 this.setForeground(Color.RED); // 设置按钮默认区域为正方形 Dimension preferredSize = getPreferredSize(); Dimension preferredSizeNew = new Dimension(preferredSize.width, preferredSize.width); setPreferredSize(preferredSizeNew); /* customize button */ UIDefaults sliderDefaults = new UIDefaults(); sliderDefaults.put("Button.contentMargins", new Insets(6, 14, 6, 14)); sliderDefaults.put("Button[Enabled].backgroundPainter", new Painter<JComponent>() { public void paint(Graphics2D g, JComponent c, int width, int height) { g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); shape = new Ellipse2D.Double( width / 2 - height / 2, 0, height, height); g.fill(shape); } }); sliderDefaults.put("Button[MouseOver].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new Ellipse2D.Double(width / 2 - height / 2, 0, height, height)); } }); sliderDefaults.put("Button[Focused].backgroundPainter", new Painter<JComponent>() { // The paint is the same as MouseOver @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new Ellipse2D.Double(width / 2 - height / 2, 0, height, height)); } }); sliderDefaults.put("Button[Focused+Pressed].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern int offsetCenter = 1; Point2D center = new Point2D.Float(width / 2 + offsetCenter, height / 2 + offsetCenter); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new Ellipse2D.Double(width / 2 - height / 2 + offsetCenter, offsetCenter, height, height)); } }); this.putClientProperty("Nimbus.Overrides", sliderDefaults); // replace the defaults this.putClientProperty("Nimbus.Overrides.InheritDefaults", false); } @Override public boolean contains(int x, int y) { try { if (shape.contains(x, y)) { return true; } else { return false; } } catch (NullPointerException e) { System.out.println("NullPointerException"); } return super.contains(x, y); } } private class JButtonExtended2 extends JButton { Shape shape; JButtonExtended2(String text) { super(text); /* customize button */ UIDefaults sliderDefaults = new UIDefaults(); // sliderDefaults.put("Button.defaultButtonFollowsFocus", false); sliderDefaults.put("Button.contentMargins", new Insets(6, 14, 6, 14)); sliderDefaults.put("Button[Enabled].backgroundPainter", new Painter<JComponent>() { public void paint(Graphics2D g, JComponent c, int width, int height) { // // Rendering operations have no effect outside of // // the clipping area. // g.setClip(0, 0, height, height); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); g.fill(shape); } }); sliderDefaults.put("Button[MouseOver].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); } }); sliderDefaults.put("Button[Focused].backgroundPainter", new Painter<JComponent>() { // The paint is the same as MouseOver @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); } }); sliderDefaults.put("Button[Focused+Pressed].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); } }); this.putClientProperty("Nimbus.Overrides", sliderDefaults); // replace the defaults this.putClientProperty("Nimbus.Overrides.InheritDefaults", false); } @Override public boolean contains(int x, int y) { try { if (shape.contains(x, y)) { return true; } else { return false; } } catch (NullPointerException e) { System.out.println("NullPointerException"); } return super.contains(x, y); } } private class JButtonExtended3 extends JButton { Shape shape; JButtonExtended3(String text) { super(text); /* customize button */ UIDefaults sliderDefaults = new UIDefaults(); sliderDefaults.put("Button.contentMargins", new Insets(6, 14, 6, 14)); sliderDefaults.put("Button[Enabled].backgroundPainter", new Painter<JComponent>() { public void paint(Graphics2D g, JComponent c, int width, int height) { g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); g.fill(shape); } }); sliderDefaults.put("Button[MouseOver].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); } }); sliderDefaults.put("Button[Focused].backgroundPainter", new Painter<JComponent>() { // The paint is the same as MouseOver @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); } }); sliderDefaults.put("Button[Focused+Pressed].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern g.setColor(new Color(0, 147, 255)); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); double borderWidth = 0.0f; // 0 pixels, no border g.fill(new RoundRectangle2D.Double(borderWidth, borderWidth, width - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f)); } }); this.putClientProperty("Nimbus.Overrides", sliderDefaults); // replace the defaults this.putClientProperty("Nimbus.Overrides.InheritDefaults", false); } @Override public boolean contains(int x, int y) { try { if (shape.contains(x, y)) { return true; } else { return false; } } catch (NullPointerException e) { System.out.println("NullPointerException"); } return super.contains(x, y); } } public static void main(String[] args) { // TODO Auto-generated method stub JButton_Bg_2 frame = new JButton_Bg_2(); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // If you want to ensure that a particular component gains the focus // the first time a window is activated, you can call the // requestFocusInWindow method on the component after the component // has been realized, but before the frame is displayed. frame.pack(); // Realize the components. // This button will have the initial focus. buttonExtended2.requestFocusInWindow(); frame.setVisible(true);// Display the window. } }
下面的只是对以上总共3种方法做了代码优化:
package com.han; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RadialGradientPaint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.LineMetrics; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.UnsupportedLookAndFeelException; /** * 使用了重绘JButton的个性化组件方法。使用paint()不可以保留按钮的HTML特性(因为目前自己 * 还没找到怎么画带HTML特性的String的方法)。 * <p> * 采用了fire JButton的ActionEvent方法来画各种不同的按钮状态。 * * @see JButton_Bg_2 * @see JButton_Bg_3 * @author HAN * */ @SuppressWarnings("serial") public class JButton_Bg extends JFrame { public JButton_Bg() { for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { if (laf.getName().equals("Nimbus")) { try { UIManager.setLookAndFeel(laf.getClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // TODO Auto-generated constructor stub Container c = getContentPane(); c.setLayout(new FlowLayout()); final JButton button = new MyButton("button 2"); c.add(button); JButton button2 = new JButton("button 2"); c.add(button2); button2.setBackground(Color.blue); JButton button3 = new MyButton2("Cancel"); c.add(button3); // 完全重绘的Button,其Text的HTML设置特性消失 // JButton button4 = new // MyButton3("<html><font size=12>Sub</font></html>"); JButton button4 = new MyButton3("Sub"); // button4.setFont(new Font("Serif", Font.PLAIN, 14)); c.add(button4); } private class MyButton extends JButton { private String text; private String state = "normal"; // private String state = "focused"; // private String state = "pressed"; // private String state = "released"; private int width; private int height; private Shape shape; // 无参构造继承时自动调用,而有参构造继承时则需手动重写 MyButton(String text) { // super("<html><font size=5>" + text + "</font></html>"); super(text); this.text = text; // 下面的代码块若是放到下面的paintComponent()方法里则Swing界面初始化时, // 布局管理器还是采用的是系统默认的PreferredSize。因为构造函数要优先于 // paintComponent()方法执行。 Dimension preferredSize = getPreferredSize(); Dimension preferredSizeNew = new Dimension(preferredSize.width, preferredSize.width); setPreferredSize(preferredSizeNew); // 自定义鼠标热点区域shape width = getPreferredSize().width; height = getPreferredSize().height; shape = new Ellipse2D.Double(width / 2 - height / 2, 0, height, height); } @Override protected void paintComponent(Graphics g) { System.out.println("paintComponent"); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (state.equals("normal")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("focused")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("pressed")) { // draw background pattern int offsetCenter = 1; Point2D center = new Point2D.Float(width / 2 + offsetCenter, height / 2 + offsetCenter); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(new Ellipse2D.Double(width / 2 - height / 2 + offsetCenter, offsetCenter, height, height)); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2) + offsetCenter, (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent())) + offsetCenter); } else if (state.equals("released")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); // draw string text g2.setColor(Color.RED); Font defaultFont = getFont(); g2.setFont(defaultFont); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移入组件"); state = "focused"; // repaint();// 可有可无,因为鼠标事件本身自动触发paintComponent() } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移出组件"); state = "normal"; } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub System.out.println("鼠标按键被按下,"); state = "pressed"; } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub System.out.println("鼠标按键被释放,"); state = "released"; } }); } // Gives the UI delegate an opportunity to define the precise shape of // this component for the sake of mouse processing. @Override public boolean contains(int x, int y) { return shape.contains(x, y); } } private class MyButton2 extends JButton { private String text; private String state = "normal"; // private String state = "focused"; // private String state = "pressed"; // private String state = "released"; private int width; private int height; private Shape shape; MyButton2(String text) { super(text); this.text = text; // 自定义鼠标热点区域shape this.width = getPreferredSize().width; this.height = getPreferredSize().height; this.shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (state.equals("normal")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("focused")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("pressed")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("released")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移入组件"); state = "focused"; } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移出组件"); state = "normal"; } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub System.out.println("鼠标按键被按下,"); state = "pressed"; } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub System.out.println("鼠标按键被释放,"); state = "released"; } }); } @Override public boolean contains(int x, int y) { return shape.contains(x, y); } } private class MyButton3 extends JButton { private String text; private String state = "normal"; // private String state = "focused"; // private String state = "pressed"; // private String state = "released"; private int width; private int height; private Shape shape; MyButton3(String text) { super(text); this.text = text; // 自定义鼠标热点区域shape this.width = getPreferredSize().width; this.height = getPreferredSize().height; this.shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (state.equals("normal")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("focused")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("pressed")) { // draw background pattern g2.setColor(new Color(0, 147, 255)); g2.fill(shape); Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); double borderWidth = 2.0f; // 2 pixels g2.fill(new RoundRectangle2D.Double(borderWidth, borderWidth, width - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f)); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } else if (state.equals("released")) { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); // draw string text Font defaultFont = getFont(); g2.setFont(defaultFont); g2.setColor(Color.BLACK); Rectangle2D rect = defaultFont.getStringBounds(text, g2.getFontRenderContext()); LineMetrics lineMetrics = defaultFont.getLineMetrics(text, g2.getFontRenderContext()); g2.drawString( text, (float) (width / 2 - rect.getWidth() / 2), (float) ((height / 2) + ((lineMetrics.getAscent() + lineMetrics .getDescent()) / 2 - lineMetrics.getDescent()))); } addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移入组件"); state = "focused"; } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub System.out.println("光标移出组件"); state = "normal"; } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub System.out.println("鼠标按键被按下,"); state = "pressed"; } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub System.out.println("鼠标按键被释放,"); state = "released"; } }); } @Override public boolean contains(int x, int y) { return shape.contains(x, y); } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub JButton_Bg frame = new JButton_Bg(); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
package com.han; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RadialGradientPaint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.awt.geom.RoundRectangle2D; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.UnsupportedLookAndFeelException; /** * 使用了重绘JButton的个性化组件方法。使用paint()保留了按钮的HTML特性(因为通过 setContentAreafilled(false) + * super.paintComponent(g) 这一方法使我们不需画带HTML特性的String)。 * <p> * 采用了JButton的getModel()方法(State model for buttons.)来画各种不同的按钮状态。 * * @see JButton_Bg * @see JButton_Bg_3 * @author HAN * */ @SuppressWarnings("serial") public class JButton_Bg_2 extends JFrame { public JButton_Bg_2() { for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { if (laf.getName().equals("Nimbus")) { try { UIManager.setLookAndFeel(laf.getClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // TODO Auto-generated constructor stub Container c = getContentPane(); c.setLayout(new FlowLayout()); final JButton button = new MyButton("button 2"); System.out.println(button.isPreferredSizeSet()); c.add(button); JButton button2 = new JButton("button 2"); c.add(button2); button2.setBackground(Color.blue); System.out.println(button2.isPreferredSizeSet()); JButton button3 = new MyButton2("Cancel"); c.add(button3); // 完全重绘的Button,其Text的HTML设置特性消失 // JButton button4 = new // MyButton3("<html><font size=12>Sub</font></html>"); JButton button4 = new MyButton3("<html>Su<u>b</u></html>"); // button4.setFont(new Font("Serif", Font.PLAIN, 14)); c.add(button4); } private class MyButton extends JButton { private int width; private int height; private Shape shape; // 无参构造继承时自动调用,而有参构造继承时则需手动重写 MyButton(String text) { super(text); setContentAreaFilled(false); setForeground(Color.RED); // 下面的代码块若是放到下面的paintComponent()方法里则Swing界面初始化时, // 布局管理器还是采用的是系统默认的PreferredSize。因为构造函数要优先于 // paintComponent()方法执行。 // 变方形按钮为圆形 Dimension preferredSize = getPreferredSize(); Dimension preferredSizeNew = new Dimension(preferredSize.width, preferredSize.width); setPreferredSize(preferredSizeNew); // 自定义鼠标热点区域shape width = getPreferredSize().width; height = getPreferredSize().height; shape = new Ellipse2D.Double(width / 2 - height / 2, 0, height, height); } @Override protected void paintComponent(Graphics g) { System.out.println(); System.out.print("paintComponent\t"); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (this.getModel().isEnabled()) { System.out.print("isEnabled\t"); if (this.getModel().isRollover()) { System.out.print("isRollover\t"); if (this.getModel().isPressed()) { System.out.print("isPressed\t"); // draw background pattern int offsetCenter = 1; Point2D center = new Point2D.Float(width / 2 + offsetCenter, height / 2 + offsetCenter); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g2.setPaint(paint); g2.fill(new Ellipse2D.Double(width / 2 - height / 2 + offsetCenter, offsetCenter, height, height)); } else { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); } } else { System.out.print("Normal\t"); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); } } super.paintComponent(g); } // Gives the UI delegate an opportunity to define the precise shape of // this component for the sake of mouse processing. @Override public boolean contains(int x, int y) { return shape.contains(x, y); } } private class MyButton2 extends JButton { private int width; private int height; private Shape shape; MyButton2(String text) { super(text); setContentAreaFilled(false); // 自定义鼠标热点区域shape this.width = getPreferredSize().width; this.height = getPreferredSize().height; this.shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); } protected void paintComponent(Graphics g) { System.out.println(); System.out.print("paintComponent\t"); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (this.getModel().isEnabled()) { System.out.print("isEnabled\t"); if (this.getModel().isRollover()) { System.out.print("isRollover\t"); if (this.getModel().isPressed()) { System.out.print("isPressed\t"); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); } else { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); } } else { System.out.print("Normal\t"); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); } } super.paintComponent(g); } @Override public boolean contains(int x, int y) { return shape.contains(x, y); } } private class MyButton3 extends JButton { private int width; private int height; private Shape shape; MyButton3(String text) { super(text); setContentAreaFilled(false); // 自定义鼠标热点区域shape this.width = getPreferredSize().width; this.height = getPreferredSize().height; this.shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); } protected void paintComponent(Graphics g) { System.out.println(); System.out.print("paintComponent\t"); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (this.getModel().isEnabled()) { System.out.print("isEnabled\t"); if (this.getModel().isRollover()) { System.out.print("isRollover\t"); if (this.getModel().isPressed()) { System.out.print("isPressed\t"); // draw background pattern g2.setColor(new Color(0, 147, 255)); g2.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g2.setPaint(paint); double borderWidth = 2.0f; // 2 pixels g2.fill(new RoundRectangle2D.Double(borderWidth, borderWidth, width - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f)); } else { // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); } } else { System.out.print("Normal\t"); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors); g2.setPaint(paint); g2.fill(shape); } } super.paintComponent(g); } @Override public boolean contains(int x, int y) { return shape.contains(x, y); } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub JButton_Bg_2 frame = new JButton_Bg_2(); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
package com.han; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.RadialGradientPaint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.awt.geom.RoundRectangle2D; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.Painter; import javax.swing.UIDefaults; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.UIManager.LookAndFeelInfo; /** * 使用了Nimbus的个性化组件方法。使用Painter可以保留按钮的HTML特性(因为自己不需要重画 Text)。 * * @see JButton_Bg * @see JButton_Bg_2 * @author HAN * */ @SuppressWarnings("serial") public class JButton_Bg_3 extends JFrame { static JButton button; static JButton buttonBg; static JButton buttonExtended1; static JButton buttonExtended2; static JButton buttonExtended3; public JButton_Bg_3() { for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { if (laf.getName().equals("Nimbus")) { try { UIManager.setLookAndFeel(laf.getClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } Container c = getContentPane(); c.setLayout(new FlowLayout()); button = new JButton("button"); c.add(button); buttonBg = new JButton("button"); c.add(buttonBg); buttonBg.setBackground(Color.blue); buttonExtended1 = new JButtonExtended1("OK"); buttonExtended1.setForeground(Color.GREEN); c.add(buttonExtended1); buttonExtended2 = new JButtonExtended2("<html><u>C</u>ancel</html>"); c.add(buttonExtended2); buttonExtended3 = new JButtonExtended3("Sub"); c.add(buttonExtended3); } private class JButtonExtended1 extends JButton { private Shape shape; JButtonExtended1(String text) { super(text); // 设置按钮默认文本颜色为红色 this.setForeground(Color.RED); // 设置按钮默认区域为正方形 Dimension preferredSize = getPreferredSize(); Dimension preferredSizeNew = new Dimension(preferredSize.width, preferredSize.width); setPreferredSize(preferredSizeNew); /* customize button */ UIDefaults sliderDefaults = new UIDefaults(); sliderDefaults.put("Button.contentMargins", new Insets(6, 14, 6, 14)); sliderDefaults.put("Button[Enabled].backgroundPainter", new Painter<JComponent>() { public void paint(Graphics2D g, JComponent c, int width, int height) { g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); shape = new Ellipse2D.Double( width / 2 - height / 2, 0, height, height); g.fill(shape); } }); sliderDefaults.put("Button[MouseOver].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new Ellipse2D.Double(width / 2 - height / 2, 0, height, height)); } }); sliderDefaults.put("Button[Focused].backgroundPainter", new Painter<JComponent>() { // The paint is the same as MouseOver @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new Ellipse2D.Double(width / 2 - height / 2, 0, height, height)); } }); sliderDefaults.put("Button[Focused+Pressed].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern int offsetCenter = 1; Point2D center = new Point2D.Float(width / 2 + offsetCenter, height / 2 + offsetCenter); float radius = height / 2; float[] dist = { 0.2f, 1.0f }; Color[] colors = { new Color(0, 0, 0, 255), new Color(255, 255, 255, 0) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new Ellipse2D.Double(width / 2 - height / 2 + offsetCenter, offsetCenter, height, height)); } }); this.putClientProperty("Nimbus.Overrides", sliderDefaults); // replace the defaults this.putClientProperty("Nimbus.Overrides.InheritDefaults", false); } @Override public boolean contains(int x, int y) { try { if (shape.contains(x, y)) { return true; } else { return false; } } catch (NullPointerException e) { System.out.println("NullPointerException"); } return super.contains(x, y); } } private class JButtonExtended2 extends JButton { Shape shape; JButtonExtended2(String text) { super(text); /* customize button */ UIDefaults sliderDefaults = new UIDefaults(); // sliderDefaults.put("Button.defaultButtonFollowsFocus", false); sliderDefaults.put("Button.contentMargins", new Insets(6, 14, 6, 14)); sliderDefaults.put("Button[Enabled].backgroundPainter", new Painter<JComponent>() { public void paint(Graphics2D g, JComponent c, int width, int height) { // // Rendering operations have no effect outside of // // the clipping area. // g.setClip(0, 0, height, height); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); g.fill(shape); } }); sliderDefaults.put("Button[MouseOver].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); } }); sliderDefaults.put("Button[Focused].backgroundPainter", new Painter<JComponent>() { // The paint is the same as MouseOver @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); } }); sliderDefaults.put("Button[Focused+Pressed].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); } }); this.putClientProperty("Nimbus.Overrides", sliderDefaults); // replace the defaults this.putClientProperty("Nimbus.Overrides.InheritDefaults", false); } @Override public boolean contains(int x, int y) { try { if (shape.contains(x, y)) { return true; } else { return false; } } catch (NullPointerException e) { System.out.println("NullPointerException"); } return super.contains(x, y); } } private class JButtonExtended3 extends JButton { Shape shape; JButtonExtended3(String text) { super(text); /* customize button */ UIDefaults sliderDefaults = new UIDefaults(); sliderDefaults.put("Button.contentMargins", new Insets(6, 14, 6, 14)); sliderDefaults.put("Button[Enabled].backgroundPainter", new Painter<JComponent>() { public void paint(Graphics2D g, JComponent c, int width, int height) { g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(0, 0, 0, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); shape = new RoundRectangle2D.Double(0, 0, width, height, height, height); g.fill(shape); } }); sliderDefaults.put("Button[MouseOver].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); } }); sliderDefaults.put("Button[Focused].backgroundPainter", new Painter<JComponent>() { // The paint is the same as MouseOver @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 0.8f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); } }); sliderDefaults.put("Button[Focused+Pressed].backgroundPainter", new Painter<JComponent>() { @Override public void paint(Graphics2D g, JComponent object, int width, int height) { // TODO Auto-generated method stub g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // draw background pattern g.setColor(new Color(0, 147, 255)); g.fill(new RoundRectangle2D.Double(0, 0, width, height, height, height)); Point2D center = new Point2D.Float(width / 2, height / 2); float radius = width / 2; float[] dist = { 0.0f, 1.0f }; Color[] colors = { new Color(255, 255, 255, 0), new Color(20, 20, 20, 255) }; RadialGradientPaint paint = new RadialGradientPaint( center, radius, dist, colors); g.setPaint(paint); double borderWidth = 0.0f; // 0 pixels, no border g.fill(new RoundRectangle2D.Double(borderWidth, borderWidth, width - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f, height - borderWidth * 2.0f)); } }); this.putClientProperty("Nimbus.Overrides", sliderDefaults); // replace the defaults this.putClientProperty("Nimbus.Overrides.InheritDefaults", false); } @Override public boolean contains(int x, int y) { try { if (shape.contains(x, y)) { return true; } else { return false; } } catch (NullPointerException e) { System.out.println("NullPointerException"); } return super.contains(x, y); } } public static void main(String[] args) { // TODO Auto-generated method stub JButton_Bg_3 frame = new JButton_Bg_3(); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // If you want to ensure that a particular component gains the focus // the first time a window is activated, you can call the // requestFocusInWindow method on the component after the component // has been realized, but before the frame is displayed. frame.pack(); // Realize the components. // This button will have the initial focus. buttonExtended2.requestFocusInWindow(); frame.setVisible(true);// Display the window. } }