java实现靠边隐藏窗口

说明:
由于个人精力有限,现将部分研究的代码开源出来,
代码或思路有部分来源于网络,有些代码还没来得及整理,
如果您对这其中的部分代码、思路整理出了一些文档,希望您能够联系我,分享您的成果
我将在下一版中更新您提供的一些文档.
开源不是靠一个人的坚持能完成的事,希望在不涉及版权问题的情况下,贡献您一份力量
版权归原作者所有,如果您有什么好的想法或建议,欢迎联系我

AutoHiddenFrame.java
package com.xdarkness.swing.autohidden;

import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Point;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
* @author Darkness
* @version 1.0
* @since JDF 1.0
*/
public class AutoHiddenFrame extends JFrame {
private static final long serialVersionUID = 1L;

protected GraphicsConfiguration translucencyCapableGC;// 图形环境

private AHFBodyState state = AHFBodyState.NORMAL; // 窗体的状态,让它初始化为普通状态
private Point hiddenPoint; // 隐藏窗体时,窗体的位置
private Point visiblePoint; // 窗体处于显示状态时的位置

public AutoHiddenFrame() {
// 获取系统图形环境
translucencyCapableGC = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration();

setContentPane(new JPanel(new BorderLayout()) {
private static final long serialVersionUID = 1L;

public Insets getInsets() {
return new Insets(3, 3, 3, 3);
}
}); // 替换掉原来的ContentPane,换上一个带有Insets的,至于为什么去看WindowMouseListener类

new WindowLocationListener(this);
new WindowMouseListener(this);
//WindowLocationListener.checkAutoHiddenState(this);// 刚出来就检查一下窗体的位置

}

protected int FWidth;
protected int FHeight;

@Override
public void setSize(int width, int height) {
super.setSize(width, height);

FWidth = width;
FHeight = height;
}

/**
* @param newState
* 新的状态 一定要是此类中定义的3中状态之一
*/
public void setStates(AHFBodyState newState) {
state = newState;
}

/*
* 返回状态,注意此方法和setStates方法区别与JFrame中的setState()和getState()方法
*/
public AHFBodyState getStates() {
return state;
}

/*
* 设置要显示时窗体的坐标
*/
public void setVisiblePoint(Point point) {
visiblePoint = point;
}

/*
* 设置要隐藏是窗体的坐标
*/
public void setHiddenPoint(Point point) {
hiddenPoint = point;
}

public void moveToVisible() {
if (visiblePoint != null) {
WindowMover.moveToPoint(this, visiblePoint);
setStates(AHFBodyState.CANHIDD);
}
}

public void moveToHidden() {
if (hiddenPoint != null) {
WindowMover.moveToPoint(this, hiddenPoint);
setStates(AHFBodyState.HIDDEN);
}
}

public void setMoveFrames(int frames){
WindowMover.FRAMES = frames;
}

}

/**
* 窗体状态
* @author Darkness
* @version 1.0
* @since JDF 1.0
*/
class AHFBodyState {
private String bodyState;

AHFBodyState(String bodyState) {
this.bodyState = bodyState;
}

public static final AHFBodyState NORMAL = new AHFBodyState("nomal"); // 窗体的普通状态
public static final AHFBodyState CANHIDD = new AHFBodyState("can hid"); // 窗体位于屏幕边缘,可以隐藏的状态
public static final AHFBodyState HIDDEN = new AHFBodyState("hidden"); // 窗体处于隐藏状态

public String toString() {
return bodyState;
}
}


WindowLocationListener.java
package com.xdarkness.swing.autohidden;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

/**
* 为窗体添加控制窗口是否隐藏的监听器 判断窗体的位置,更新显示、隐藏的点,及窗体的状态
*
* @author Darkness
* @version 1.0
* @since JDF 1.0
*
*/
public class WindowLocationListener extends ComponentAdapter {

public static final int HIDDEN_BOUND = 3; // 当窗体进入到屏幕边缘3像素以内就可以隐藏
public static final int VISIBLE_BOUND = 5; // 当窗体隐藏后要有5像素的部分露出来,不能完全隐藏

AutoHiddenFrame frame;

public WindowLocationListener(AutoHiddenFrame a) {
frame = a;
frame.addComponentListener(this);
}

public void componentMoved(ComponentEvent e) {
checkAutoHiddenState(frame);// 当窗体移动就调用检查方法;
}

/**
* 判断窗体的位置,更新显示、隐藏的点,及窗体的状态
*
* @param frame
*/
public static void checkAutoHiddenState(AutoHiddenFrame frame) {

// 当窗体状态不是隐藏的,再进行检查
if (frame.getStates() == AHFBodyState.HIDDEN) {
return;
}

// 首先获得屏幕的大小和窗体的坐标
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

Point hiddenPoint = frame.getLocation();
Point visiblePoint = null;
boolean canhidden = false;

System.out.println("hiddenPoint before:" + hiddenPoint);

// 当窗体位于左边边缘
if (hiddenPoint.x <= HIDDEN_BOUND) {
hiddenPoint.move(VISIBLE_BOUND - frame.FWidth, hiddenPoint.y);
visiblePoint = new Point(0, hiddenPoint.y);
canhidden = true;
}
// 当窗体位于上边
else if (hiddenPoint.y <= HIDDEN_BOUND) {
hiddenPoint.setLocation(hiddenPoint.x, VISIBLE_BOUND
- frame.FHeight);
visiblePoint = new Point(hiddenPoint.x, 0);
canhidden = true;
}
// 当窗体位于右边
else if (hiddenPoint.x + frame.getWidth() >= screenSize.width
- HIDDEN_BOUND) {
hiddenPoint.setLocation(screenSize.width - VISIBLE_BOUND,
hiddenPoint.y);
visiblePoint = new Point(screenSize.width - frame.FWidth,
hiddenPoint.y);
canhidden = true;
}
System.out.println("hiddenPoint after:" + hiddenPoint);
if (canhidden) {
// 如果符合以上几种情况的一种就可以隐藏
frame.setVisiblePoint(visiblePoint);
frame.setHiddenPoint(hiddenPoint);
frame.setStates(AHFBodyState.CANHIDD);
System.out.println("进入可隐藏区域!");
} else {
// 如果不可以隐藏,那就是离开了边缘了
if (frame.getStates() == AHFBodyState.CANHIDD) {
System.out.println("离开可应藏区域!");
}
frame.setVisiblePoint(frame.getLocation());
frame.setStates(AHFBodyState.NORMAL);
}
}
}



WindowMouseListener.java
package com.xdarkness.swing.autohidden;

import java.awt.Container;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

/**
* 为窗体添加鼠标事件监听器
*
* @author Darkness
* @version 1.0
* @since JDF 1.0
*/
public class WindowMouseListener extends MouseAdapter implements
ActionListener, WindowFocusListener {
private Timer timer;

private AutoHiddenFrame frame;

Container container;

public WindowMouseListener(AutoHiddenFrame a) {
frame = a;
container = frame.getContentPane();
container.addMouseListener(this);
// 注册鼠标侦听器到ContentPane上,因为我们可以加大它的Insets以提高鼠标进入和离开的灵敏度
frame.addWindowFocusListener(this);
// 注册一个焦点侦听器到窗体上
timer = new Timer(2000, this);
timer.setRepeats(false);
}

public void mouseEntered(MouseEvent e) {
// 当鼠标进入,就显示窗体
if (frame.getStates() == AHFBodyState.HIDDEN) {
frame.moveToVisible();
}

}

public void mouseExited(MouseEvent e) {
// 当鼠标离开,启动计时器
if (frame.getStates() == AHFBodyState.CANHIDD) {
if (!container.contains(e.getPoint())) {
System.out.println(timer.getDelay() / 1000 + "秒后自动隐藏窗口!");
timer.restart();
}
}

}

public void actionPerformed(ActionEvent e) {
// 计时器到期,检查鼠标是不是还在此窗体里面,不再的话,再开始隐藏
Point p = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(p, container);
if (!container.contains(p)
&& frame.getStates() == AHFBodyState.CANHIDD) {
frame.moveToHidden();
}
}

public void windowGainedFocus(WindowEvent e) {
// 得到焦点检查鼠标是不是在窗体上
Point p = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(p, container);
if (container.contains(p)
&& frame.getStates() == AHFBodyState.HIDDEN) {
frame.moveToVisible();
}
}

public void windowLostFocus(WindowEvent e) {
// 失去焦点,启动计时器
if (frame.getStates() == AHFBodyState.CANHIDD) {
System.out.println("2秒后自动隐藏窗口!");
timer.restart();
}
}
}



WindowMover.java
package com.xdarkness.swing.autohidden;

import java.awt.Point;
import java.awt.event.ComponentListener;

import javax.swing.JFrame;

/**
* 用来提示将要隐藏的线程
*
* @author Darkness
* @version 1.0
* @since JDF 1.0
*/
public class WindowMover extends Thread {

public static void moveToPoint(JFrame dialog, Point targetPoint) {
new WindowMover(dialog, targetPoint).start();
}

protected static int FRAMES = 15; // 最多移动多少动画帧

private JFrame window; // 要移动的窗口

private Point point; // 目的坐标

private int index; // 当前帧数

private int addedX; // 每次移动的X坐标增量

private int addedY; // 每次移动的Y坐标的增量

ComponentListener[] componentListeners;// 组件侦听器数组

/*
* 定义私有的构造方法,应调用静态方法moveToPoint;
*/
private WindowMover(JFrame window, Point targetPoint) {
this.window = window;
window.getGlassPane().setVisible(true);
// 设置此窗体的GlassPane为显示的,以阻止子组件接收鼠标事件,减少事件触发

// 同样,移除此窗体上的组件侦听器,防止再次触发窗体移动事件
componentListeners = window.getComponentListeners();

for (ComponentListener cl : componentListeners) {
window.removeComponentListener(cl);
}

Point wl = window.getLocation();
point = targetPoint;
index = 0; // 初始化帧书为0;

// 计算每次移动量
addedX = (point.x - wl.x) / FRAMES;
if (addedX == 0 && point.x != wl.x) {
addedX = point.x < wl.x ? -1 : 1;
}
addedY = (point.y - wl.y) / FRAMES;
if (addedY == 0 && point.y != wl.y) {
addedY = point.y < wl.y ? -1 : 1;
}
}

public void run() {
System.out.println(window.getLocation() + "=====" + point);

if (window.getLocation().equals(point))
return;// 如果已在目的点,则返回
if (!window.isVisible())
return;// 如果窗口是不可视的则返回

while (index < FRAMES) {
Point p = window.getLocation();
if (p.x != point.x)
p.translate(addedX, 0);
if (p.y != point.y)
p.translate(0, addedY);
window.setLocation(p);
index++;
try {
Thread.sleep(15);
} catch (Exception e) {
}
}
window.setLocation(point);
// 还原所做的操作
window.getGlassPane().setVisible(false);
for (ComponentListener cl : componentListeners) {
window.addComponentListener(cl);
}
// 释放资源,使gc可以回收此对象
window = null;
point = null;
componentListeners = null;
System.out.println("finsh Moved");
}

}



测试:
package com.xdarkness.swing.test;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import com.xdarkness.swing.autohidden.AutoHiddenFrame;

/**
* 自动隐藏窗体测试
* @author Darkness
* create on 2010-11-26 下午02:02:14
* @version 1.0
* @since JDF 1.0
*/
public class AutoHiddenFrameTest extends AutoHiddenFrame {

private static final long serialVersionUID = -455700849275575191L;

public AutoHiddenFrameTest(){
this.setTitle("Music");
this.setSize(228, 720);
this.setMoveFrames(100);// 设置自动隐藏窗体移动的帧住,数值越大,速度越慢
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

public void run() {
AutoHiddenFrameTest shell = new AutoHiddenFrameTest();
shell.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
shell.setVisible(true);
}
});
}
}


效果:

[img]http://dl.iteye.com/upload/attachment/354578/890d1fbf-e36a-38b2-a40d-8080f6148495.jpg[/img]

[img]http://dl.iteye.com/upload/attachment/354580/aa7650ca-383c-312d-8c00-84e7aa0de414.jpg[/img]

[img]http://dl.iteye.com/upload/attachment/354582/b4dcfd25-d286-333e-9850-a043d2dbbb3e.jpg[/img]

[img]http://dl.iteye.com/upload/attachment/354584/04973c73-fa3b-344a-b85c-68698d329595.jpg[/img]

[img]http://dl.iteye.com/upload/attachment/354586/269e9de8-ccc7-3aeb-9eab-b7717e22a0b1.jpg[/img]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值