swing自制组件(二)
在未来的几天里,我将持续为大家更新swing的自制组件,全部都含有运行截图和源代码。方便大家互相交流。
今天的自制组件屏幕震动组件。可以像QQ发送的抖动窗口一样弹出震动
package com.tianlong.framework.component; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JDialog; import javax.swing.JOptionPane; import javax.swing.Timer; /** * 窗口抖动工具 * @author 翟天龙 * @version V1.0 2011-2-21 */ public class ShakeDialog extends Object { /** * 震幅 */ public static final int SHAKE_DISTANCE = 10; /** * 震动频率 */ public static final double SHAKE_CYCLE = 50; /** * 震动持续时间 */ public static final int SHAKE_DURATION = 1000; /** * 初始延迟(毫秒) */ public static final int SHAKE_UPDATE = 5; /** * 要震动的Dialog */ private JDialog dialog; /** * 要震动的Dialog的左上角坐标 */ private Point naturalLocation; /** * 震动开始时间 */ private long startTime; /** * 时间触发器 */ private Timer shakeTimer; /** * 正弦震幅 */ private final double TWO_PI = Math.PI * 2.0; /** * 构造方法 * @param d */ public ShakeDialog( 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; //利用正弦计算出震动差值 double waveOffset = (elapsed % SHAKE_CYCLE) / SHAKE_CYCLE; //正弦震幅 double angle = waveOffset * TWO_PI; //左上角x坐标 int shakenX = (int) ((Math.sin(angle) * SHAKE_DISTANCE) + naturalLocation.x); dialog.setLocation(shakenX, naturalLocation.y); dialog.repaint(); //震动结束的判断 if (elapsed >= SHAKE_DURATION) { stopShake(); } } }); shakeTimer.start(); } /** * 震动停止 */ public void stopShake() { shakeTimer.stop(); dialog.setLocation(naturalLocation); dialog.repaint(); } public static void main(String[] args) { JOptionPane pane = new JOptionPane("屏幕震动|屏幕震动|屏幕震动|屏幕震动|\n屏幕震动|屏幕震动|屏幕震动|屏幕震动", JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_OPTION); JDialog d = pane.createDialog(null, "屏幕震动!"); ShakeDialog dec = new ShakeDialog(d); d.pack(); d.setModal(false); d.setVisible(true); dec.startShake(); while (pane.getValue() == JOptionPane.UNINITIALIZED_VALUE) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.exit(0); } }