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

[Java基础知识]震动的窗口

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

    [LV.1]初来乍到

    发表于 2014-10-2 03:12:32 | 显示全部楼层 |阅读模式
    在网上看到了一个很有趣的关于Swing扩展的小例子,觉得很有意思,我把他的代码稍微作了些改进,需要的朋友可以立刻在项目中使用。        这个例子主要是为了实现一个“震动”的对话框,这种震动功能在苹果机上应用的比较多。原文对源代码进行了很详细的解释,希望英文好的朋友直接去看原文,然后再回来继续看我的文章,原文的连接附在文章的最后。  下面的代码已经被我做了适当的修改,在代码中, 我也添加了适当的注释, public class DialogEarthquakeCenter extends Object {     // 窗口距离中心左右晃动的最大距离     public static final int SHAKE_DISTANCE = 10;
         
          
          
            
          

          
          
         
          // 窗口晃动一个循环(中间,右,中间,左, 中间)所需要的时间(ms),    // 这个值越小, 晃动的就越快。     public static final double SHAKE_CYCLE = 80;   // 整个晃动所需要的时间。     public static final int SHAKE_DURATION = 300;    // 这个是设定Swing多长时间(ms)更新窗口的位置。     public static final int SHAKE_UPDATE = 5;     private JDialog dialog;     private Point naturalLocation;     private long startTime;     private Timer shakeTimer;     private final double HALF_PI = Math.PI / 2.0;     private final double TWO_PI = Math.PI * 2.0;      public DialogEarthquakeCenter (JDialog d) {         dialog = d;     }     public void startShake() {        // 保存窗口的原始位置         naturalLocation = dialog.getLocation();        // 保存开始的时间         startTime = System.currentTimeMillis();         shakeTimer =             new Timer(SHAKE_UPDATE,                       new ActionListener() {                           public void actionPerformed (ActionEvent e) {                               // 计算倒目前为止花费的时间                               long elapsed = System.currentTimeMillis() -                                   startTime;                            // 下了三角公式是为了利用时间计算出某一时刻晃动的幅度,举例见A.
                                   double waveOffset = (elapsed % SHAKE_CYCLE) /                                   SHAKE_CYCLE;                               double angle = waveOffset * TWO_PI;                               double angley = waveOffset * TWO_PI;                              int shakenX = (int) ((Math.sin(angle) *                                                        SHAKE_DISTANCE) +                                                    naturalLocation.x);                               int shakenY = (int) ((Math.sin(angley) *                                   SHAKE_DISTANCE) +                                   naturalLocation.y);                               dialog.setLocation (shakenX, shakenY);                               dialog.repaint();                                // should we stop timer?                               if (elapsed >= SHAKE_DURATION)                                   stopShake();                           }                       } );         shakeTimer.start();     }     public void stopShake() {         shakeTimer.stop();         dialog.setLocation (naturalLocation);         dialog.repaint();     } // 去掉了原始代码中的main }   
      


      
      A. 下面我来解释一下这里用到的三角函数,其实非常简单,其目的就是让窗口流畅的晃动。
        double waveOffset = (elapsed % SHAKE_CYCLE) /SHAKE_CYCLE;
      由于窗口是在相对于他的原始位置做周期震动,这个公式是为了将震动的时间换算成相对震动一周的相对比例,举例来说就是:(%是取余运算)
      20ms时,震动了1/4周,waveOffset = (20%80)/80 = 0.25, 到右边最远处。
      40ms时,震动了半周, waveOffset = (40%80)/80 = 0.5, 回到起点位置。
      60ms时,震动了3/4周,waveOffset = (60%80)/80 = 0.25, 到左边最远处。
      80ms时,整好震动一周, waveOffset = (80 %80)/80 = 0, 回到起点位置。
      然后继续循环
      double angle = waveOffset * TWO_PI
      将上述介于0到1的比例换算成角度,也就是20ms-1/4周-PI/2。  
                                    int shakenX = (int) ((Math.sin(angle) *
                                                          SHAKE_DISTANCE) +
                                                         naturalLocation.x);
      然后再将角度利用sin函数换算成相对应的震动幅度。到这里可能会有朋友要问,问什么不利用时间比例waveOffset直接换算成震动幅度, 就是好象这样:
                                    int shakenX = (int) ((waveOffset*
                                                          SHAKE_DISTANCE) +
                                                         naturalLocation.x);
          这样也是可以的,利用三角函数可以使振动更加圆滑更加真实,因为y = sin(x)函数波浪形的曲线,结果是靠近中心的地方震动幅度变化的比较快,远离中心的地方震动幅度变化的比较慢。而使用waveOffset直接换算成震动幅度使用的是y=ax函数,他的函数图是直线,导致震动幅度变化比较生硬。
          原始的代码里面只是设置了x方向的震动,我又加入了y方向的震动,并且调整了一些参数,使得震动比较柔和。 还有就是,原始代码是含有main方法的application。在实际开发中根本没用,我把她改写成了一个简单的类。在实际开发中只要在DialogFactory里面增加一个方法生成这种对话框就可以了,编码人员可以轻松使用,i.e. 。

    DialogFacotry.createShakeMessageDialog(……)
      Public final class DialogFactory {
      ……   
      // 这里使用enum是为了实现I18N,如果不需要的话,可以直接使用String
      private void createShakeMessageDialog(Enum title,
                  Enum message) {
                  // 作为例子,这里只是生成一个简单的信息框,只带有一个ok按钮。
                  JOptionPane pane = new JOptionPane(message.localized(),
                      JOptionPane.INFORMATION_MESSAGE, JOptionPane.DEFAULT_OPTION,
                      null, null, null);  
                  JDialog dialog = pane.createDialog(DialogFactory.defaultFrame(),
                      title.localized());
                  DialogShaker shaker = new DialogShaker(dialog);
                  dialog.pack();
                  // 这个很关键,一定要设为false
                  dialog.setModal(false);
                  dialog.setVisible(true);
                  shaker.startShake();
              }
      ......
      //其他方法。
      }
    来源:http://polygoncell.spaces.live.com/PersonalSpace.aspx?_c02_owner=1
      原文:http://www.oreilly.com/catalog/swinghks/chapter/hack38.pdf
      
       
       
       
          
          

          
          

          
          
       
       
      

      


      
      



    源码下载:http://file.javaxxz.com/2014/10/2/031231344.zip
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2025-2-27 01:40 , Processed in 0.324476 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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