我正在使用java,并试图编写一个简单的sudo鼠标记录器,该记录器将在按下空格键时存储鼠标位置。我唯一需要检测的键是空格键(尽管如果另一个键更容易,那也可以)。
我需要用java编写整个鼠标记录器,但如果按键的函数是另一种语言也可以。我将在Windows7中运行这个。
做所描述的事情最简单的方法是什么?我发现的所有方法都需要至少20行代码。这还可以,只是我不知道如何实现它们。我有一个例子来源如下:
import java.awt.MouseInfo;
import javax.swing.JOptionPane;
public class MouseRecorder {
public static void main (String[] args)
{
int slot = 0;
int xLoc[10];
int yLoc[10];
while (slot <= 10)
{
if (keyPressed(KEY_SPACE)) //<<<<This obviously won't work, but I'm looking for the simplest way to code this
{
xLoc[slot] = MouseInfo.getPointerInfo().getLocation().x;
yLoc[slot] = MouseInfo.getPointerInfo().getLocation().y;
slot++;
}
}
//The mouse information can now be utilized
}
}
同样,您的问题不清楚,因为您没有回答我的评论:
在我看来,你可能想要一个只响应一次按键的系统范围的按键记录器,而不需要GUI。如果是这样的话,那么最好的解决方案就是不要使用Java来创建应用程序,而是使用一种更接近操作系统的工具。如果这是一个Windows项目,我会想到AutoIt。请更好地定义您的需求。
这迫使我们猜测这个问题及其解决方案。
如果你有兴趣创建一个Swing GUI,让它关注焦点,并让它监听关键事件,那么解决方案就是这样做:
- 创建Swing GUI并显示它,在应用程序运行时将其保留为活动窗口应用程序
- 使用键绑定使其侦听空格键按压
- 然后在按下空格键时记录鼠标位置
- 如前所述,这在5行代码中是无法实现的,所以把这个想法放在一边
另一方面,如果你希望没有GUI,而是在任何和所有应用程序运行时监听热键,那么
- 所使用的可能平台至关重要,因为您的解决方案将需要特定于操作系统的代码,因为创建热键意味着必须创建一个键盘处理程序例程,通常使用C,并为每个平台执行此操作,然后使用JNI或JNA将其链接到Java
- 或者如前所述,另一种方法是将Java程序与特定于操作系统的实用程序或脚本(如AutoIt)链接起来
如果您需要更具体的帮助,请澄清您的问题。
编辑
您所在的州:
谢谢你的回答,但正如我上面所描述的:"改变语言是不可能的,尽管这看起来可能更容易。"one_answers"如果我能避免的话,我不想要gui"
那么我的第二个答案就是你在找什么。你在C/C++、JNI或JNA方面有多熟练?你对操作系统库的了解有多好?如果你想要一个只使用Java的解决方案,我会认为你的需求远远超过初级或中级Java,并进入高级领域——或者至少超出了我目前的能力,尽管我相信经过几天到一两周的学习,我可以想出一些解决方案。
或者考虑摆脱"不断变化的语言"的需求,转而允许至少将Java与脚本实用程序(如AutoIt)结合在一起。这可以在更短的时间内创建解决方案,至少对我来说是这样。但一个限制是,这些解决方案将是特定于平台的解决方案。你做这一切的目的是什么?这可能是一个伪装的XY问题吗?
编辑2
我决定尝试用一个小的AutoIt实用程序来解决这个问题,我用Java实现了这个实用程序,这就是我想到的。
我的AutoIt程序名为CaptureHotKey.au3,在使用前会编译为exe:
$key = $CmdLine[1]
HotKeySet($key, "hotKeyFunction")
While 1
Sleep(100)
WEnd
Func hotKeyFunction()
ConsoleWrite(@CRLF)
EndFunc
它没有太多功能。它所做的只是从第一个命令行参数设置一个热键,提供一个无休止的while循环,以便它继续运行,以及一个非常简单的热键功能,只向控制台发送回车/换行(这将是标准输出)。
然后是一个Java类来帮助与之交互。它使用SwingPropertyLanguageSupport来允许添加在Swing线程上响应的PropertyChangeListener(如果我想将其与GUI一起使用)。
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.swing.event.SwingPropertyChangeSupport;
public class CaptureHotKey implements Runnable {
public static final String HOT_KEY = "hot key";
private String hotKey;
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
private Scanner scanner;
private CaptureHotKeyFromAutoIt capture;
public CaptureHotKey(final String hotKey) throws IOException {
this.hotKey = hotKey;
capture = new CaptureHotKeyFromAutoIt(hotKey);
scanner = new Scanner(capture.getReadable());
}
public void startCapturing() {
new Thread(this).start();
}
public void exit() {
if (capture != null) {
capture.exit();
}
if (scanner != null) {
scanner.close();
}
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
public String getHotKey() {
return hotKey;
}
@Override
public void run() {
while (scanner != null && scanner.hasNextLine()) {
scanner.nextLine();
pcSupport.firePropertyChange(HOT_KEY, true, false);
}
}
private static class CaptureHotKeyFromAutoIt {
public static final String AUTO_IT_APP_PATH = "CaptureHotKey.exe";
private Process process = null;
private ProcessBuilder pb;
public CaptureHotKeyFromAutoIt(String hotKey) throws IOException {
List<String> cmdList = new ArrayList<>();
cmdList.add(AUTO_IT_APP_PATH);
cmdList.add(hotKey);
pb = new ProcessBuilder(cmdList);
pb.redirectErrorStream(true);
process = pb.start();
}
public void exit() {
if (process != null) {
process.destroy();
}
}
public Readable getReadable() {
if (process != null) {
return new InputStreamReader(process.getInputStream());
}
return null;
}
}
}
最后一个Java类来测试这个设置:;
这将向上面的类添加一个PropertyChangeListener,以便在按下热键时通知它:
import java.awt.MouseInfo;
import java.awt.PointerInfo;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.Scanner;
public class CaptureHotKeyTest {
public static final String CTRL_R = "^r"; // "{SPACE}" works for spacebar
private static final String EXIT = "exit";
private CaptureHotKey capture;
public CaptureHotKeyTest() {
try {
capture = new CaptureHotKey(CTRL_R);
capture.addPropertyChangeListener(new HotKeyPropertyChngListener());
capture.startCapturing();
Scanner scan = new Scanner(System.in);
System.out.println("Press control-r to get mouse position.");
System.out.println("Type "exit" to exit program");
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line.equalsIgnoreCase(EXIT)) {
scan.close();
capture.exit();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private class HotKeyPropertyChngListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(CaptureHotKey.HOT_KEY)) {
System.out.println("hot key pressed");
PointerInfo pointerInfo = MouseInfo.getPointerInfo();
System.out.println("Mouse: " + pointerInfo.getLocation());
}
}
}
public static void main(String[] args) {
new CaptureHotKeyTest();
}
}
您应该使用KeyListener:http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html它与Swing 配合良好