我正在制作一些可以模拟和读取原生输入事件的鼠标/键盘/像素类。这些是作为java.awt.Robot和JNativeHook的包装器实现的。它们旨在用作Mac上AutoHotKey或AutoIt的替代品。我在Windows 7 64位计算机上进行测试。
我的问题是,我无法弄清楚为什么JNativeHook的键盘监听器无法正常工作。我还没有去测试鼠标听众的工作情况。它可能与Swing和JNativeHook的多线程问题有关,但我没有排除库或构建版本的问题。
我的大部分代码都是直接来自示例页面。 JNativeHook使用鼠标/键盘的调试信息为Logger和控制台发送垃圾邮件,但它不会调用监听器。我使用下载页面中的最新jar以及Eclipse和最新的jdk / jre,除非安装出现了可怕的错误。
测试类
程序显示一个按钮和一个彩色面板。按下按钮,然后键入" 1"应该将面板的颜色更改为与鼠标光标下的像素相同。
import java.awt.AWTException;
import java.awt.Color;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.border.LineBorder;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
@SuppressWarnings("serial")
public class Test extends JFrame implements NativeKeyListener, WindowListener {
JPanel panel1 = null;
JButton button1 = null;
static final int PAD = 20;
public Test() {
// Disable console/log spam from JNativeHook
/*
LogManager.getLogManager().reset();
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage()
.getName());
logger.setLevel(Level.WARNING);
*/
setTitle("Test");
this.setLayout(null);
this.setSize(300, 270);
panel1 = new JPanel();
panel1.setBackground(Color.RED);
panel1.setSize(40, 40);
panel1.setLocation(20, 20);
panel1.setBorder(new LineBorder(Color.BLACK, 1));
this.getContentPane().add(panel1);
button1 = new JButton();
button1.setText("Button1");
button1.setSize(100, 20);
button1.setLocation(20,
panel1.getHeight() + panel1.getY() + PAD);
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Keys.addKeyListener(new NativeKeyListener() {
public void nativeKeyPressed(NativeKeyEvent e) {
if(e.getKeyCode() == NativeKeyEvent.VC_1) {
Keys.removeKeyListener(this);
Point p = MouseInfo.getPointerInfo().getLocation();
try {
panel1.setBackground(new Robot().getPixelColor(p.x, p.y));
} catch (AWTException e1) {
e1.printStackTrace();
}
System.out.println("Listener Removed");
}
Toolkit.getDefaultToolkit().beep();
System.out.println("Pressed");
}
public void nativeKeyReleased(NativeKeyEvent e) {
System.out.println("Released");
Toolkit.getDefaultToolkit().beep();
}
public void nativeKeyTyped(NativeKeyEvent e) {
System.out.println("Typed");
Toolkit.getDefaultToolkit().beep();
}
});
System.out.println("Button1");
Toolkit.getDefaultToolkit().beep();
}
});
this.getContentPane().add(button1);
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.addWindowListener(this);
this.setVisible(true); // Display the window.
}
public void windowOpened(WindowEvent e) {
// Initialize native hook
try {
GlobalScreen.registerNativeHook();
} catch (NativeHookException ex) {
System.err
.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
ex.printStackTrace();
System.exit(1);
}
GlobalScreen.getInstance().addNativeKeyListener(this);
}
public void windowClosed(WindowEvent e) {
// Clean up the native hook
GlobalScreen.unregisterNativeHook();
System.runFinalization();
System.exit(0);
}
public void windowClosing(WindowEvent e) {
/* Unimplemented */
}
public void windowIconified(WindowEvent e) {
/* Unimplemented */
}
public void windowDeiconified(WindowEvent e) {
/* Unimplemented */
}
public void windowActivated(WindowEvent e) {
/* Unimplemented */
}
public void windowDeactivated(WindowEvent e) {
/* Unimplemented */
}
public void nativeKeyReleased(NativeKeyEvent e) {
if (e.getKeyCode() == NativeKeyEvent.VC_SPACE) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(null,
"This will run on Swing's Event Dispatch Thread.");
}
});
}
}
public void nativeKeyPressed(NativeKeyEvent e) {
Toolkit.getDefaultToolkit().beep();
/* Unimplemented */
}
public void nativeKeyTyped(NativeKeyEvent e) {
Toolkit.getDefaultToolkit().beep();
/* Unimplemented */
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Test();
}
});
}
}
键类
import java.awt.AWTException;
import java.awt.AWTKeyStroke;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import org.jnativehook.GlobalScreen;
import org.jnativehook.keyboard.NativeKeyListener;
public class Keys {
protected static Robot r = null;
static {
try {
r = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
}
private Keys() {
} // STATIC CLASS
public static void setRobot(Robot r) {
Keys.r = r;
}
public static Robot getRobot(Robot r) {
return r;
}
/**
* Sets the delay between each key Press/Release.
*
* @param ms
* Number of milliseconds to delay. Zero removes any delay.
*/
public static void setDelay(int ms) {
r.setAutoDelay(ms);
}
/**
* @param keycode
* Key to send, for example KeyEvent.VK_0 for the 0 key.
*/
public static void send(int keycode) {
r.keyPress(keycode);
r.keyRelease(keycode);
}
/**
* @param keycode
* Key to send, for example KeyEvent.VK_0 for the 0 key.
*/
public static void press(int keycode) {
r.keyPress(keycode);
}
/**
* @param keycode
* Key to send, for example KeyEvent.VK_0 for the 0 key.
*/
public static void release(int keycode) {
r.keyRelease(keycode);
}
public static void send(char c) {
String str = "" + c;
send(str);
}
/**
* Doesn't support ALT, CTRL, NUMLOCK, or CAPSLOCK. Might not support every
* key.
*
* @param str
* The string to simulate typing.
*/
public static void send(String str) {
boolean shiftOn = false;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
int keycode = AWTKeyStroke.getAWTKeyStroke(c).getKeyCode();
boolean isLower = Character.isLowerCase(c);
if (shiftOn) {
if (Character.isLowerCase(c)) {
r.keyRelease(KeyEvent.VK_SHIFT);
shiftOn = false;
}
} else if (!isLower) {
r.keyPress(KeyEvent.VK_SHIFT);
shiftOn = true;
}
r.keyPress(keycode);
r.keyRelease(keycode);
}
if (shiftOn) {
r.keyRelease(KeyEvent.VK_SHIFT);
}
}
public static void addKeyListener(NativeKeyListener listener) {
GlobalScreen.getInstance().addNativeKeyListener(listener);
}
public static void removeKeyListener(NativeKeyListener listener) {
GlobalScreen.getInstance().removeNativeKeyListener(listener);
}
}
答案 0 :(得分:0)
我将jar版本从RC3切换到Beta2,它适用于Windows。 Beta2并没有在Mac上运行,但我认为RC 2或3可以。