Java Keylistener没有窗口打开?

我正在尝试用Java创建一个自动点击器(只有我知道的语言,我刚刚学习了Threads)。 我想让applet在它自己的窗口中打开(不在网页上),我希望能够在没有选择窗口的情况下使用空格键启动和停止程序,这样我就可以在另一个程序上使用自动点击器并且能够在没有alt-f4ing一堆东西的情况下阻止它。

有什么可以推荐给我的,可以帮助我吗? 或者你有什么建议吗?

这可能超出了Java applet的范围。 事实上,全局键盘钩子绝对不能简单地使用Java,但我可以帮助您朝着正确的方向前进。

但是,你有一些希望。 我将指出JNI(Java Native Interface)的方向,它允许您使用本机库。 现在,既然你想留在Java世界,我建议不要直接使用JNI,因为你必须编写一些令人困惑的本机代码(通常是C,C ++)。 JNI有几个包装器允许您使用这些function,但原生实现被抽象掉了,但其中很多都需要花钱。


因此,我认为最适合您的解决方案是JNA(Java Native Access) 。 这允许您直接从Java中调用本机库。 (注意:实现不是跨平台的。您必须为Windows,Linux等单独实现。)在项目网站的示例中有一个很好的Windows键盘钩子示例。

至于打开它自己的窗口而不是在网页中,你是否希望applet不能在浏览器中运行,而是在它自己的独立进程中运行,或者只是在一个单独的窗口中,仍然依赖浏览器窗口打开?

  • 如果您只想启动一个新窗口并仍然需要打开浏览器,那么这是一个很好的例子:

    final Frame window = new Frame("This is the Frame's Title Bar!"); window.add(new Label("This is the Frame.")); window.setSize(300,200); window.setVisible(true); window.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent we){ window.dispose(); } }); 
  • 如果您希望applet生成新进程并在不需要浏览器的情况下运行,请查看JavaFX 。

迟到的答案,但希望有帮助:)

你可以使用JNA,这是一个很棒的!

  1. 得到JNA(jna.jar)
  2. 在表单中为User32(User32.dll)创建自己的映射

    公共接口User32扩展了StdCallLibrary {
     User32 INSTANCE =(User32)Native.loadLibrary(“User32”,User32.class,Options.UNICODE_OPTIONS);
    
    
     // dwWakeMask常量
     public static final int QS_ALLEVENTS = 0x04BF;
     public static final int QS_ALLINPUT = 0x04FF;
     public static final int QS_ALLPOSTMESSAGE = 0x0100;
     public static final int QS_HOTKEY = 0x0080;
     public static final int QS_INPUT = 0x407;
     public static final int QS_KEY = 0x0001;
     public static final int QS_MOUSE = 0x0006;
     public static final int QS_MOUSEBUTTON = 0x0004;
     public static final int QS_MOUSEMOVE = 0x0002;
     public static final int QS_PAINT = 0x0020;
     public static final int QS_POSTMESSAGE = 0x0008;
     public static final int QS_RAWINPUT = 0x0400;
     public static final int QS_SENDMESSAGE = 0x0040;
     public static final int QS_TIMER = 0x0010;
    
    
     public static final int INFINITE = 0xFFFFFFFF;
    
    
     / *
     DWORD WINAPI MsgWaitForMultipleObjects(
     __in DWORD nCount,
     __in const HANDLE * pHandles,
     __in BOOL bWaitAll,
     __in DWORD dwMilliseconds,
     __in DWORD dwWakeMask
     ); * /
    
    
     int MsgWaitForMultipleObjects(int nCount,Pointer pHandles,boolean bWaitAll,int dwMilliSeconds,int dwWakeMask);
    
    
     / * fsModifiers vaues * /
     public static final int MOD_ALT = 0x0001;
     public static final int MOD_CONTROL = 0x0002;
     public static final int MOD_NOREPEAT = 0x4000;
     public static final int MOD_SHIFT = 0x0004;
     public static final int MOD_WIN = 0x0008;
    
    
     / * BOOL WINAPI RegisterHotKey(
     __in_opt HWND hWnd,
     __in int id,
     __在UINT fsModifiers中,
     __在UINT vk
     );
     * /
     boolean RegisterHotKey(Pointer hWnd,int id,int fsModifiers,int vk);
     }
    
  3. 只需查看以下页面,即可清楚了解工作原理:

ħ**号码://msdn.microsoft.com/en-us/library/ms646309%28VS.85%29.aspx

ħ**号码://msdn.microsoft.com/en-us/library/ms684242%28VS.85%29.aspx

  1. 检查此页面以查看可以注册回调的关键常量

ħ**号码://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx

  1. 创建一个这样的测试程序:
 User32 user32 = User32.INSTANCE;
 boolean res = user32.RegisterHotKey(Pointer.NULL,9999,User32.MOD_ALT | User32.MOD_CONTROL,WINUSER.VK_LEFT);
如果(!RES)
   System.out.println(“无法注册热键”);

 System.out.println(“正在等待”);
 user32.MsgWaitForMultipleObjects(0,Pointer.NULL,true,User32.INFINITE,User32.QS_HOTKEY);
的System.out.println( “结束”);

User32.INFINITE是一个未记录的常量,其值为0xFFFFFFFF

抱歉,http链接重命名为h ** p 🙂 Stackoverflow规则Stefano

我认为你可以使用setVisible(false)方法做到这一点。 窗口将在那里,但用户将无法看到它。