//AutoHiddenFrame
/*<br /> * To change this template, choose Tools | Templates<br /> * and open the template in the editor.<br /> */<br />package autohiddenframe;<br />import java.awt.BorderLayout;<br />import java.awt.Insets;<br />import java.awt.Point; </p><p>import javax.swing.JFrame;<br />import javax.swing.JLabel;<br />import javax.swing.JPanel;<br />/**<br /> *<br /> * @author Administrator<br /> */<br />public class AutoHiddenFrame extends JFrame {<br /> /**<br /> * @param args the command line arguments<br /> */<br /> private static final long serialVersionUID = 1L;<br /> public static void main(String args[])<br /> {<br /> new AutoHiddenFrame();<br /> } </p><p> public static final int NORMAL = 0; //表單的普通狀態<br /> public static final int CANHIDD = 1; //表單位於螢幕邊緣,可以隱藏的狀態<br /> public static final int HIDDEN = 2; //表單處於隱藏狀態 </p><p> private int state = NORMAL; //表單的狀態,讓它初始化為普通狀態<br /> private Point hiddenPoint; //隱藏表單時,表單的位置<br /> private Point visiblePoint; //表單處於顯示狀態時的位置 </p><p> private JLabel infoLabel; //用於顯示資訊的JLabel;<br /> public AutoHiddenFrame()<br /> {<br /> JPanel p = new JPanel(new BorderLayout()) {<br /> private static final long serialVersionUID = 1L; </p><p> public Insets getInsets()<br /> {<br /> return new Insets(3,3,3,3);<br /> }<br /> };<br /> setContentPane(p); //替換掉原來的ContentPane,換上一個帶有Insets的,至於為什麼去看WindowMouseListener類<br /> infoLabel = new JLabel();<br /> add(infoLabel,BorderLayout.SOUTH);<br /> setSize(300,200);<br /> setDefaultCloseOperation(EXIT_ON_CLOSE);<br /> setVisible(true); </p><p> new WindowLocationListener(this);<br /> new WindowMouseListener(this);<br /> WindowLocationListener.checkAutoHiddenState(this);//剛出來就檢查一下表單的位置<br /> } </p><p> /**<br /> * @param newState 新的狀態<br /> * 一定要是此類中定義的3中狀態之一<br /> */<br /> public void setStates(int newState)<br /> {<br /> if(newState == NORMAL || newState == CANHIDD || newState == HIDDEN)<br /> {<br /> state = newState;<br /> }<br /> } </p><p> /*<br /> * 返回狀態,注意此方法和setStates方法區別與JFrame中的setState()和getState()方法<br /> */<br /> public int getStates()<br /> {<br /> return state;<br /> }<br /> /*<br /> * 設定要顯示時表單的座標<br /> */<br /> public void setVisiblePoint(Point point)<br /> {<br /> visiblePoint = point;<br /> }<br /> /*<br /> * 設定要隱藏是表單的座標<br /> */<br /> public void setHiddenPoint(Point point)<br /> {<br /> hiddenPoint = point;<br /> } </p><p> public void moveToVisible()<br /> {<br /> if(visiblePoint!=null)<br /> {<br /> WindowMover.moveToPoint(this, visiblePoint);<br /> setStates(CANHIDD);<br /> }<br /> } </p><p> public void moveToHidden()<br /> {<br /> if(hiddenPoint!=null)<br /> {<br /> WindowMover.moveToPoint(this, hiddenPoint);<br /> setStates(HIDDEN);<br /> }<br /> } </p><p> public void showInfo(String info)<br /> {<br /> infoLabel.setText(info);<br /> }<br /> public void clearInfo()<br /> {<br /> infoLabel.setText("");<br /> }</p><p>}<br />
WindowLocationListener.java
/*<br /> * To change this template, choose Tools | Templates<br /> * and open the template in the editor.<br /> */<br />package autohiddenframe;<br />import java.awt.Dimension;<br />import java.awt.Point;<br />import java.awt.Toolkit;<br />import java.awt.event.ComponentAdapter;<br />import java.awt.event.ComponentEvent;<br />/**<br /> *<br /> * @author Administrator<br /> */<br />public class WindowLocationListener extends ComponentAdapter {<br /> public static final int HIDDEN_BOUND = 3; // 當表單進入到螢幕邊緣3像素以內就可以隱藏 </p><p> public static final int VISIBLE_BOUND = 5; // 當表單隱藏後要有5像素的部分露出來,不能完全隱藏 </p><p> AutoHiddenFrame frame; </p><p> public WindowLocationListener(AutoHiddenFrame a) {<br /> frame = a;<br /> frame.addComponentListener(this);<br /> } </p><p> public void componentMoved(ComponentEvent e) {<br /> checkAutoHiddenState(frame);<br /> // 當表單移動就調用檢查方法;<br /> } </p><p> public static void checkAutoHiddenState(AutoHiddenFrame frame) {<br /> // 當表單狀態不是隱藏的,再進行檢查<br /> if (frame.getStates() != AutoHiddenFrame.HIDDEN) {<br /> // 首先獲得螢幕的大小和表單的座標<br /> Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();<br /> Point hiddenPoint = frame.getLocation(); </p><p> Point visiblePoint = null;<br /> boolean canhidden = false;<br /> // 當表單位於左邊邊緣<br /> if (hiddenPoint.x <= HIDDEN_BOUND) {<br /> hiddenPoint.move(VISIBLE_BOUND - frame.getWidth(),<br /> hiddenPoint.y);<br /> visiblePoint = new Point(0, hiddenPoint.y);<br /> canhidden = true;<br /> }<br /> // 當表單位於上邊<br /> else if (hiddenPoint.y <= HIDDEN_BOUND) {<br /> hiddenPoint.setLocation(hiddenPoint.x, VISIBLE_BOUND<br /> - frame.getHeight());<br /> visiblePoint = new Point(hiddenPoint.x, 0);<br /> canhidden = true;<br /> }<br /> // 當表單位於右邊<br /> else if (hiddenPoint.x + frame.getWidth() >= screenSize.width<br /> - HIDDEN_BOUND) {<br /> hiddenPoint.setLocation(screenSize.width - VISIBLE_BOUND,<br /> hiddenPoint.y);<br /> visiblePoint = new Point(screenSize.width - frame.getWidth(),<br /> hiddenPoint.y);<br /> canhidden = true;<br /> }<br /> if (canhidden) {<br /> // 如果符合以上幾種情況的一種就可以隱藏<br /> frame.setVisiblePoint(visiblePoint);<br /> frame.setHiddenPoint(hiddenPoint);<br /> frame.setStates(AutoHiddenFrame.CANHIDD);<br /> frame.showInfo("進入可隱藏地區!");<br /> } else {<br /> // 如果不可以隱藏,那就是離開了邊緣了<br /> if (frame.getStates() == AutoHiddenFrame.CANHIDD) {<br /> frame.showInfo("離開可應藏地區!");<br /> }<br /> frame.setVisiblePoint(frame.getLocation());<br /> frame.setStates(AutoHiddenFrame.NORMAL);<br /> }<br /> }<br /> } </p><p>}<br />
WindowMouseListener.java
/*<br /> * To change this template, choose Tools | Templates<br /> * and open the template in the editor.<br /> */<br />package autohiddenframe;<br />import java.awt.Container;<br />import java.awt.MouseInfo;<br />import java.awt.Point;<br />import java.awt.event.ActionEvent;<br />import java.awt.event.ActionListener;<br />import java.awt.event.MouseAdapter;<br />import java.awt.event.MouseEvent;<br />import java.awt.event.WindowEvent;<br />import java.awt.event.WindowFocusListener; </p><p>import javax.swing.SwingUtilities;<br />import javax.swing.Timer;<br />/**<br /> *<br /> * @author Administrator<br /> */<br />public class WindowMouseListener extends MouseAdapter implements<br /> ActionListener, WindowFocusListener {<br /> private Timer timer; </p><p> private AutoHiddenFrame frame; </p><p> Container container; </p><p> public WindowMouseListener(AutoHiddenFrame a) {<br /> frame = a;<br /> container = frame.getContentPane();<br /> container.addMouseListener(this);<br /> // 註冊滑鼠接聽程式到ContentPane上,因為我們可以加大它的Insets以提高滑鼠進入和離開的靈敏度<br /> frame.addWindowFocusListener(this);<br /> // 註冊一個焦點接聽程式到表單上<br /> timer = new Timer(2000, this);<br /> timer.setRepeats(false);<br /> } </p><p> public void mouseEntered(MouseEvent e) {<br /> // 當滑鼠進入,就顯示表單<br /> if (frame.getStates() == AutoHiddenFrame.HIDDEN) {<br /> frame.moveToVisible();<br /> } else {<br /> frame.clearInfo();<br /> } </p><p> } </p><p> public void mouseExited(MouseEvent e) {<br /> // 當滑鼠離開,啟動計時器<br /> if (frame.getStates() == AutoHiddenFrame.CANHIDD) {<br /> if (!container.contains(e.getPoint())) {<br /> frame.showInfo(timer.getDelay() / 1000 + "秒後自動隱藏視窗!");<br /> // System.out.println("Mouse has exited the Dialog!");<br /> timer.restart();<br /> }<br /> } </p><p> } </p><p> public void actionPerformed(ActionEvent e) {<br /> // 計時器到期,檢查滑鼠是不是還在此表單裡面,不再的話,再開始隱藏<br /> Point p = MouseInfo.getPointerInfo().getLocation();<br /> SwingUtilities.convertPointFromScreen(p, container);<br /> if (!container.contains(p)<br /> && frame.getStates() == AutoHiddenFrame.CANHIDD) {<br /> frame.moveToHidden();<br /> } else {<br /> frame.clearInfo();<br /> }<br /> } </p><p> public void windowGainedFocus(WindowEvent e) {<br /> // 得到焦點檢查滑鼠是不是在表單上<br /> Point p = MouseInfo.getPointerInfo().getLocation();<br /> SwingUtilities.convertPointFromScreen(p, container);<br /> if (container.contains(p)<br /> && frame.getStates() == AutoHiddenFrame.HIDDEN) {<br /> frame.moveToVisible();<br /> }<br /> } </p><p> public void windowLostFocus(WindowEvent e) {<br /> // 失去焦點,啟動計時器<br /> if (frame.getStates() == AutoHiddenFrame.CANHIDD) {<br /> frame.showInfo("2秒後自動隱藏視窗!");<br /> timer.restart();<br /> }<br /> } </p><p>}<br />
WindowMover.java
/*<br /> * To change this template, choose Tools | Templates<br /> * and open the template in the editor.<br /> */<br />package autohiddenframe;<br />import java.awt.Point;<br />import java.awt.event.ComponentListener; </p><p>import javax.swing.JFrame;<br />/**<br /> *<br /> * @author Administrator<br /> */<br />public class WindowMover extends Thread {<br /> public static void moveToPoint(JFrame dialog, Point targetPoint) {<br /> new WindowMover(dialog, targetPoint).start();<br /> } </p><p> private static final int FRAMES = 15; // 最多移動多少動畫幀 </p><p> private JFrame window; // 要移動的視窗 </p><p> private Point point; // 目的座標 </p><p> private int index; // 當前幀數 </p><p> private int addedX; // 每次移動的X座標增量 </p><p> private int addedY; // 每次移動的Y座標的增量 </p><p> ComponentListener componentListeners[];// 組件接聽程式數組 </p><p> /*<br /> * 定義私人的構造方法,應調用靜態方法moveToPoint;<br /> */<br /> private WindowMover(JFrame window, Point targetPoint) {<br /> this.window = window;<br /> window.getGlassPane().setVisible(true);<br /> // 設定此表單的GlassPane為顯示的,以阻止子組件接收滑鼠事件,減少事件觸發 </p><p> // 同樣,移除此表單上的組件接聽程式,防止再次觸發表單移動事件<br /> componentListeners = window.getComponentListeners(); </p><p> for (ComponentListener cl : componentListeners) {<br /> window.removeComponentListener(cl);<br /> } </p><p> Point wl = window.getLocation();<br /> point = targetPoint;<br /> index = 0; // 初始化幀書為0; </p><p> // 計算每次移動量<br /> addedX = (point.x - wl.x) / FRAMES;<br /> if (addedX == 0 && point.x != wl.x) {<br /> addedX = point.x < wl.x ? -1 : 1;<br /> }<br /> addedY = (point.y - wl.y) / FRAMES;<br /> if (addedY == 0 && point.y != wl.y) {<br /> addedY = point.y < wl.y ? -1 : 1;<br /> }<br /> } </p><p> public void run() { </p><p> if (window.getLocation().equals(point))<br /> return;// 如果已在目的點,則返回<br /> if (!window.isVisible())<br /> return;// 如果視窗是不可視的則返回 </p><p> while (index < FRAMES) {<br /> Point p = window.getLocation();<br /> if (p.x != point.x)<br /> p.translate(addedX, 0);<br /> if (p.y != point.y)<br /> p.translate(0, addedY);<br /> window.setLocation(p);<br /> index++;<br /> try {<br /> Thread.sleep(15); </p><p> } catch (Exception e) {<br /> }<br /> }<br /> window.setLocation(point);<br /> // 還原所做的操作<br /> window.getGlassPane().setVisible(false);<br /> for (ComponentListener cl : componentListeners) {<br /> window.addComponentListener(cl);<br /> }<br /> // 釋放資源,使gc可以回收此對象<br /> window = null;<br /> point = null;<br /> componentListeners = null;<br /> System.out.println("finsh Moved");<br /> } </p><p>}<br />