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入门到精通教程
查看: 852|回复: 0

[Swing学习]学习Java7中的一个新的类,JLayer

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

    [LV.1]初来乍到

    发表于 2014-11-17 23:57:51 | 显示全部楼层 |阅读模式
    java7中的一个新的类,JLayer。 JLayer主要用于装饰Swing组件。你可以用它改变如何绘制组件,以及它们如何响应事件。下面是这个类的一个简单的例子: 先看运行结果: 1、鼠标进入登陆框时:聚光灯效果(Spotlight)

    2、点击登录按钮:


    3、代码:
    1.     import java.awt.AWTEvent;  
    2.     import java.awt.AlphaComposite;  
    3.     import java.awt.BasicStroke;  
    4.     import java.awt.Color;  
    5.     import java.awt.Composite;  
    6.     import java.awt.Font;  
    7.     import java.awt.Graphics;  
    8.     import java.awt.Graphics2D;  
    9.     import java.awt.Image;  
    10.     import java.awt.Point;  
    11.     import java.awt.RadialGradientPaint;  
    12.     import java.awt.RenderingHints;  
    13.     import java.awt.event.ActionEvent;  
    14.     import java.awt.event.ActionListener;  
    15.     import java.awt.event.FocusAdapter;  
    16.     import java.awt.event.FocusEvent;  
    17.     import java.awt.event.ItemEvent;  
    18.     import java.awt.event.ItemListener;  
    19.     import java.awt.event.MouseEvent;  
    20.     import java.beans.PropertyChangeEvent;  
    21.     import javax.swing.ImageIcon;  
    22.     import javax.swing.JButton;  
    23.     import javax.swing.JCheckBox;  
    24.     import javax.swing.JComponent;  
    25.     import javax.swing.JFrame;  
    26.     import javax.swing.JLabel;  
    27.     import javax.swing.JLayer;  
    28.     import javax.swing.JPanel;  
    29.     import javax.swing.JPasswordField;  
    30.     import javax.swing.JTextField;  
    31.     import javax.swing.SwingUtilities;  
    32.     import javax.swing.Timer;  
    33.     import javax.swing.UIManager;  
    34.     import javax.swing.plaf.LayerUI;  
    35.     /**
    36.      * @author http://blog.csdn.net/Cannel_2020
    37.      *
    38.      */  
    39.     public class TestJLayer {  
    40.         private static JFrame loginFrame;  
    41.         private LoginLayerUI layerUI;//LayerUI的一个子类  
    42.         public static void main(String[] args) {  
    43.             try {  
    44.                 UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");     
    45.             } catch (Exception e) {  
    46.                 e.printStackTrace();  
    47.             }  
    48.               
    49.             javax.swing.SwingUtilities.invokeLater(new Runnable() {  
    50.                 public void run() {  
    51.                     new TestJLayer().createUI();  
    52.                 }  
    53.             });  
    54.         }  
    55.         public void createUI() {  
    56.               
    57.             loginFrame = new JFrame("From Cannel_2020"s blog(CSDN)");  
    58.             loginFrame.setSize(340, 260);  
    59.             loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    60.             loginFrame.setLocationRelativeTo(null);  
    61.               
    62.             JPanel panel = createPanel();  
    63.             layerUI = new LoginLayerUI();  
    64.             /*
    65.              * JLayer的构造函数:JLayer(V view, LayerUI
    66.    
    67.       ui),
    68.              * 第一个参数view为Component的一个子类,就是要要装饰的Swing组件
    69.              * 第二个参数为LayerUI
    70.      
    71.       的一个实例,指定
    72.              */  
    73.             JLayer
    74.       
    75.         jlayer = new JLayer
    76.       
    77.         (panel, layerUI);  
    78.             //注意这个add的是JLayer
    79.         
    80.          的一个实例  
    81.             loginFrame.add(jlayer);  
    82.             loginFrame.setVisible(true);  
    83.         }  
    84.       
    85.         private JPanel createPanel() {  
    86.             final Image background = new ImageIcon("image/background.jpg").getImage();//背景图片  
    87.             JPanel panel = new JPanel() {  
    88.                 private static final long serialVersionUID = 6246862165441423926L;  
    89.                 public void paintComponent(Graphics g) {  
    90.                     super.paintComponent(g);  
    91.                     Graphics2D g2d = (Graphics2D) g;  
    92.                     g2d.drawImage(background, 0, 0, loginFrame.getWidth(),  
    93.                             loginFrame.getHeight(), this);  
    94.                 }  
    95.             };  
    96.             panel.setLayout(null);  
    97.               
    98.               
    99.             Font font = new Font("微软雅黑",Font.PLAIN,14);  
    100.             JLabel accountLabel = new JLabel("账号:");  
    101.             accountLabel.setFont(font);  
    102.             accountLabel.setBounds(40, 60, 40, 15);  
    103.             JLabel pswLabel = new JLabel("密码:");  
    104.             pswLabel.setFont(font);  
    105.             pswLabel.setBounds(40, 98, 40, 15);  
    106.               
    107.             final JTextField userName = new JTextField();  
    108.             userName.setFont(font);  
    109.             userName.setBounds(88, 53, 155, 33);  
    110.             userName.addFocusListener(new FocusAdapter(){  
    111.                 public void focusGained(FocusEvent e) {  
    112.                     userName.selectAll();  
    113.                 }  
    114.             });  
    115.             JPasswordField password = new JPasswordField();  
    116.             password.setBounds(88, 90, 155, 33);  
    117.             JLabel registerLabel = new JLabel("注册");  
    118.             registerLabel.setFont(font);  
    119.             registerLabel.setBounds(260, 60, 28, 19);  
    120.             JLabel findBackLabel = new JLabel("找回");  
    121.             findBackLabel.setFont(font);  
    122.             findBackLabel.setBounds(260, 98, 28, 19);  
    123.               
    124.             JCheckBox rmbCBox = new JCheckBox("记住密码");  
    125.             rmbCBox.setSelected(true);  
    126.             rmbCBox.setBounds(90, 140, 77, 14);  
    127.             rmbCBox.addItemListener(new ItemListener(){  
    128.                 public void itemStateChanged(ItemEvent e) {  
    129.                     if(e.getStateChange() == ItemEvent.DESELECTED){  
    130.                         System.out.println("rmbCBox(JCheckBox)被选中!");  
    131.                     }  
    132.                 }  
    133.             });  
    134.             JCheckBox autoCBox = new JCheckBox("自动登录");  
    135.             autoCBox.setBounds(175, 140, 77, 14);  
    136.               
    137.             JButton setButton = new JButton("设置");  
    138.             setButton.setBounds(50, 170, 75, 27);  
    139.               
    140.             JButton loginButton = new JButton("登录");  
    141.             loginButton.setFont(font);  
    142.             loginButton.setBounds(90, 170, 75, 27);  
    143.             //5秒钟后停止  
    144.             final Timer stopper = new Timer(5000, new ActionListener() {  
    145.                 public void actionPerformed(ActionEvent ae) {  
    146.                     layerUI.stop();  
    147.                 }  
    148.             });  
    149.             stopper.setRepeats(false);//设置计时器只在第一次时触发然后停止  
    150.       
    151.             loginButton.addActionListener(new ActionListener() {  
    152.                 public void actionPerformed(ActionEvent ae) {  
    153.                     layerUI.start();  
    154.                     //若stopper不是在运行,则启动stopper。  
    155.                     if (!stopper.isRunning()) {  
    156.                         stopper.start();  
    157.                     }  
    158.                 }  
    159.             });  
    160.               
    161.             JButton exitButton = new JButton("退出");  
    162.             exitButton.setFont(font);  
    163.             exitButton.setBounds(170, 170, 75, 27);  
    164.             exitButton.addActionListener(new ActionListener()  
    165.             {  
    166.                 public void actionPerformed(ActionEvent e) {  
    167.                     System.exit(0);  
    168.                 }  
    169.                   
    170.             });  
    171.               
    172.             panel.add(userName);  
    173.             panel.add(password);  
    174.             panel.add(accountLabel);  
    175.             panel.add(pswLabel);  
    176.             panel.add(registerLabel);  
    177.             panel.add(findBackLabel);  
    178.             panel.add(rmbCBox);  
    179.             panel.add(autoCBox);  
    180.             panel.add(loginButton);  
    181.             panel.add(exitButton);  
    182.               
    183.             return panel;  
    184.       
    185.       
    186.         }  
    187.     }  
    188.     class LoginLayerUI extends LayerUI
    189.          
    190.            implements ActionListener {  
    191.       
    192.         private static final long serialVersionUID = 1L;  
    193.         private boolean mIsRunning = false;// 点击按钮之后所触发的线程是否在运行  
    194.         private boolean mIsFadingOut = false;//控制线程的停止,和处理  
    195.         private Timer mTimer;// 在指定时间间隔触发一个或多个 ActionEvent。  
    196.       
    197.         private int mAngle = 0;//用于旋转时计算角度  
    198.         private int mFadeCount = 0;//结合mFadeLimit用于设置针形旋转图案整体的渐变的效果  
    199.         private int mFadeLimit = 30;  
    200.       
    201.         private boolean mActive;// 是否进入窗口内  
    202.         private int mX, mY;// 记录鼠标的坐标  
    203.         /*
    204.          * 渲染效果的过程中会不断调用paint
    205.          */  
    206.         public void paint(Graphics g, JComponent c) {  
    207.             int w = c.getWidth();//获取组件c的宽度  
    208.             int h = c.getHeight();  
    209.             super.paint(g, c);//调用父类的paint方法,绘画组件c  
    210.       
    211.             Graphics2D g2 = (Graphics2D) g.create();  
    212.             // 设置聚光灯(Spotlight)效果  
    213.             if (mActive) {  
    214.                 // 创建径向渐变,中间透明。  
    215.                 java.awt.geom.Point2D center = new java.awt.geom.Point2D.Float(mX,  
    216.                         mY);  
    217.                 float radius = 72;  
    218.                 float[] dist = { 0.0f, 1.0f };  
    219.                 Color[] colors = { new Color(0.0f, 0.0f, 0.0f, 0.0f), Color.black };  
    220.                 //RadialGradientPaint 类提供使用圆形辐射颜色渐变模式填充某一形状的方式  
    221.                 RadialGradientPaint p = new RadialGradientPaint(center, radius,  
    222.                         dist, colors);  
    223.                 //setPaint:为 Graphics2D 上下文设置 Paint 属性  
    224.                 g2.setPaint(p);  
    225.                 /*为 Graphics2D 上下文设置 Composite。  
    226.                  *Composite 用于所有绘制方法中,如 drawImage、drawString、draw 和 fill
    227.                  *这里使用AlphaComposite 类实现一些基本的 alpha 合成规则
    228.                  *将源色与目标色组合,在图形和图像中实现混合和透明效果
    229.                  */  
    230.                 g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,  
    231.                         .6f));  
    232.                 //填充是绘画  
    233.                 g2.fillRect(0, 0, c.getWidth(), c.getHeight());  
    234.             }  
    235.               
    236.               
    237.             if (!mIsRunning) {  
    238.                 return;  
    239.             }  
    240.             float fade = (float) mFadeCount / (float) mFadeLimit;  
    241.             //fade的不同形成:12根针整体刚才出现的渐变效果,和登录成功后的针消失过程的渐变效果  
    242.             g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,  
    243.                     .5f * fade));  
    244.             g2.fillRect(0, 0, w, h);  
    245.       
    246.             int s = Math.min(w, h) / 5;  
    247.             int cx = w / 2;  
    248.             int cy = h / 2;  
    249.             /* 为呈现算法设置单个首选项的值。
    250.              * RenderingHints.KEY_ANTIALIASING:抗锯齿提示键。
    251.              * RenderingHints.VALUE_ANTIALIAS_ON:抗锯齿提示值――使用抗锯齿模式完成呈现
    252.              */  
    253.             g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,  
    254.                     RenderingHints.VALUE_ANTIALIAS_ON);  
    255.       
    256.             /*
    257.              *  setStroke:设置呈现过程中要画的图形
    258.              * BasicStroke 类定义针对图形图元轮廓呈现属性的一个基本集合
    259.              */  
    260.             g2.setStroke(new BasicStroke(s / 4, BasicStroke.CAP_ROUND,  
    261.                     BasicStroke.JOIN_ROUND));  
    262.             //设置绘画颜色  
    263.             g2.setPaint(Color.white);  
    264.             /* rotate:旋转转换连接
    265.              * 第一个参数 Math.PI * mAngle / 180:旋转的角度,以弧度为单位
    266.              * 第二个参数 cx:x - 旋转原点的 x 坐标
    267.              * 第二个参数 cy:y - 旋转原点的 y 坐标
    268.              */  
    269.             g2.rotate(Math.PI * mAngle / 180, cx, cy);  
    270.               
    271.             //12跟针,各个针的颜色是不同的,针与针之间形成渐变的效果  
    272.             for (int i = 0; i < 12; i++) {  
    273.                 float scale = (11.0f - (float) i) / 11.0f;  
    274.                 g2.drawLine(cx + s, cy, cx + s * 2, cy);  
    275.                 g2.rotate(-Math.PI / 6, cx, cy);  
    276.                 //通过设置AlphaComposite.getInstance()第二个参数的不同来实现12“针”颜色的不同  
    277.                 g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,  
    278.                         scale * fade));  
    279.             }  
    280.             //释放此图形的上下文以及它使用的所有系统资源。   
    281.             g2.dispose();  
    282.         }  
    283.       
    284.         public void installUI(JComponent c) {  
    285.             super.installUI(c);  
    286.             JLayer jlayer = (JLayer) c;  
    287.             // 启动鼠标事件和鼠标移动事件  
    288.             jlayer.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK  
    289.                     | AWTEvent.MOUSE_MOTION_EVENT_MASK);  
    290.         }  
    291.       
    292.         public void uninstallUI(JComponent c) {  
    293.             JLayer jlayer = (JLayer) c;  
    294.             jlayer.setLayerEventMask(0);  
    295.             super.uninstallUI(c);  
    296.         }  
    297.       
    298.         // JLayer对象专用的鼠标事件,在installUI中启动事件,在uninstallUI中禁用事件  
    299.         protected void processMouseEvent(MouseEvent e, JLayer l) {  
    300.             if (e.getID() == MouseEvent.MOUSE_ENTERED)  
    301.                 mActive = true;  
    302.             if (e.getID() == MouseEvent.MOUSE_EXITED)  
    303.                 mActive = false;  
    304.             l.repaint();  
    305.         }  
    306.       
    307.         // JLayer对象专用的鼠标移动事件,在installUI中启动事件,在uninstallUI中禁用事件  
    308.         // 这里把鼠标坐标记录在mX和mY中  
    309.         protected void processMouseMotionEvent(MouseEvent e, JLayer l) {  
    310.             // 确定鼠标移动事件相对于层的坐标位置。  
    311.             Point p = SwingUtilities  
    312.                     .convertPoint(e.getComponent(), e.getPoint(), l);  
    313.             mX = p.x;  
    314.             mY = p.y;  
    315.             l.repaint();  
    316.         }  
    317.       
    318.         public void actionPerformed(ActionEvent e) {  
    319.             if (mIsRunning) {  
    320.                 //firePropertyChange():通知的内部状态的更新  
    321.                 firePropertyChange("tick", 0, 1);  
    322.                 mAngle += 3;  
    323.                 if (mAngle >= 360) {  
    324.                     mAngle = 0;  
    325.                 }  
    326.                 if (mIsFadingOut) {  
    327.                     if (--mFadeCount == 0) {  
    328.                         mIsRunning = false;  
    329.                         mTimer.stop();  
    330.                     }  
    331.                 //防止AlphaComposite.getInstance()的第二个参数的值超出范围  
    332.                 } else if (mFadeCount < mFadeLimit) {  
    333.                     mFadeCount++;  
    334.                 }  
    335.             }  
    336.         }  
    337.       
    338.         public void start() {  
    339.             if (mIsRunning) {  
    340.                 return;  
    341.             }  
    342.             mIsRunning = true;  
    343.             mIsFadingOut = false;  
    344.             mFadeCount = 0;  
    345.             int fps = 24;  
    346.             int tick = 1000 / fps;  
    347.             //每tick毫秒调用一次本类中的actionPerformed方法  
    348.             mTimer = new Timer(tick, this);  
    349.             mTimer.start();  
    350.         }  
    351.       
    352.         public void stop() {  
    353.             mIsFadingOut = true;  
    354.         }  
    355.         //不断repaint()窗口  
    356.         public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) {  
    357.             if ("tick".equals(pce.getPropertyName())) {  
    358.                 l.repaint();  
    359.             }  
    360.         }  
    361.     }  
    362.          
    363.         
    364.       
    365.       
    366.      
    367.    
    复制代码

       
         
         
          
          

            
          

            
          
         
       

      


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

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2025-2-25 07:48 , Processed in 0.329755 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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