java实现靠边隐藏窗口

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

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


/**
 * @author qusic
 *
 */
public class AutoHiddenFrame extends JFrame
{
	private static final long serialVersionUID = 1L;
	public static void main(String args[])
	{
		new AutoHiddenFrame();
	}
	
	
	public static final int NORMAL = 0;			//窗体的普通状态
	public static final int CANHIDD = 1;		//窗体位于屏幕边缘,可以隐藏的状态	
	public static final int HIDDEN = 2;			//窗体处于隐藏状态
	
	private int state = NORMAL;			//窗体的状态,让它初始化为普通状态
	private Point hiddenPoint;			//隐藏窗体时,窗体的位置
	private Point visiblePoint;			//窗体处于显示状态时的位置	
	
	private JLabel infoLabel;				//用于显示信息的JLabel;
	public AutoHiddenFrame()
	{
		JPanel p = new JPanel(new BorderLayout()) {
			private static final long serialVersionUID = 1L;

			public Insets getInsets()
			{
				return new Insets(3,3,3,3);
			}
		};
		setContentPane(p);	//替换掉原来的ContentPane,换上一个带有Insets的,至于为什么去看WindowMouseListener类
		infoLabel = new JLabel();
		add(infoLabel,BorderLayout.SOUTH);
		setSize(300,200);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
		
		new WindowLocationListener(this);
		new WindowMouseListener(this);
		WindowLocationListener.checkAutoHiddenState(this);//刚出来就检查一下窗体的位置
	}
	
	/**
	 * @param newState 新的状态
	 * 一定要是此类中定义的3中状态之一
	 */
	public void setStates(int newState)
	{
		if(newState == NORMAL || newState == CANHIDD || newState == HIDDEN)
		{
			state = newState;
		}
	}
	
	/*
	 * 返回状态,注意此方法和setStates方法区别与JFrame中的setState()和getState()方法
	 */
	public int 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(CANHIDD);
		}		
	}
	
	public void moveToHidden()
	{
		if(hiddenPoint!=null)
		{
			WindowMover.moveToPoint(this, hiddenPoint);
			setStates(HIDDEN);
		}
	}
	
	public void showInfo(String info)
	{
		infoLabel.setText(info);
	}
	public void clearInfo()
	{
		infoLabel.setText("");
	}
}
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

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);
		// 当窗体移动就调用检查方法;
	}

	public static void checkAutoHiddenState(AutoHiddenFrame frame) {
		// 当窗体状态不是隐藏的,再进行检查
		if (frame.getStates() != AutoHiddenFrame.HIDDEN) {
			// 首先获得屏幕的大小和窗体的坐标
			Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
			Point hiddenPoint = frame.getLocation();

			Point visiblePoint = null;
			boolean canhidden = false;
			// 当窗体位于左边边缘
			if (hiddenPoint.x <= HIDDEN_BOUND) {
				hiddenPoint.move(VISIBLE_BOUND - frame.getWidth(),
						hiddenPoint.y);
				visiblePoint = new Point(0, hiddenPoint.y);
				canhidden = true;
			}
			// 当窗体位于上边
			else if (hiddenPoint.y <= HIDDEN_BOUND) {
				hiddenPoint.setLocation(hiddenPoint.x, VISIBLE_BOUND
						- frame.getHeight());
				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.getWidth(),
						hiddenPoint.y);
				canhidden = true;
			}
			if (canhidden) {
				// 如果符合以上几种情况的一种就可以隐藏
				frame.setVisiblePoint(visiblePoint);
				frame.setHiddenPoint(hiddenPoint);
				frame.setStates(AutoHiddenFrame.CANHIDD);
				frame.showInfo("进入可隐藏区域!");
			} else {
				// 如果不可以隐藏,那就是离开了边缘了
				if (frame.getStates() == AutoHiddenFrame.CANHIDD) {
					frame.showInfo("离开可应藏区域!");
				}
				frame.setVisiblePoint(frame.getLocation());
				frame.setStates(AutoHiddenFrame.NORMAL);
			}
		}
	}
}
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;

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() == AutoHiddenFrame.HIDDEN) {
			frame.moveToVisible();
		} else {
			frame.clearInfo();
		}

	}

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

	}

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

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

	public void windowLostFocus(WindowEvent e) {
		// 失去焦点,启动计时器
		if (frame.getStates() == AutoHiddenFrame.CANHIDD) {
			frame.showInfo("2秒后自动隐藏窗口!");
			timer.restart();
		}
	}
}
import java.awt.Point;
import java.awt.event.ComponentListener;

import javax.swing.JFrame;

public class WindowMover extends Thread {

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

	private static final 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() {

		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");
	}

}

你可能感兴趣的:(java,thread,swing)