Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 576|回复: 0

[Swing学习]Swing自定义组件之Button

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-11 23:57:16 | 显示全部楼层 |阅读模式
    GUI组件要完成的任务有2个,展现与业务。对于按钮来说,文本、图标、边框、背景属于展现层,而这些元素在按钮不同状态下会不尽相同,一般来说至少有4种状态下的展现:普通、鼠标放在其上、被按下、被禁用,也就是按钮应该具备这4种状态。

    下面给出的示例是swing实现的自定义按钮。

          通常swing自定义组件继承javax.swing.JComponent并重写protected void paintComponent(Graphics g)方法实现自定义绘制。 重写paintComponent方法时通常要先去掉super.paintComponent(g),因为父方法调用会绘制背景色。不妨先看一下源代码中的调用过程。

           在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;
    然后转向ComponentUI的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种状态都可通过鼠标监听来感知,当状态改变时,调用repaint()使Button重绘。除了背景,按钮文本、图标等的改变一样也必须调用repaint()来刷新。

          然后重要的一点是你必须重写public Dimension getPreferredSize()来获得按钮的最佳尺寸。getPreferredSize方法对于布局管理器来说至关重要,布局管理器会通过getPreferredSize的判断组件的最佳大小,并进行布局。而对于本范例而言,getPreferredSize的大小只和背景图片大小有关。

          对于业务,尽量做到前台界面与后来业务分离。你可以自定义按钮动作监听器来实现,本例是沿用swing的Action实现,当鼠标抬起时,构造一个ActionEvent对象,然后交给Action成员的actionPerformed(ActionEvent e)处理。

    代码如下:
    1. /*
    2. * ImageButton.java
    3. *
    4. * Created on 2007年11月11日, 下午6:30
    5. *
    6. * To change this template, choose Tools | Template Manager
    7. * and open the template in the editor.
    8. */
    9. package demo.swing;
    10. import java.awt.AlphaComposite;
    11. import java.awt.Color;
    12. import java.awt.Container;
    13. import java.awt.Dimension;
    14. import java.awt.Font;
    15. import java.awt.FontMetrics;
    16. import java.awt.Graphics;
    17. import java.awt.Graphics2D;
    18. import java.awt.RenderingHints;
    19. import java.awt.Shape;
    20. import java.awt.event.ActionEvent;
    21. import java.awt.event.MouseEvent;
    22. import java.awt.font.TextAttribute;
    23. import java.awt.font.TextLayout;
    24. import java.awt.geom.AffineTransform;
    25. import java.util.HashMap;
    26. import javax.swing.Action;
    27. import javax.swing.Icon;
    28. import javax.swing.JComponent;
    29. import javax.swing.SwingConstants;
    30. import javax.swing.SwingUtilities;
    31. import javax.swing.event.MouseInputListener;
    32. /**
    33. * 为需要具备专业外观的按钮提供方便的实现。通过此类提供的若干方法可轻松实现专业外观。
    34. * @author 电玩
    35. */
    36. public final class ImageButton extends JComponent implements
    37.         MouseInputListener {
    38.     /**
    39.      * 通常状态下的背景图片
    40.      */
    41.     private Icon backgroundImage;
    42.    
    43.     /**
    44.      * 通常状态下的最佳尺寸
    45.      */
    46.     private Dimension preferredSize;
    47.    
    48.     /**
    49.      * 鼠标光标在上方时的背景图片
    50.      */
    51.     private Icon rolloverBackgroundImage;
    52.    
    53.     /**
    54.      * 鼠标光标在上方时的最佳尺寸
    55.      */
    56.     private Dimension rolloverPreferredSize;
    57.    
    58.     /**
    59.      * 按钮被按下时的背景图片
    60.      */
    61.     private Icon pressedBackgroundImage;
    62.    
    63.     /**
    64.      * 按钮被按下时的最佳尺寸
    65.      */
    66.     private Dimension pressedPreferredSize;
    67.    
    68.     /**
    69.      * 按钮被禁止时的背景图片
    70.      */
    71.     private Icon disabledBackgroundImage;
    72.    
    73.     /**
    74.      * 按钮被禁止时的最佳尺寸
    75.      */
    76.     private Dimension disabledPreferredSize;
    77.    
    78.     /**
    79.      * 当前按钮的最佳尺寸
    80.      */
    81.     private volatile Dimension currentSize;
    82.    
    83.     /**
    84.      * 通常状态下按钮的图标
    85.      */
    86.     private Icon icon;
    87.    
    88.     /**
    89.      * 按钮被禁止时的图标
    90.      */
    91.     private Icon disabledIcon;
    92.    
    93.     /**
    94.      * 按钮图标出现的位置
    95.      */
    96.     private IconOrientation iconOrientation = IconOrientation.WEST;
    97.    
    98.     /**
    99.      * 按钮的默认尺寸
    100.      */
    101.     private static final Dimension DEFAULT_SIZE = new Dimension(100, 25);
    102.    
    103.     /**
    104.      * 水平偏移量
    105.      */
    106.     private int horizontalOffset = DEFAULT_HORIZONTAL_OFFSET;
    107.     /**
    108.      * 默认的水平偏移量
    109.      */
    110.     private static final int DEFAULT_HORIZONTAL_OFFSET = 4;
    111.    
    112.     /**
    113.      * 垂直偏移量
    114.      */
    115.     private int verticalOffset = DEFALUT_VERTICAL_OFFSET;
    116.    
    117.     /**
    118.      * 默认的垂直偏移量
    119.      */
    120.     private static final int DEFALUT_VERTICAL_OFFSET = 2;
    121.    
    122.     /**
    123.      * 显示在按钮上的文字
    124.      */
    125.     private String text;
    126.    
    127.     /**
    128.      * 按钮文本的字体
    129.      */
    130.     private Font font;
    131.    
    132.     /**
    133.      * 按钮文本的默认字体
    134.      */
    135.     private static final Font DEFAULT_FONT = Font.decode("Dialog-Plain-14");
    136.    
    137.     /**
    138.      * 按钮被禁止时候文字的颜色
    139.      */
    140.     private Color disabledForeground;
    141.    
    142.     /**
    143.      * 默认的按钮被禁止时文本的颜色
    144.      */
    145.     private final Color DEFAULT_DISABLED_FOREGROUND = new Color(192, 192, 192);
    146.    
    147.     /**
    148.      * 按钮的状态
    149.      */
    150.     private volatile Status status = Status.DEFAULT;
    151.    
    152.     /**
    153.      * 按钮的颜色透明度
    154.      */
    155.     private volatile float alpha = 1.0f;
    156.    
    157.     private static HashMap< RenderingHints.Key, Object> renderingHints;
    158.    
    159.     /**
    160.      * 按钮执行的动作
    161.      */
    162.     private Action action;
    163.    
    164.     static {
    165.         renderingHints = new HashMap();
    166.         renderingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
    167.                 RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
    168.         renderingHints.put(RenderingHints.KEY_ANTIALIASING,
    169.                 RenderingHints.VALUE_ANTIALIAS_ON);
    170.         renderingHints.put(RenderingHints.KEY_COLOR_RENDERING,
    171.                 RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    172.         renderingHints.put(RenderingHints.KEY_DITHERING,
    173.                 RenderingHints.VALUE_DITHER_DISABLE);
    174.         renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
    175.                 RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    176.         renderingHints.put(RenderingHints.KEY_INTERPOLATION,
    177.                 RenderingHints.VALUE_INTERPOLATION_BICUBIC );
    178.         renderingHints.put(RenderingHints.KEY_STROKE_CONTROL,
    179.                 RenderingHints.VALUE_STROKE_PURE);
    180.         renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
    181.                 RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    182.     }
    183.    
    184.     /** 创建一个ImageButton按钮的实例 */
    185.     public ImageButton() {
    186.         currentSize = DEFAULT_SIZE;
    187.         addMouseListener(this);
    188.         addMouseMotionListener(this);
    189.     }
    190.    
    191.     /**
    192.      * 设置常规状态下按钮的背景。调用该方法会影响到按钮在常规状态下的最佳尺寸,
    193.      * 由传入的图标参数对应的图标尺寸决定
    194.      * @param backgroundImage 常规状态下背景图标对象
    195.      * @throws java.lang.IllegalArgumentException 如果传入的参数为null
    196.      */
    197.     public void setBackgroundImage(Icon backgroundImage) throws IllegalArgumentException {
    198.         if (backgroundImage == null) {
    199.             throw new IllegalArgumentException("backgroundImage can"t be null");
    200.         }
    201.         this.backgroundImage = backgroundImage;
    202.         preferredSize = new Dimension(backgroundImage.getIconWidth(),
    203.                 backgroundImage.getIconHeight());
    204.         currentSize = preferredSize;
    205.     }
    206.    
    207.     /**
    208.      * 设置被禁用状态下按钮的背景。调用该方法会影响到按钮在禁用状态下的最佳尺寸,
    209.      * 由传入的图标参数对应的图标尺寸决定
    210.      * @param disabledBackgroundImage 禁用状态下背景图标对象
    211.      * @throws java.lang.IllegalArgumentException 如果传入的参数为null
    212.      */
    213.     public void setDisabledBackgroundImage(Icon disabledBackgroundImage) throws IllegalArgumentException {
    214.         if (disabledBackgroundImage == null) {
    215.             throw new IllegalArgumentException(
    216.                     "disabledBackgroundImage can"t be null");
    217.         }
    218.         this.disabledBackgroundImage = disabledBackgroundImage;
    219.         disabledPreferredSize = new Dimension(disabledBackgroundImage
    220.                 .getIconWidth(), disabledBackgroundImage.getIconHeight());
    221.     }
    222.    
    223.     /**
    224.      * 设置在被按下状态时按钮的背景。调用该方法会影响到按钮在被按下状态时的最佳尺寸,
    225.      * 由传入的图标参数对应的图标尺寸决定
    226.      * @param pressedBackgroundImage 被按下时的背景图标对象
    227.      * @throws java.lang.IllegalArgumentException 如果传入的参数为null
    228.      */
    229.     public void setPressedBackgroundImage(Icon pressedBackgroundImage)throws IllegalArgumentException {
    230.         if (pressedBackgroundImage == null) {
    231.             throw new IllegalArgumentException(
    232.                     "pressedBackgroundImage can"t be null");
    233.         }
    234.         this.pressedBackgroundImage = pressedBackgroundImage;
    235.         pressedPreferredSize = new Dimension(pressedBackgroundImage
    236.                 .getIconWidth(), pressedBackgroundImage.getIconHeight());
    237.     }
    238.     /**
    239.      * 设置鼠标指针在其上方时按钮的背景。调用该方法会影响到按钮在鼠标指针在其上方
    240.      * 时的最佳尺寸,由传入的图标参数对应的图标尺寸决定
    241.      * @param rolloverBackgroundImage 鼠标指针在其上方时的背景图标对象
    242.      * @throws java.lang.IllegalArgumentException 如果传入的参数为null
    243.      */
    244.     public void setRolloverBackgroundImage(Icon rolloverBackgroundImage) throws IllegalArgumentException {
    245.         if (rolloverBackgroundImage == null) {
    246.             throw new IllegalArgumentException(
    247.                     "rolloverBackgroundImage can"t be null");
    248.         }
    249.         this.rolloverBackgroundImage = rolloverBackgroundImage;
    250.         rolloverPreferredSize = new Dimension(rolloverBackgroundImage
    251.                 .getIconWidth(), rolloverBackgroundImage.getIconHeight());
    252.     }
    253.    
    254.     /**
    255.      * 设置水平偏移量。
    256.      * @param horizontalOffset 水平偏移量
    257.      * @throws java.lang.IllegalArgumentException 如果参数小于0,抛出此异常
    258.      */
    259.     public void setHorizontalOffset(int horizontalOffset) throws IllegalArgumentException{
    260.         if(horizontalOffset < 0) {
    261.             throw new IllegalArgumentException("horizontalOffset must >=0");
    262.         }
    263.         this.horizontalOffset = horizontalOffset;
    264.     }
    265.    
    266.     /**
    267.      * 设置垂直偏移量
    268.      * @param verticalOffset 垂直偏移量
    269.      * @throws java.lang.IllegalArgumentException 如果参数小于0,抛出此异常
    270.      */
    271.     public void setVerticalOffset(int verticalOffset) throws IllegalArgumentException{
    272.         if(verticalOffset < 0) {
    273.             throw new IllegalArgumentException("verticalOffset must >=0");
    274.         }
    275.         this.verticalOffset = verticalOffset;
    276.     }
    277.    
    278.     /**
    279.      * 设置按钮的图标
    280.      * @param icon 图标对象
    281.      * @throws java.lang.IllegalArgumentException 如果传入的参数为null,抛出此异常
    282.      */
    283.     public synchronized void setIcon(Icon icon) throws IllegalArgumentException {
    284.         if(icon == null) {
    285.             throw new IllegalArgumentException(
    286.                     "icon can"t be null");
    287.         }
    288.         this.icon = icon;
    289.     }
    290.    
    291.     /**
    292.      * 设置按钮在被禁用时显示的图标
    293.      * @param disabledIcon 图标对象
    294.      * @throws java.lang.IllegalArgumentException 如果传入的参数为null,抛出此异常
    295.      */
    296.     public synchronized void setDisabledIcon(Icon disabledIcon) throws IllegalArgumentException {
    297.         if(disabledIcon == null) {
    298.             throw new IllegalArgumentException(
    299.                     "disabledIcon can"t be null");
    300.         }
    301.         this.disabledIcon = disabledIcon;
    302.     }
    303.    
    304.     public void setIconOrientation(IconOrientation iconOrientation) throws IllegalArgumentException{
    305.         if(iconOrientation == null) {
    306.             throw new IllegalArgumentException(
    307.                     "iconOrientation can"t be null");
    308.         }
    309.         this.iconOrientation = iconOrientation;
    310.     }
    311.    
    312.     public void setDisabledForeground(Color disabledForeground) {
    313.         this.disabledForeground = disabledForeground;
    314.     }
    315.    
    316.     /**
    317.      * 设置按钮的透明度
    318.      * @param alpha 透明度。范围在0.0f~1.0f之间。0.0f为完全透明,1.0f为完全显示
    319.      * @throws java.lang.IllegalArgumentException 如果不在0.0f~1.0f之间会抛出此异常
    320.      */
    321.     public synchronized void setAlpha(float alpha)throws IllegalArgumentException{
    322.         if (alpha < 0f || alpha > 1.0f) {
    323.             throw new IllegalArgumentException(
    324.                     "alpha value must between 0.0 and 1.0");
    325.         }
    326.         this.alpha = alpha;
    327.         repaint();
    328.     }
    329.    
    330.     /**
    331.      * 设置按钮显示的文本
    332.      * @param text 显示的文本字符串
    333.      */
    334.     public synchronized  void setText(String text) {
    335.         if (text != null) {
    336.             this.text = text;
    337.             repaint();
    338.         }
    339.     }
    340.    
    341.     /**
    342.      * 返回按钮的当前字体,如果之前没有设置字体,则返回默认字体
    343.      * @return 按钮的当前字体
    344.      */
    345.     public Font getFont() {
    346.         if(font == null) {
    347.             return DEFAULT_FONT;
    348.         }
    349.         return font;
    350.     }
    351.    
    352.     /**
    353.      * 设置按钮的当前字体
    354.      * @param font 字体实例
    355.      */
    356.     public void setFont(Font font) {
    357.         this.font = font;
    358.         super.setFont(font);
    359.     }
    360.     /**
    361.      * 指定这个按钮的[code]动作
    复制代码

         * @param action 按钮的
    1. 动作
    复制代码

         */
        public void setAction(Action action) {
            this.action = action;
        }
       
        /**
         * 覆盖
    1. JComponent.setEnabled(boolean enabled)
    复制代码
    ,设置是否按钮可用或被禁止
         * @param enabled 如果按钮可用则为true,否则为false
         * @see java.awt.Component#isEnabled
         */
        @Override
        public void setEnabled(boolean enabled) {
            super.setEnabled(enabled);
            if (isEnabled() != enabled) {
                if (disabledPreferredSize != null
                        && !disabledPreferredSize.equals(currentSize)) {
                    currentSize = disabledPreferredSize;
                    revalidate();
                }
            }
        }
       
        /**
         * 绘制按钮边框
         * @param g 图形上下文
         * @deprecated 此方法只在内部被调用,外部不要显式调用
         */
        @Override
        protected void paintBorder(Graphics g) {
            
        }
        /**
         * 绘制子组件
         * @param g 图形上下文
         * @deprecated 此方法只在内部被调用,外部不要显式调用
         */
        @Override
        protected void paintChildren(Graphics g) {
            
        }
        /**
         * 绘制按钮
         * @param g 图形上下文
         * @deprecated 此方法只在内部被调用,外部不要显式调用
         */
        @Override
        protected 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);
            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:
                    offsetX = 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() - verticalOffset - 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 = 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 (disabledBackgroundImage != 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 (pressedBackgroundImage != 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(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.getHeight() / 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 此方法只在内部被调用,外部不要显式调用
         */
        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
                    && !pressedPreferredSize.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 && 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()) {
                return;
            }
            status = (status == Status.PRESSED_EXIT) ? Status.PRESSED
                    : Status.ROLLOVER;
            repaint();
            if (rolloverPreferredSize != null
                    && !rolloverPreferredSize.equals(currentSize)) {
                currentSize = rolloverPreferredSize;
                revalidate();
            }
        }
       
        /**
         * 鼠标离开时的处理
         * @param e 鼠标事件
         * @deprecated 此方法只在内部被调用,外部不要显式调用
         */
        public void mouseExited(MouseEvent e) {
            if (!isEnabled()) {
                return;
            }
            status = (status == Status.PRESSED) ? Status.PRESSED_EXIT
                    : Status.DEFAULT;
            repaint();
            if (preferredSize != null && !preferredSize.equals(currentSize)) {
                currentSize = preferredSize;
                revalidate();
            }
        }
       
        /**
         * 鼠标拖拽时的处理
         * @param e 鼠标事件
         * @deprecated 此方法只在内部被调用,外部不要显式调用
         */
        public void mouseDragged(MouseEvent e) {
        }
       
        /**
         * 鼠标在按钮上方移动时的处理
         * @param e 鼠标事件
         * @deprecated 此方法只在内部被调用,外部不要显式调用
         */
        public void mouseMoved(MouseEvent e) {
        }
       
        /**
         * 执行按钮的动作
         * @param e 鼠标事件
         * @throws java.lang.Exception 如果执行的业务代码抛出的异常
         */
        private void doAction(MouseEvent e) throws Exception{
            if (!isEnabled()) {
                return;
            }
            if (action != null) {
                ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), "", e
                        .getWhen(), e.getModifiers());
                action.actionPerformed(ae);
            }
        }
       
        /**
         * 返回当前鼠标状态的最佳尺寸。这个值是不固定的,随着鼠标针对按钮的不同状态这个值会随时
         * 改变,一般地这个方法只被布局管理器所调用。
         * @return 当前鼠标状态的最佳尺寸
         */
        @Override
        public Dimension getPreferredSize() {
            return currentSize;
        }
       
        /**
         * 按钮各个状态的枚举
         *
         * @author 刘一童
         *
         */
        private enum Status {
            /**
             * 默认状态
             */
            DEFAULT,
            /**
             * 鼠标移动到按钮之上
             */
            ROLLOVER,
            /**
             * 在按钮上按下鼠标左键
             */
            PRESSED,
            /**
             * 在按钮上按下鼠标左键后鼠标光标移开按钮区域
             */
            PRESSED_EXIT;
        }
       
        /**
         * 图标在按钮上出现位置的枚举,此按钮只允许放置一个图标,这也符合大多数按钮的规范。
         * @author 刘一童
         */
        public enum IconOrientation {
            /**
             * 图标位于按钮的正左
             */
            WEST,
            /**
             * 图标位于按钮的正北
             */
            NORTH,
            /**
             * 图标位于按钮的正右
             */
            EAST,
            /**
             * 图标位于按钮的正南
             */
            SOUTH,
            /**
             * 图标位于按钮的左上方
             */
            NORTH_WEST,
            /**
             * 图标位于按钮的左下方
             */
            SOUTH_WEST,
            /**
             * 图标位于按钮的右上方
             */
            NORTH_EAST,
            /**
             * 图标位于按钮的右下方
             */
            SOUTH_EAST,
            /**
             * 图标位于按钮的中心
             */
            CENTER;
        }
    }[/code]


      
      
       
       

         
       

         
       
      
    复制代码

    源码下载:http://file.javaxxz.com/2014/11/11/235716281.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 08:02 , Processed in 0.358817 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表