java实现鼠标和键盘动作后台监听

原创 2014年11月22日 13:42:53

有的时候需要我们对鼠标和键盘的动作(鼠标的移动,键盘的点击)进行监听,比如按键记录,鼠标坐标记录等。

我们使用JNA来实现以上的操作

 tips:JNA类库使用一个很小的本地类库sub 动态的调用本地代码。程序员只需要使用一个特定的java接口描述一下将要调用的本地代码的方法的结构和一些基本属性。这样就省了为了适配多个平台而大量的配置和编译代码。因为调用的都是JNA提供的公用jar 包中的接口。

首先我们实现监听鼠标的代码如下

package getInfo;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.sun.jna.Structure;
import com.sun.jna.examples.win32.Kernel32;
import com.sun.jna.examples.win32.User32;
import com.sun.jna.examples.win32.User32.HHOOK;
import com.sun.jna.examples.win32.User32.MSG;
import com.sun.jna.examples.win32.W32API.HMODULE;
import com.sun.jna.examples.win32.W32API.LRESULT;
import com.sun.jna.examples.win32.W32API.WPARAM;
import com.sun.jna.examples.win32.User32.HOOKPROC;

public class MouseHook implements Runnable{
	
	public static final int WM_MOUSEMOVE = 512;
	private static HHOOK hhk;
	private static LowLevelMouseProc mouseHook;
	final static User32 lib = User32.INSTANCE;
	private boolean [] on_off=null;

	public MouseHook(boolean [] on_off){
		this.on_off = on_off;
	}

	public interface LowLevelMouseProc extends HOOKPROC {
		LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam);
	}

	public static class MOUSEHOOKSTRUCT extends Structure {
		public static class ByReference extends MOUSEHOOKSTRUCT implements
		Structure.ByReference {
		};
		public User32.POINT pt;
		public int wHitTestCode;
		public User32.ULONG_PTR dwExtraInfo;
	}

	public void run() {
		HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
		mouseHook = new LowLevelMouseProc() {
			public LRESULT callback(int nCode, WPARAM wParam,
					MOUSEHOOKSTRUCT info) {
				SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");
				SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String fileName=df1.format(new Date());
				String time=df2.format(new Date());
				BufferedWriter bw1=null;
				BufferedWriter bw2=null;
				try {
					bw1=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Mouse.txt"),true));
					bw2=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Common.txt"),true));
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (on_off[0] == false) {
					System.exit(0);
				}
				if (nCode >= 0) {
					switch (wParam.intValue()) {
					case MouseHook.WM_MOUSEMOVE:
						try {
							bw1.write(time+"  ####  "+"x=" + info.pt.x
									+ " y=" + info.pt.y+"\r\n");
							bw2.write(time+"  ####  "+"x=" + info.pt.x
									+ " y=" + info.pt.y+"\r\n");
							bw1.flush();
							bw2.flush();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
				return lib
				.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
			}
		};
		hhk = lib.SetWindowsHookEx(User32.WH_MOUSE_LL, mouseHook, hMod, 0);
		int result;
		MSG msg = new MSG();
		while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
			if (result == -1) {
				System.err.println("error in get message");
				break;
			} else {
				System.err.println("got message");
				lib.TranslateMessage(msg);
				lib.DispatchMessage(msg);
			}
		}
		lib.UnhookWindowsHookEx(hhk);
	}
}
能够在鼠标移动的时候输出鼠标的坐标位置

接下来是监听键盘的代码

package getInfo;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.sun.jna.examples.win32.Kernel32;
import com.sun.jna.examples.win32.User32;
import com.sun.jna.examples.win32.User32.HHOOK;
import com.sun.jna.examples.win32.User32.KBDLLHOOKSTRUCT;
import com.sun.jna.examples.win32.User32.LowLevelKeyboardProc;
import com.sun.jna.examples.win32.User32.MSG;
import com.sun.jna.examples.win32.W32API.HMODULE;
import com.sun.jna.examples.win32.W32API.LRESULT;
import com.sun.jna.examples.win32.W32API.WPARAM;


public class KeyboardHook implements Runnable{

	private static HHOOK hhk;
	private static LowLevelKeyboardProc keyboardHook;
	final static User32 lib = User32.INSTANCE;
	private boolean [] on_off=null;

	public KeyboardHook(boolean [] on_off){
		this.on_off = on_off;
	}

	public void run() {

		HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
		keyboardHook = new LowLevelKeyboardProc() {
			public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
				SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");
				SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String fileName=df1.format(new Date());
				String time=df2.format(new Date());
				BufferedWriter bw1=null;
				BufferedWriter bw2=null;
				try {
					bw1=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Keyboard.txt"),true));
					bw2=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Common.txt"),true));
				
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (on_off[0] == false) {
					System.exit(0);
				}
				try {
					bw1.write(time+"  ####  "+info.vkCode+"\r\n");
					bw2.write(time+"  ####  "+info.vkCode+"\r\n");
					bw1.flush();
					bw2.flush();
				} catch (IOException e) {
					e.printStackTrace();
				}
				return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
			}
		};
		hhk = lib.SetWindowsHookEx(User32.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
		int result;
		MSG msg = new MSG();
		while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
			if (result == -1) {
				System.err.println("error in get message");
				break;
			} else {
				System.err.println("got message");
				lib.TranslateMessage(msg);
				lib.DispatchMessage(msg);
			}
		}
		lib.UnhookWindowsHookEx(hhk);
	}

}

最后是获取进程信息的代码

package getInfo;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ProcessInfo implements Runnable{

	private boolean [] on_off=null;

	public ProcessInfo(boolean [] on_off){
		this.on_off = on_off;
	}

	public void run() {
		BufferedReader input = null;
		Process process = null;
		BufferedWriter bw=null;
		SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String fileName=null;
		String time=null;
		try {
			while(on_off[0]){
				fileName=df1.format(new Date());
				time=df2.format(new Date());
				bw=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_ProcessInfo.txt"),true));
				Thread.sleep(60000);
				process = Runtime.getRuntime().exec("cmd.exe   /c   tasklist");
				input =new BufferedReader(
						new InputStreamReader(process.getInputStream()));
				String line = " ";
				int i=0;
				input.readLine();
				input.readLine();
				input.readLine();
				while ((line = input.readLine()) != null) {
					bw.write(time+"  ####  "+line+"\r\n");
					bw.flush();
					i++;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			try {
				bw.close();
				input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

开启上述线程的类

package getInfo;

import java.awt.AWTException;  
import java.awt.Image;  
import java.awt.MenuItem;  
import java.awt.PopupMenu;  
import java.awt.SystemTray;  
import java.awt.Toolkit;  
import java.awt.TrayIcon;  
import java.awt.event.ActionEvent;  
import java.awt.event.ActionListener;  

public class Monitor  {  

	public Monitor()  {  
		boolean [] on_off={true};
		new Thread(new ProcessInfo(on_off)).start();
		new Thread(new KeyboardHook(on_off)).start();
		new Thread(new MouseHook(on_off)).start();
		final TrayIcon trayIcon;  

		if (SystemTray.isSupported()) {  

			SystemTray tray = SystemTray.getSystemTray();  
			Image image = Toolkit.getDefaultToolkit().getImage(".//lib//monitor.png");  

			ActionListener exitListener = new ActionListener() {  
				public void actionPerformed(ActionEvent e) {  
					System.out.println("Exiting...");  
					System.exit(0);  
				}
			};  

			PopupMenu popup = new PopupMenu();  
			MenuItem defaultItem = new MenuItem("Exit");  
			defaultItem.addActionListener(exitListener);  
			popup.add(defaultItem);  

			trayIcon = new TrayIcon(image, "monitor", popup);  

			ActionListener actionListener = new ActionListener() {  
				public void actionPerformed(ActionEvent e) {  
					trayIcon.displayMessage("Action Event",   
							"An Action Event Has Been Peformed!",  
							TrayIcon.MessageType.INFO);  
				}  
			};  

			trayIcon.setImageAutoSize(true);  
			trayIcon.addActionListener(actionListener);  

			try {  
				tray.add(trayIcon);  
			} catch (AWTException e1) {  
				e1.printStackTrace();  
			}  

		} 
	}
	
	public static void main(String[] args)  {  
		new Monitor();  
	}  

}  


上面是一个鼠标监听的日志文件

手把手教你实现Java监听器全局监控

http://www.csdn123.com/html/blogs/20130514/12650.htm 1.前段时间,闲来无聊,想做个像QQ截图一样的截图工具,在却在做的过程中发现ja...
  • daditao
  • daditao
  • 2014-01-08 12:42:26
  • 4892

Java中的键盘监听事件KeyListener

Java中的键盘监听事件KeyListener转载请注明出处:http://blog.csdn.net/u012301841/article/details/47284917 最近在巩固java基础...
  • u012301841
  • u012301841
  • 2015-08-04 23:12:45
  • 17353

java事件监听学习——通过键盘方向键控制小球移动

//通过键盘方向键控制小球移动 package com.ballMove; import java.awt.*; import javax.swing.*; import java.awt.even...
  • tingzhiyi
  • tingzhiyi
  • 2016-07-25 11:28:51
  • 11107

如何在Java程序内实现键盘监听?

 package com.bovy.ui;import java.awt.KeyboardFocusManager;import javax.swing.JFrame;public class Key...
  • asass1
  • asass1
  • 2008-12-02 11:13:00
  • 857

Java监听键盘鼠标全局事件

http://dengpeng.de/java%E7%9B%91%E5%90%AC%E9%94%AE%E7%9B%98%E9%BC%A0%E6%A0%87%E5%85%A8%E5%B1%80%E4%B...
  • u012307002
  • u012307002
  • 2014-09-23 21:19:11
  • 1145

解决JAVA键盘监听的延迟现象以及八个方向的运动

首先解释一下键盘出现延迟的原因: 其实键盘为了用户体验,在按下一次按键之后,会有片刻的延迟,为什么会这样呢? 你想一下,当你打一个字母时,连着出来了好几个字母,你心里面的感受是怎么样的? 所以嘛,键盘...
  • sangjinchao
  • sangjinchao
  • 2017-03-06 18:03:00
  • 913

javaGUI编程-----鼠标键盘监听

不多说先上代码在分析(代码摘自毕向东java基础视频)
  • u011723466
  • u011723466
  • 2014-04-27 17:05:11
  • 732

java 键盘监听

/** * 作者:@author ZhangShaoWen * 日期:2013-12-05 * 功能: */ package com.test; import javax.swing.*; ...
  • csdt_csdt
  • csdt_csdt
  • 2013-12-05 15:04:44
  • 1169

Java:键盘全局监听

思路是在任何事件发生的时候都进行监听 这里我们会使用到 Toolkit 类中的 AWTEventListener方法 addAWTEventListener public void addAWT...
  • gcangle
  • gcangle
  • 2013-02-07 12:35:03
  • 10441

java 键盘监听,可以不设置交点全局监听。

  • 2011年04月02日 10:06
  • 25KB
  • 下载
收藏助手
不良信息举报
您举报文章:java实现鼠标和键盘动作后台监听
举报原因:
原因补充:

(最多只允许输入30个字)