我正在使用robot类用java编写一个小程序。程序接管了鼠标。在调试过程中,如果它开始以我不希望的方式运行,很难退出程序,因为在eclipse中我不能将鼠标移到终止按钮上,并且我不能使用热键来点击它,因为鼠标在另一个窗口中不断地点击,而是给那个窗口焦点。
我想做的是连接一个keylister,这样当我按q时就可以退出程序,但我知道的唯一方法是创建一个窗口,这个窗口需要焦点来捕获输入。有没有一种方法可以从任何地方监听键盘或鼠标的输入,而不管什么东西有焦点?
我正在使用robot类用java编写一个小程序。程序接管了鼠标。在调试过程中,如果它开始以我不希望的方式运行,很难退出程序,因为在eclipse中我不能将鼠标移到终止按钮上,并且我不能使用热键来点击它,因为鼠标在另一个窗口中不断地点击,而是给那个窗口焦点。
我想做的是连接一个keylister,这样当我按q时就可以退出程序,但我知道的唯一方法是创建一个窗口,这个窗口需要焦点来捕获输入。有没有一种方法可以从任何地方监听键盘或鼠标的输入,而不管什么东西有焦点?
7条答案
按热度按时间l2osamch1#
让你的程序打开第二个窗口,它显示在你的主窗口下面,但是被最大化了,那么你的鼠标错误点击都会被最大化的窗口接收,它可以接收你的键盘输入。
ca1c2owp2#
这不是一个微不足道的问题,java并没有为您提供一种优雅的方法。您可以使用Banjolly建议的解决方案,但即使这样也不会一直有效,例如,如果您错误地单击鼠标打开当前在任务栏中打开的另一个完整窗口。
事实是,java默认情况下对操作系统的控制很少。这是由两个主要原因造成的:安全性(正如java文档中提到的)和不同操作系统处理事件的方式完全不同的事实,而让一个统一的模型来表示所有这些可能没有多大意义。
所以要回答你的问题,我想你想要的是你的程序的某种行为,它在全球范围内监听按键,而不仅仅是在你的应用程序中。像这样的事情需要您访问所选操作系统提供的功能,而要用java访问它,您需要通过java本机接口(jni)层来访问它。
所以你要做的是:
用c语言实现一个程序,在你的操作系统上监听全局按键,如果这个操作系统是windows,那么在windows钩子上查找文档,这些文档由microsoft和msdn在web和其他地方很好地记录。如果您的操作系统是linux或macosx,那么您将需要使用x11开发库监听全局按键。这可以在ubunutulinux发行版上根据我在上写的howto来完成http://ubuntuforums.org/showthread.php?t=864566
通过jni将c代码连接到java代码。这一步实际上是更简单的一步。按照我在上的教程中使用的步骤操作http://ubuntuforums.org/showthread.php?t=864566 在windows和linux下,将c代码连接到java代码的过程在两个操作系统上是相同的。
要记住的重要一点是,如果您首先编写和调试c/c++代码并确保它正常工作,那么让jni代码正常工作就容易多了。那么将它与java集成就很容易了。
afdcj2ne3#
(如@masterid所述,并在jnativehook的本机键盘输入检测文档{main github project here}中显示),
此代码应足以在没有应用程序焦点的情况下监听任何键(按下和/或释放):
对于这个特殊的问题,使用nativekeypressed方法如下:
请注意,jnativehook在默认情况下会在控制台中显示许多您可能不希望看到的内容,要更改这些内容,只需在您在main函数中使用的try-catch之前添加这些内容,如图所示(这还将关闭警告和错误消息,更多信息请参见此处):
免责声明:我知道这个问题在几年前就解决了,我只是希望有人觉得这个更容易找到/使用。
dhxwm5r44#
有一个图书馆为您做着艰苦的工作:https://github.com/kwhat/jnativehook
hvvq6cgz5#
这里有一个纯java的方法来解决您所描述的问题(不是keylistener问题。。。使用机器人问题时提前退出测试):
在整个测试过程中,将鼠标位置与测试最近设置的位置进行比较。如果不匹配,退出测试。注意:这个代码的重要部分是
testPosition
方法。下面是我最近使用的代码:ngynwnxp6#
我也有同样的问题。在我的例子中,机器人只是控制一个windows应用程序,这是最大化的。我把这些线放在驱动机器人的主回路的顶部:
color iconcentercolor=新颜色(255,0,0);//如果程序图标为红色
if(iconcentercolor.equals(robot.getpixelcolor(10,15)))抛出新的illegalstateexception(“robot没有与正确的应用程序交互。”);
要取消机器人,只需将tab键切换到另一个应用程序。适用于简单的单应用驱动机器人。
hjqgdpho7#
从终端中的命令行启动程序,并使用ctrl-c终止程序。