`
anysky131
  • 浏览: 175029 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Swing 制作振动窗口

    博客分类:
  • GUI
阅读更多
今天在网上看到了一个很有趣的关于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();

    }

public static void main(String asrg[]){
	JFrame frame = new JFrame();
	JButton button = new JButton("打开");
	button.addActionListener(new ActionListener(){

		public void actionPerformed(ActionEvent arg0) {
			JDialog dialog = new JDialog();
			dialog.setVisible(true);
			dialog.setSize(200, 200);
			DialogEarthquakeCenter dialog1 = new DialogEarthquakeCenter(dialog);
			dialog1.startShake();
		}
		
	});
	frame.setSize(500,500);
	frame.setMinimumSize(new Dimension(500,500));
	frame.getContentPane().add(button);
	frame.setVisible(true);
}

}




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://www.oreilly.com/catalog/swinghks/chapter/hack38.pdf
分享到:
评论
1 楼 xiaoyiz 2009-09-26  
非常好 perfect! 借用了。。 呵呵 用于提醒用户挺不错的!

相关推荐

    swing多窗口联动的实现示例

    在Java的Swing库中,开发GUI应用程序时,我们经常需要处理多个窗口之间的交互和数据共享,这在实际应用中非常常见,例如在一个主窗口进行操作,然后更新其他子窗口的信息。本示例"swing多窗口联动的实现示例"就是...

    javaSwing各种主题窗口

    Swing 提供了多种窗口主题,使得开发者可以为应用创建具有不同视觉风格的界面,以适应不同的操作系统环境,如 Windows、Mac OS(苹果系统)等。在Java Swing中,这些主题通常被称为“LookAndFeel”。 在Java Swing...

    Swing制作的QQ界面

    在这个“Swing制作的QQ界面”项目中,开发者使用Swing构建了一个类似腾讯QQ的聊天应用界面。 `TestWindow.java`是压缩包中的关键文件,通常它会包含整个应用的主要窗口或主类。这个类可能是程序的入口点,负责初始...

    使用JavaSwing重写的美化版窗口模板

    在这个“使用JavaSwing重写的美化版窗口模板”中,我们可以深入探讨Java Swing在构建美观、交互性强的窗口应用中的运用。 1. **Java Swing基础**: - Swing是Java的轻量级GUI框架,它使用Java2D进行渲染,可以创建...

    使用swing制作的向导页面

    本示例中,我们关注的是“使用Swing制作的向导页面”,这是一种常见的用户交互模式,用于引导用户逐步完成复杂任务或提供一系列设置。向导页面通常由多个步骤组成,每个步骤都包含特定的信息输入或选择,用户按顺序...

    java Swing 气泡浮动提示窗口代码

    在Swing中,有时我们需要为用户提供一种轻量级的提示机制,比如气泡浮动提示窗口,这通常用于显示临时信息或者提示。在给定的代码中,作者实现了一个自定义的`ToolTip`类来达到这个目的。 `ToolTip`类主要包含了...

    用swing制作的简单图书管理系统

    本系统——"用Swing制作的简单图书管理系统"就是基于这一强大的库构建的。下面我们将深入探讨该系统的设计理念、主要功能以及Swing在其中的关键应用。 一、Swing基础与应用 Swing是Java Foundation Classes (JFC)的...

    Swing精美界面设计和动画制作教程+实例

    Swing精美界面设计和动画制作教程+实例Swing精美界面设计和动画制作教程+实例Swing精美界面设计和动画制作教程+实例Swing精美界面设计和动画制作教程+实例Swing精美界面设计和动画制作教程+实例Swing精美界面...

    用Swing制作精美的图层叠加图

    这篇博文“用Swing制作精美的图层叠加图”探讨了如何利用Swing来实现这一目标,尤其是在数据可视化和用户交互方面。通过源码分析,我们可以学习到以下关键知识点: 1. **Swing组件基础**:Swing是Java GUI(图形...

    java swing 基于JFrame窗口的绘画板

    首先,JFrame是Java Swing中的一个顶级容器,它充当窗口的基础。开发者可以通过添加各种组件到JFrame中来构建应用程序的界面。在绘画板应用中,JFrame将是用户与绘图区域交互的主要窗口。 绘画功能的实现主要涉及到...

    Swing实现半透明窗口的Sample

    在这个特定的项目中,"Swing实现半透明窗口的Sample"是关于如何利用Swing库来创建一个具有半透明效果的窗口。半透明窗口是一种在视觉上吸引人的设计元素,它允许部分背景透过窗口显示,为用户带来独特的交互体验。 ...

    swing窗口旋转关闭

    在Swing窗口旋转关闭这一主题中,我们将深入探讨如何利用Swing组件和方法来实现窗口的旋转效果以及自定义窗口关闭操作。 首先,Swing中的主要窗口类是`JFrame`,它是顶级容器,用于创建应用程序的主要窗口。要创建...

    java基础SWING之窗口篇

    在这个“java基础SWING之窗口篇”中,我们将深入探讨Swing如何帮助开发者构建交互式的窗口应用。 Swing 提供了一个称为 `JFrame` 的类,它是创建窗口的基础。`JFrame` 对象代表了应用程序的主要窗口,可以添加各种...

    java_swing设置窗口居中的最佳方法

    在Java Swing中,设置窗口居中的最佳方法是一个常见的需求,特别是在开发用户界面时,为了提升用户体验,确保窗口在不同尺寸的屏幕上都能居中显示是非常重要的。以下是对如何在Java Swing中实现窗口居中的详细解析:...

    swing制作的精美记事本

    swing制作的精美记事本,界面仿苹果。可以拿去参考和使用

    Swing窗口美化包.zip

    在压缩包"Swing窗口美化包.zip"中,包含了这三个美化库的jar文件,这使得开发者可以直接将它们导入到项目中,快速提升Swing应用的视觉效果。通过探索和实践,开发者可以找到最适合自己的美化方案,为Swing应用带来...

    java swing制作的时钟

    Java Swing 是Java GUI(图形用户界面)库,用于构建桌面应用程序。它提供了丰富的组件和工具,使得开发者可以创建出美观且功能丰富的用户界面。在这个场景中,我们讨论的是一个使用Java Swing开发的时钟应用,该...

    抽象窗口工具包 (AWT)和Swing

    【抽象窗口工具包 (AWT) 和 Swing 的概念及区别】 AWT(Abstract Window Toolkit)是Java早期提供的用于创建图形用户界面(GUI)的基础框架,它由Java标准版(Java SE)提供。AWT组件是操作系统原生组件的代理,...

    用AWT Swing制作的登录注册页面,连接MySQL

    在本项目中,"用AWT Swing制作的登录注册页面,连接MySQL",开发者创建了一个使用这两种技术的简单应用,允许用户进行登录和注册操作,并将数据存储在MySQL数据库中。这为Java初学者提供了了解如何结合使用这些技术...

    Swing制作的ERP图表

    用swing实现的制作(ERP)报表;很好很简单方便!

Global site tag (gtag.js) - Google Analytics