今天在网上看到了一个很有趣的关于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
分享到:
相关推荐
在Java的Swing库中,开发GUI应用程序时,我们经常需要处理多个窗口之间的交互和数据共享,这在实际应用中非常常见,例如在一个主窗口进行操作,然后更新其他子窗口的信息。本示例"swing多窗口联动的实现示例"就是...
Swing 提供了多种窗口主题,使得开发者可以为应用创建具有不同视觉风格的界面,以适应不同的操作系统环境,如 Windows、Mac OS(苹果系统)等。在Java Swing中,这些主题通常被称为“LookAndFeel”。 在Java Swing...
在这个“Swing制作的QQ界面”项目中,开发者使用Swing构建了一个类似腾讯QQ的聊天应用界面。 `TestWindow.java`是压缩包中的关键文件,通常它会包含整个应用的主要窗口或主类。这个类可能是程序的入口点,负责初始...
在这个“使用JavaSwing重写的美化版窗口模板”中,我们可以深入探讨Java Swing在构建美观、交互性强的窗口应用中的运用。 1. **Java Swing基础**: - Swing是Java的轻量级GUI框架,它使用Java2D进行渲染,可以创建...
本示例中,我们关注的是“使用Swing制作的向导页面”,这是一种常见的用户交互模式,用于引导用户逐步完成复杂任务或提供一系列设置。向导页面通常由多个步骤组成,每个步骤都包含特定的信息输入或选择,用户按顺序...
在Swing中,有时我们需要为用户提供一种轻量级的提示机制,比如气泡浮动提示窗口,这通常用于显示临时信息或者提示。在给定的代码中,作者实现了一个自定义的`ToolTip`类来达到这个目的。 `ToolTip`类主要包含了...
本系统——"用Swing制作的简单图书管理系统"就是基于这一强大的库构建的。下面我们将深入探讨该系统的设计理念、主要功能以及Swing在其中的关键应用。 一、Swing基础与应用 Swing是Java Foundation Classes (JFC)的...
Swing精美界面设计和动画制作教程+实例Swing精美界面设计和动画制作教程+实例Swing精美界面设计和动画制作教程+实例Swing精美界面设计和动画制作教程+实例Swing精美界面设计和动画制作教程+实例Swing精美界面...
这篇博文“用Swing制作精美的图层叠加图”探讨了如何利用Swing来实现这一目标,尤其是在数据可视化和用户交互方面。通过源码分析,我们可以学习到以下关键知识点: 1. **Swing组件基础**:Swing是Java GUI(图形...
通过Jigloo,开发者可以快速创建复杂的窗口布局,自动生成对应的Java源代码,并方便地进行调试和修改。 Swing的知识点包括但不限于以下几点: 1. **组件(Components)**:Swing提供了许多预定义的组件,如JButton...
在这个特定的项目中,"Swing实现半透明窗口的Sample"是关于如何利用Swing库来创建一个具有半透明效果的窗口。半透明窗口是一种在视觉上吸引人的设计元素,它允许部分背景透过窗口显示,为用户带来独特的交互体验。 ...
在Swing窗口旋转关闭这一主题中,我们将深入探讨如何利用Swing组件和方法来实现窗口的旋转效果以及自定义窗口关闭操作。 首先,Swing中的主要窗口类是`JFrame`,它是顶级容器,用于创建应用程序的主要窗口。要创建...
在这个“java基础SWING之窗口篇”中,我们将深入探讨Swing如何帮助开发者构建交互式的窗口应用。 Swing 提供了一个称为 `JFrame` 的类,它是创建窗口的基础。`JFrame` 对象代表了应用程序的主要窗口,可以添加各种...
在Java Swing中,设置窗口居中的最佳方法是一个常见的需求,特别是在开发用户界面时,为了提升用户体验,确保窗口在不同尺寸的屏幕上都能居中显示是非常重要的。以下是对如何在Java Swing中实现窗口居中的详细解析:...
swing制作的精美记事本,界面仿苹果。可以拿去参考和使用
Java Swing 是Java GUI(图形用户界面)库,用于构建桌面应用程序。它提供了丰富的组件和工具,使得开发者可以创建出美观且功能丰富的用户界面。在这个场景中,我们讨论的是一个使用Java Swing开发的时钟应用,该...
在压缩包"Swing窗口美化包.zip"中,包含了这三个美化库的jar文件,这使得开发者可以直接将它们导入到项目中,快速提升Swing应用的视觉效果。通过探索和实践,开发者可以找到最适合自己的美化方案,为Swing应用带来...
【抽象窗口工具包 (AWT) 和 Swing 的概念及区别】 AWT(Abstract Window Toolkit)是Java早期提供的用于创建图形用户界面(GUI)的基础框架,它由Java标准版(Java SE)提供。AWT组件是操作系统原生组件的代理,...
在本项目中,"用AWT Swing制作的登录注册页面,连接MySQL",开发者创建了一个使用这两种技术的简单应用,允许用户进行登录和注册操作,并将数据存储在MySQL数据库中。这为Java初学者提供了了解如何结合使用这些技术...
用swing实现的制作(ERP)报表;很好很简单方便!