swing自定义组件之BUTTON_第1页
swing自定义组件之BUTTON_第2页
swing自定义组件之BUTTON_第3页
swing自定义组件之BUTTON_第4页
swing自定义组件之BUTTON_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Swing自定义组件之ButtonGUI组件要完成的任务有2个,展现与业务。对于按钮来说,文本、图标、边框、背景属于展现层,而这些元素在按钮不同状态下会不尽相同,一般来说至少有4种状态下的展现:普通、鼠标放在其上、被按下、被禁用,也就是按钮应该具备这4种状态。下面给出的示例是swing实现的自定义按钮。通常swing自定义组件继承javax.swing.JComponent并重写protected void paintComponent(Graphics g方法实现自定义绘制。 重写paintComponent方法时通常要先去掉super.paintComponent(g,因为父方法调用会绘制

2、背景色。不妨先看一下源代码中的调用过程。在JComponent.java中paintComponent(Graphics g方法定义如下: protected void paintComponent(Graphics g if (ui != null Graphics scratchGraphics = (g = null ? null : g.create(;try ui.update(scratchGraphics, this;finally scratchGraphics.dispose(;其中ui的声明如下protected transient ComponentUI ui;然后转向C

3、omponentUI的update(Graphics g, JComponent c方法:public void update(Graphics g, JComponent c if (c.isOpaque( g.setColor(c.getBackground(;g.fillRect(0, 0, c.getWidth(,c.getHeight(;paint(g, c;可见如果发现组件是非透明的,就绘制背景,可以看出swing组件的setBackground方法如何绘制背景的。一般简单的自定义组件,你可以只通过重写paintComponent方法来实现绘制,对于一般的组件这已经足够。对于自定义

4、按钮一般的原则是准备4张背景图对应上述4种状态,这4种状态都可通过鼠标*来感知,当状态改变时,调用repaint(使Button重绘。除了背景,按钮文本、图标等的改变一样也必须调用repaint(来刷新。然后重要的一点是你必须重写public Dimension getPreferredSize(来获得按钮的最佳尺寸。getPreferredSize方法对于布局管理器来说至关重要,布局管理器会通过getPreferredSize的判断组件的最佳大小,并进行布局。而对于本范例而言,getPreferredSize的大小只和背景图片大小有关。对于业务,尽量做到前台界面与后来业务分离。你可以自定义按

5、钮动作*器来实现,本例是沿用swing的Action实现,当鼠标抬起时,构造一个ActionEvent对象,然后交给Action成员的actionPerformed(ActionEvent e处理。代码如下:/* Created on 2007年11月11日, 下午6:30* To change this template, choose Tools | Template Manager* and open the template in the editor.*/package demo.swing;import java.awt.AlphaComposite;import java.awt

6、.Color;import java.awt.Container;import java.awt.Dimension;import java.awt.Font;import java.awt.FontMetrics;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.RenderingHints;import java.awt.Shape;import java.awt.event.ActionEvent;import java.awt.event.MouseEvent;import java.awt.font

7、.TextAttribute;import java.awt.font.TextLayout;import java.awt.geom.AffineTransform;import java.util.HashMap;import javax.swing.Action;import javax.swing.Icon;import javax.swing.JComponent;import javax.swing.SwingConstants;import javax.swing.SwingUtilities;import javax.swing.event.MouseInputListener

8、;/* 为需要具备专业外观的按钮提供方便的实现。通过此类提供的若干方法可轻松实现专业外观。* author 电玩*/public final class ImageButton extends JComponent implementsMouseInputListener /* 通常状态下的背景图片*/private Icon backgroundImage;/* 通常状态下的最佳尺寸*/private Dimension preferredSize;/* 鼠标光标在上方时的背景图片*/private Icon rolloverBackgroundImage;/* 鼠标光标在上方时的最佳尺寸*

9、/private Dimension rolloverPreferredSize;/* 按钮被按下时的背景图片*/private Icon pressedBackgroundImage;/* 按钮被按下时的最佳尺寸*/private Dimension pressedPreferredSize;/* 按钮被禁止时的背景图片*/private Icon disabledBackgroundImage;/* 按钮被禁止时的最佳尺寸*/private Dimension disabledPreferredSize;/* 当前按钮的最佳尺寸*/private volatile Dimension cu

10、rrentSize;/* 通常状态下按钮的图标*/private Icon icon;/* 按钮被禁止时的图标*/private Icon disabledIcon;/* 按钮图标出现的位置*/private IconOrientation iconOrientation = IconOrientation.WEST;/* 按钮的默认尺寸*/private static final Dimension DEFAULT_SIZE = new Dimension(100, 25;/* 水平偏移量*/private int horizontalOffset = DEFAULT_HORIZONTAL_

11、OFFSET;/* 默认的水平偏移量*/private static final int DEFAULT_HORIZONTAL_OFFSET = 4;/* 垂直偏移量*/private int verticalOffset = DEFALUT_VERTICAL_OFFSET;/* 默认的垂直偏移量*/private static final int DEFALUT_VERTICAL_OFFSET = 2;/* 显示在按钮上的文字*/private String text;/* 按钮文本的字体*/private Font font;/* 按钮文本的默认字体*/private static fin

12、al Font DEFAULT_FONT = Font.decode("Dialog-Plain-14"/* 按钮被禁止时候文字的颜色*/private Color disabledForeground;/* 默认的按钮被禁止时文本的颜色*/private final Color DEFAULT_DISABLED_FOREGROUND = new Color(192, 192, 192;/* 按钮的状态*/private volatile Status status = Status.DEFAULT;/* 按钮的颜色透明度*/private volatile float a

13、lpha = 1.0f;private static HashMap< RenderingHints.Key, Object> renderingHints;/* 按钮执行的动作*/private Action action;static renderingHints = new HashMap(;renderingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY;renderingHints.put(RenderingHints.KEY

14、_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON;renderingHints.put(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY;renderingHints.put(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_DISABLE;renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS,RenderingHints.V

15、ALUE_FRACTIONALMETRICS_ON;renderingHints.put(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC ;renderingHints.put(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_PURE;renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_

16、ON;/* 创建一个ImageButton按钮的实例 */public ImageButton( currentSize = DEFAULT_SIZE;addMouseListener(this;addMouseMotionListener(this;/* 设置常规状态下按钮的背景。调用该方法会影响到按钮在常规状态下的最佳尺寸,* 由传入的图标参数对应的图标尺寸决定* param backgroundImage 常规状态下背景图标对象* throws java.lang.IllegalArgumentException 如果传入的参数为null*/public void setBackgrou

17、ndImage(Icon backgroundImage throws IllegalArgumentException if (backgroundImage = null throw new IllegalArgumentException("backgroundImage can't be null"this.backgroundImage = backgroundImage;preferredSize = new Dimension(backgroundImage.getIconWidth(,backgroundImage.getIconHeight(;cu

18、rrentSize = preferredSize;/* 设置被禁用状态下按钮的背景。调用该方法会影响到按钮在禁用状态下的最佳尺寸,* 由传入的图标参数对应的图标尺寸决定* param disabledBackgroundImage 禁用状态下背景图标对象* throws java.lang.IllegalArgumentException 如果传入的参数为null*/public void setDisabledBackgroundImage(Icon disabledBackgroundImage throws IllegalArgumentException if (disabledBa

19、ckgroundImage = null throw new IllegalArgumentException("disabledBackgroundImage can't be null"this.disabledBackgroundImage = disabledBackgroundImage;disabledPreferredSize = new Dimension(disabledBackgroundImage.getIconWidth(, disabledBackgroundImage.getIconHeight(;/* 设置在被按下状态时按钮的背景。调用

20、该方法会影响到按钮在被按下状态时的最佳尺寸,* 由传入的图标参数对应的图标尺寸决定* param pressedBackgroundImage 被按下时的背景图标对象* throws java.lang.IllegalArgumentException 如果传入的参数为null*/public void setPressedBackgroundImage(Icon pressedBackgroundImagethrows IllegalArgumentException if (pressedBackgroundImage = null throw new IllegalArgumentExc

21、eption("pressedBackgroundImage can't be null"this.pressedBackgroundImage = pressedBackgroundImage;pressedPreferredSize = new Dimension(pressedBackgroundImage.getIconWidth(, pressedBackgroundImage.getIconHeight(;/* 设置鼠标指针在其上方时按钮的背景。调用该方法会影响到按钮在鼠标指针在其上方* 时的最佳尺寸,由传入的图标参数对应的图标尺寸决定* param r

22、olloverBackgroundImage 鼠标指针在其上方时的背景图标对象* throws java.lang.IllegalArgumentException 如果传入的参数为null*/public void setRolloverBackgroundImage(Icon rolloverBackgroundImage throws IllegalArgumentException if (rolloverBackgroundImage = null throw new IllegalArgumentException("rolloverBackgroundImage can

23、't be null"this.rolloverBackgroundImage = rolloverBackgroundImage;rolloverPreferredSize = new Dimension(rolloverBackgroundImage.getIconWidth(, rolloverBackgroundImage.getIconHeight(;/* 设置水平偏移量。* param horizontalOffset 水平偏移量* throws java.lang.IllegalArgumentException 如果参数小于0,抛出此异常*/public vo

24、id setHorizontalOffset(int horizontalOffset throws IllegalArgumentExceptionif(horizontalOffset < 0 throw new IllegalArgumentException("horizontalOffset must >=0"this.horizontalOffset = horizontalOffset;/* 设置垂直偏移量* param verticalOffset 垂直偏移量* throws java.lang.IllegalArgumentException

25、如果参数小于0,抛出此异常*/public void setVerticalOffset(int verticalOffset throws IllegalArgumentExceptionif(verticalOffset < 0 throw new IllegalArgumentException("verticalOffset must >=0"this.verticalOffset = verticalOffset;/* 设置按钮的图标* param icon 图标对象* throws java.lang.IllegalArgumentException

26、 如果传入的参数为null,抛出此异常*/public synchronized void setIcon(Icon icon throws IllegalArgumentException if(icon = null throw new IllegalArgumentException("icon can't be null"this.icon = icon;/* 设置按钮在被禁用时显示的图标* param disabledIcon 图标对象* throws java.lang.IllegalArgumentException 如果传入的参数为null,抛出此异

27、常*/public synchronized void setDisabledIcon(Icon disabledIcon throws IllegalArgumentException if(disabledIcon = null throw new IllegalArgumentException("disabledIcon can't be null"this.disabledIcon = disabledIcon;public void setIconOrientation(IconOrientation iconOrientation throws Ill

28、egalArgumentExceptionif(iconOrientation = null throw new IllegalArgumentException("iconOrientation can't be null"this.iconOrientation = iconOrientation;public void setDisabledForeground(Color disabledForeground this.disabledForeground = disabledForeground;/* 设置按钮的透明度*/public synchroniz

29、ed void setAlpha(float alphathrows IllegalArgumentExceptionif (alpha < 0f | alpha > 1.0f throw new IllegalArgumentException("alpha value must between 0.0 and 1.0"this.alpha = alpha;repaint(;/* 设置按钮显示的文本* param text 显示的文本字符串*/public synchronized void setText(String text if (text != nu

30、ll this.text = text;repaint(;/* 返回按钮的当前字体,如果之前没有设置字体,则返回默认字体* return 按钮的当前字体*/public Font getFont( if(font = null return DEFAULT_FONT;return font;/* 设置按钮的当前字体* param font 字体实例*/public void setFont(Font font this.font = font;super.setFont(font;/* 指定这个按钮的动作* param action 按钮的动作*/public void setAction(A

31、ction action this.action = action;/* 覆盖JComponent.setEnabled(boolean enabled,设置是否按钮可用或被禁止* param enabled 如果按钮可用则为true,否则为false* see java.awt.Component#isEnabled*/Overridepublic void setEnabled(boolean enabled super.setEnabled(enabled;if (isEnabled( != enabled if (disabledPreferredSize != null&&a

32、mp; !disabledPreferredSize.equals(currentSize currentSize = disabledPreferredSize;revalidate(;/* 绘制按钮边框* param g 图形上下文* deprecated 此方法只在内部被调用,外部不要显式调用*/Overrideprotected void paintBorder(Graphics g /* 绘制子组件* param g 图形上下文* deprecated 此方法只在内部被调用,外部不要显式调用*/Overrideprotected void paintChildren(Graphics

33、 g /* 绘制按钮* param g 图形上下文* deprecated 此方法只在内部被调用,外部不要显式调用*/Overrideprotected void paintComponent(Graphics g Graphics2D g2d = (Graphics2D g.create(;g2d.addRenderingHints(renderingHints;if(alpha < 1.0f g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha;drawBackgroundImage(g2d

34、;drawIcon(g2d;drawText(g2d;g2d.dispose(;private void drawIcon(final Graphics2D g2d Icon currentIcon = isEnabled( ? icon : disabledIcon;if(currentIcon = null return;int w = currentIcon.getIconWidth(;int h = currentIcon.getIconHeight(;int offsetX = 0;int offsetY = 0;switch (iconOrientation case WEST:o

35、ffsetX = horizontalOffset;offsetY = getHeight( / 2 - h / 2;break;case EAST:offsetX = getWidth( - horizontalOffset - w;offsetY = getHeight( / 2 - h / 2;break;case NORTH:offsetX = getWidth( / 2 - w / 2;offsetY = verticalOffset;break;case SOUTH:offsetX = getWidth( / 2 - w / 2;offsetY = getHeight( - ver

36、ticalOffset - h;break;case NORTH_WEST:offsetX = horizontalOffset;offsetY = verticalOffset;break;case NORTH_EAST:offsetX = getWidth( - horizontalOffset - w;offsetY = verticalOffset;break;case SOUTH_WEST:offsetX = horizontalOffset;offsetY = getHeight( - verticalOffset - h;break;case SOUTH_EAST:offsetX

37、 = getWidth( - horizontalOffset - w;offsetY = getHeight( - verticalOffset - h;break;case CENTER:offsetX = getWidth( / 2 - w / 2;offsetY = getHeight( / 2 - h / 2;break;currentIcon.paintIcon(this,g2d,offsetX,offsetY;private void drawBackgroundImage(final Graphics2D g2d if (!isEnabled( if (disabledBack

38、groundImage != null disabledBackgroundImage.paintIcon(this, g2d, 0, 0;return;switch (status case ROLLOVER:if (rolloverBackgroundImage != null rolloverBackgroundImage.paintIcon(this, g2d, 0, 0; else if (backgroundImage != null backgroundImage.paintIcon(this, g2d, 0, 0;break;case PRESSED:if (pressedBa

39、ckgroundImage != null pressedBackgroundImage.paintIcon(this, g2d, 0, 0; else if (backgroundImage != null backgroundImage.paintIcon(this, g2d, 0, 0;break;case PRESSED_EXIT:default:if (backgroundImage != null backgroundImage.paintIcon(this, g2d, 0, 0;break;private void drawText(final Graphics2D g2d if

40、(text = null | text.isEmpty( return;Font font = getFont(;FontMetrics fm = getFontMetrics(font;TextLayout textLayout = new TextLayout(text, font, g2d.getFontRenderContext(;AffineTransform affineTransform = AffineTransform.getTranslateInstance(getWidth( - fm.stringWidth(text / 2,getHeight( / 2 + fm.ge

41、tHeight( / 4;Shape textShape = textLayout.getOutline(affineTransform;if(isEnabled( g2d.setPaint(getForeground(; else g2d.setPaint(disabledForeground != null ? disabledForeground: DEFAULT_DISABLED_FOREGROUND;g2d.fill(textShape;g2d.draw(textShape;/* 鼠标单击事件的处理* param e 鼠标事件* deprecated 此方法只在内部被调用,外部不要显

42、式调用*/public void mouseClicked(MouseEvent e /* 按钮按下时的处理* param e 鼠标事件* deprecated 此方法只在内部被调用,外部不要显式调用*/public void mousePressed(MouseEvent e if (!isEnabled( return; else if(!SwingUtilities.isLeftMouseButton(e return;status = Status.PRESSED;repaint(;if (pressedPreferredSize != null&& !pressedP

43、referredSize.equals(currentSize currentSize = pressedPreferredSize;revalidate(;/* 鼠标抬起时的处理* param e 鼠标事件* deprecated 此方法只在内部被调用,外部不要显式调用*/public void mouseReleased(MouseEvent e if (!isEnabled( return; else if(!SwingUtilities.isLeftMouseButton(e return;if (e.getX( > 0 && e.getY( > 0 &am

44、p;& e.getX( < getPreferredSize(.width&& e.getY( < getPreferredSize(.height status = Status.ROLLOVER;if (rolloverPreferredSize != null&& !rolloverPreferredSize.equals(currentSize currentSize = rolloverPreferredSize;try doAction(e; catch (Exception ex ex.printStackTrace(; else status = Status.DEFAULT;if (preferredSize != null && !preferredSize.equals(currentSize currentSize = preferredSize;repaint(;revalidate(;/* 鼠标进入时的处理* param e 鼠标事件* deprecated 此方法只在内部被调用,外部不要显式调用*/public void mouseEntered(MouseEvent e if (!isEnabled( r

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论