想实现一个后台程序,监听鼠标/键盘事件,记录下时间。
awt或swt可以实现类似功能不?看了下awt的Toolkit,不太会用。只是想统计下自己电脑每天的使用时间。

解决方案 »

  1.   


    awt and swt实现不了您这个需求需要使用JNI调用C++具体如下,C++// syshook.cpp
    /*
     * SysHook - 7/17/05
     * Jacob Gohlke
     *
     * JNI Interface for setting a Keyboard Hook and monitoring
     * it Java-side
     *
     * (c) Copyright 2005 Jacob Gohlke
     *
     * Feel free to use and learn from this code, royalty-free!
     * I only ask you acknkowlege what library you are using
     * and who made it. Thanks, and happy hooking!
     */
     
    #include <windows.h>
    #include <winuser.h>
    #include "jni.h"
    #include "syshook.h"
     
    #pragma data_seg(".HOOKDATA") //Shared data among all instances.
    static HHOOK hkb = NULL;
    static HANDLE g_hModule = NULL;
    static WPARAM g_wParam = NULL;
    static LPARAM g_lParam = NULL;
     
    JNIEXPORT void NotifyJava(JNIEnv *env, jobject obj, WPARAM wParam, LPARAM lParam)
    {
    jclass cls = env->GetObjectClass(obj);
    jmethodID mid;
     
    mid = env->GetMethodID(cls, "Callback", "(ZIZZ)V");
    if (mid == NULL) 
    return;
     
    if( (HIWORD( lParam ) & KF_UP) )
    env->CallVoidMethod(obj, mid, (jboolean)FALSE, (jint)(wParam), (jboolean)(HIWORD( lParam ) & KF_ALTDOWN), (jboolean)(HIWORD( lParam ) & KF_EXTENDED));
    else
    env->CallVoidMethod(obj, mid, (jboolean)TRUE, (jint)(wParam), (jboolean)(HIWORD( lParam ) & KF_ALTDOWN), (jboolean)(HIWORD( lParam ) & KF_EXTENDED));
    }
     
    #pragma data_seg() 
     
    #pragma comment(linker, "/SECTION:.HOOKDATA,RWS")
     
    JNIEXPORT LRESULT CALLBACK HookKeyboardProc(INT nCode, WPARAM wParam, LPARAM lParam) 
    {
        if (nCode < 0)  // do not process message 
    return CallNextHookEx(hkb, nCode, wParam, lParam); 
     
    g_wParam = wParam;
    g_lParam = lParam;
    return CallNextHookEx(hkb, nCode, wParam, lParam);

     
    JNIEXPORT void JNICALL Java_PollThread_checkKeyboardChanges(JNIEnv *env, jobject obj)
    {
    if(g_wParam != NULL && g_lParam != NULL)
    {
    NotifyJava(env, obj, g_wParam, g_lParam);
    g_wParam = NULL;
    g_lParam = NULL;
    }
    }
     
    static void Init()
    {
    hkb = SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)HookKeyboardProc, (HINSTANCE)g_hModule, 0 );
    }
     
    static void Cleanup()
    {
    if( hkb != NULL )
    UnhookWindowsHookEx( hkb );
     
    hkb = NULL;
    }
     
    BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
    {
    switch(ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    g_hModule = hModule;
    Init();
    return TRUE;
     
    case DLL_PROCESS_DETACH:
    Cleanup();
    return TRUE;
    }
     
        return TRUE;
    }
    // syshook.h
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include "jni.h"
    /* Header for class PollThread */
     
    #ifndef _Included_PollThread
    #define _Included_PollThread
    #ifdef __cplusplus
    extern "C" {
    #endif
    #undef PollThread_MIN_PRIORITY
    #define PollThread_MIN_PRIORITY 1L
    #undef PollThread_NORM_PRIORITY
    #define PollThread_NORM_PRIORITY 5L
    #undef PollThread_MAX_PRIORITY
    #define PollThread_MAX_PRIORITY 10L
    /*
     * Class:     PollThread
     * Method:    checkKeyboardChanges
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_PollThread_checkKeyboardChanges
      (JNIEnv *, jobject);
     
    #ifdef __cplusplus
    }
    #endif
    #endif
    Java://KeyboardEvent.java
    import java.util.*;
     
    public class KeyboardEvent extends EventObject
    {
    boolean ts, ap, ek;
    int vk;
     
    public KeyboardEvent( Object source, boolean ts, int vk, boolean ap, boolean ek )
    {
    super(source);
    this.ts = ts;
    this.vk = vk;
    this.ap = ap;
    this.ek = ek;
    }
     
    public boolean getTransitionState()
    {
    return ts;
    }
     
    public long getVirtualKeyCode()
    {
    return vk;
    }
     
    public boolean isAltPressed()
    {
    return ap;
    }
     
    public boolean isExtendedKey()
    {
    return ek;
    }
     
    public boolean equals( KeyboardEvent event )
    {
    if( event.getVirtualKeyCode() == vk )
    {
    if( event.isExtendedKey() == ek )
    {
    if( event.isAltPressed() == ap )
    {
    return true;
    }
    }
    }
    return false;
    }
    }// KeyboardEventListener.java
    import java.util.*;
     
    public interface KeyboardEventListener extends EventListener
    {
    public void GlobalKeyPressed( KeyboardEvent event );
    public void GlobalKeyReleased( KeyboardEvent event );
    }
    // KeyboardHook.java
    import java.io.*;
     
    public class KeyboardHook
    {
    public KeyboardHook()
    {
    ( new PollThread(this) ).start();
    }
     
    protected javax.swing.event.EventListenerList listenerList = new javax.swing.event.EventListenerList();
     
    public void addEventListener(KeyboardEventListener listener)
    {
    listenerList.add( KeyboardEventListener.class, listener );
    }
     
    public void removeEventListener(KeyboardEventListener listener)
    {
    listenerList.remove( KeyboardEventListener.class, listener );
    }
     
    void keyPressed(KeyboardEvent event)
    {
    Object[] listeners = listenerList.getListenerList();
    for ( int i = 0; i < listeners.length; i += 2 )
    {
    if ( listeners[ i ] == KeyboardEventListener.class )
    {
    ( (KeyboardEventListener)listeners[i + 1] ).GlobalKeyPressed( event );
    }
    }
    }
     
    void keyReleased(KeyboardEvent event)
    {
    Object[] listeners = listenerList.getListenerList();
    for ( int i = 0; i < listeners.length; i += 2 )
    {
    if ( listeners[ i ] == KeyboardEventListener.class )
    {
    ( (KeyboardEventListener)listeners[i + 1] ).GlobalKeyReleased( event );
    }
    }
    }
    }
     
    class PollThread extends Thread
    {
    public native void checkKeyboardChanges();
    private KeyboardHook kbh;
     
    public PollThread( KeyboardHook kh )
    {
    kbh = kh;
    System.loadLibrary("syshook");
    }
     
    public void run()
    {
    for(;;)
    {
    checkKeyboardChanges();
    yield();
    }
    }
     
    void Callback( boolean ts, int vk, boolean ap, boolean ek )
    {
    KeyboardEvent event = new KeyboardEvent( this, ts, vk, ap, ek );
    if( ts )
    {
    kbh.keyPressed( event );
    }
    else
    {
    kbh.keyReleased( event );
    }
    }
    }Example Java Usage:// Test.java
    import java.io.*;
     
    public class Test implements KeyboardEventListener
    {
    public static void main( String args[] )
    {
    KeyboardHook kh = new KeyboardHook();
    kh.addEventListener( new Test() );
    BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
    try{
    br.readLine();
    } catch( IOException ex ) {}
    }
     
    public void GlobalKeyPressed( KeyboardEvent event )
    {
    System.out.println( "Key Pressed: " + event.getVirtualKeyCode() );
    }
     
    public void GlobalKeyReleased( KeyboardEvent event )
    {
    System.out.println( "Key Released: " + event.getVirtualKeyCode() );
    }
    }
      

  2.   


    直接看windows的事件查看器么拉倒。或者去解析它
      

  3.   

    看来java做这个事真是不适合啊
      

  4.   

    如果是监控自己的awt或swing窗口的事件,可以做到
    如果是监控系统的事件,那纯java就做不到了,因为java运行于JVM,并非直接跟系统打交道
    如果想实现这样的功能,那就要用JNI(java本地方法),调用其他直接跟系统打交道的程序语言开发的程序,如4楼所说