`

java实现靠边隐藏窗口

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

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


效果:










  • 大小: 136 KB
  • 大小: 143.6 KB
  • 大小: 135.6 KB
  • 大小: 137.5 KB
  • 大小: 200 KB
分享到:
评论

相关推荐

    仿QQ靠边隐藏窗口源码

    这个标题所指的“仿QQ靠边隐藏窗口源码”即是一个实例,它涉及到的是创建一个类似腾讯QQ聊天软件的窗口隐藏功能的源代码。QQ作为中国最流行的即时通讯工具之一,其界面设计和用户体验备受用户喜爱,特别是它的窗口...

    java swt 窗口靠边自动隐藏

    我们可以通过添加这样的监听器来实现窗口靠边时的自动隐藏。 3. **Bounds**:Shell对象有一个Bounds属性,它包含了窗口的左上角坐标(x, y)和宽度(width)、高度(height)。我们可以检查窗口的Bounds来判断是否...

    electron实现类似QQ窗口靠边自动边缘隐藏

    可以访问这篇文章有完整介绍: ... 最近做了一个electron+vue的项目,需要实现类似QQ边缘自动隐藏的功能。...后来发现通过监听鼠标在窗口的位置可以非常方便实现鼠标hover和out的判断,从而实现窗口自动隐现功能。

    窗口靠边吸附隐藏模块

    窗口靠边吸附隐藏模块是计算机用户界面中的一种实用功能,主要应用于桌面应用程序和操作系统中。这一功能使得用户在调整窗口大小时,可以方便地将窗口贴靠到屏幕边缘,实现快速隐藏或者占据屏幕的一半,从而提高工作...

    易语言源码程序靠边自动隐藏窗口.rar

    易语言源码程序靠边自动隐藏窗口.rar 易语言源码程序靠边自动隐藏窗口.rar 易语言源码程序靠边自动隐藏窗口.rar 易语言源码程序靠边自动隐藏窗口.rar 易语言源码程序靠边自动隐藏窗口.rar 易语言源码程序靠边...

    易语言程序靠边自动隐藏窗口

    然而,"程序靠边自动隐藏窗口"的功能更进一步,不仅提供了Aero Snap的便利,还增加了窗口隐藏的特性,使得窗口在不使用时可以完全消失在屏幕边缘,保持桌面整洁。 实现这一功能的关键在于监听窗口的位置变化和触发...

    VB仿QQ窗口靠边隐藏

    在VB(Visual Basic)编程中,"VB仿QQ窗口靠边隐藏"是一个常见的用户界面(UI)设计技巧,它使得程序窗口能够模仿QQ聊天窗口的行为,即当窗口靠近屏幕边缘时,可以自动隐藏,鼠标经过时又会动态显示。这个功能可以...

    C#实现QQ靠边隐藏

    本项目“C#实现QQ靠边隐藏”聚焦于一个特定的用户界面(UI)交互功能,即让应用程序窗口能够像QQ聊天窗口那样,根据用户的操作自动停靠到屏幕边缘并隐藏或显示。下面我们将详细探讨这一功能的实现原理和步骤。 首先...

    qq靠边隐藏功能

    首先,"QQ靠边隐藏"这一核心功能是指在电脑屏幕边缘快速隐藏或显示QQ窗口。在工作或学习时,用户可以将QQ窗口拖动到屏幕边缘,使其自动缩小为一条窄条或者完全隐藏,以保持桌面整洁,避免打扰。当需要查看消息或进行...

    C#窗体贴边自动隐藏实现方法

    本文将详细介绍C#窗体贴边自动隐藏实现方法的知识点,包括靠边隐藏效果的实现原理、判断窗体位置和屏幕四边的关系、使用timer判断鼠标和窗体的关系、钩子拦截系统消息、.Net 里面封装的事件、封装成一个.Net 组件等...

    易语言窗口靠边隐藏

    在"易语言窗口靠边隐藏"这个主题中,我们主要探讨的是如何使用易语言来实现窗口程序的一种常见功能——窗口靠边隐藏。这种功能在许多桌面应用中都很常见,比如当用户将窗口拖动到屏幕边缘时,窗口会自动调整大小或...

    winform实现QQ靠边隐藏及最小化到托盘代码模型

    "winform实现QQ靠边隐藏及最小化到托盘代码模型"这个主题涉及的是如何模仿QQ等流行软件的功能,即当窗口靠近屏幕边缘时自动隐藏,以及将窗口最小化至系统托盘区域,保持后台运行。这些特性提供了更流畅的用户体验,...

    QQ靠边隐藏功能的实现 (vb.net)

    通过这样的设计,我们可以创建一个类似QQ、飞信的靠边隐藏窗口应用程序,提高用户在多任务操作时的工作效率,同时也为桌面环境提供了更整洁的视觉体验。在VB.NET中实现这类功能,既体现了语言的灵活性,也展示了其在...

    模拟QQ靠边隐藏效果

    2. **Windows API函数**:为了实现窗口的吸附和隐藏效果,我们需要使用Windows API,如`GetSystemMetrics`来获取屏幕尺寸,`GetCursorPos`获取鼠标位置,以及`ScreenToClient`将屏幕坐标转换为窗口坐标。关键的API...

    易语言靠边自动隐藏模块源码

    在Windows应用程序开发中,"靠边自动隐藏"功能通常指的是窗口可以贴靠在屏幕边缘,并在不使用时自动隐藏,提高桌面的工作空间利用率。 这个模块可能包含了一系列的易语言代码,用于实现这样的功能。在描述中提到的...

    QQ窗体的靠边隐藏,上边、左边、右边

    在编程领域,窗体的靠边隐藏是一种常见的用户界面(UI)设计,它允许应用程序窗口在用户将它们拖动到屏幕边缘时自动调整大小或最小化,为用户提供更灵活的工作空间。这种功能在QQ等即时通讯软件中尤其常见,提高了...

    vb.net无边框+靠边隐藏窗体模板【源码】.rar

    2.内容2:窗体靠边自动隐藏,上下左右都可以;鼠标靠边自动显现窗体; 3.编译环境: windows10 vs2019 vb.net frameworke4.52 x86 4.因为自己做的是32位软件,预设是32位,可以直接自己改成any cpu

    易语言靠边隐藏模块演示源码,易语言自动隐藏模块

    3. 隐藏窗口:调用"调用API"命令,传入"ShowWindow" API名,以及获取到的窗口句柄和SW_HIDE参数,使窗口隐藏。 4. 监听事件:可以设置消息监听,当触发特定事件(如键盘、鼠标事件)时,再次显示窗口或保持隐藏状态...

    MFC仿QQ窗口靠边自动收缩隐藏效果

    本文将深入探讨如何使用MFC实现类似QQ的窗口靠边自动收缩隐藏效果,这是一种常见的用户界面(UI)特性,可以提高用户体验。 首先,我们需要了解MFC中的CWnd类,它是所有窗口类的基础。当我们创建一个MFC应用时,...

    易语言源码易语言窗口靠边隐藏源码.rar

    易语言源码易语言窗口靠边隐藏源码.rar 易语言源码易语言窗口靠边隐藏源码.rar 易语言源码易语言窗口靠边隐藏源码.rar 易语言源码易语言窗口靠边隐藏源码.rar 易语言源码易语言窗口靠边隐藏源码.rar 易语言源码...

Global site tag (gtag.js) - Google Analytics