【发布时间】:2020-07-31 14:39:28
【问题描述】:
我制作了一个程序,在我单击时模拟 Robot 类的单击。所以我有 2 次点击,但我点击了一次。我的问题是 MouseListener 还检测到来自机器人的点击,并且机器人总是触发 MouseListener 并且它不会停止点击。有人知道如何解决这个问题吗? 我使用 JNativeHook 库,所以我可以收听全局 KeyStrokes。使用 java.awt.MouseListener 我只能在窗口处于焦点时检测鼠标输入。 这是我的代码:
package de.fastwieac.doubleclicker.main;
// imports
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import java.awt.AWTException;
public class Main extends javax.swing.JFrame implements NativeMouseInputListener {
private static final long serialVersionUID = 1L;
public Main() {
initComponents();
}
private void initComponents() {
// create instances
panel = new javax.swing.JPanel();
rbtnOn = new javax.swing.JRadioButton();
rbtnOff = new javax.swing.JRadioButton();
rbtnLeft = new javax.swing.JRadioButton();
rbtnRight = new javax.swing.JRadioButton();
txtKey = new javax.swing.JTextField();
txtHotkey = new javax.swing.JTextField();
// frame properties
setLocationRelativeTo(null);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("DoubleClicker");
setResizable(false);
setSize(new java.awt.Dimension(304, 304));
// panel properties
panel.setBackground(new java.awt.Color(0, 204, 204));
panel.setFont(new java.awt.Font("Segoe UI", 1, 14));
// radio button rbtnOn properties
rbtnOn.setFont(new java.awt.Font("Segoe UI", 1, 14));
rbtnOn.setForeground(new java.awt.Color(0, 0, 0));
rbtnOn.setText("On");
rbtnOn.setSelected(true);
rbtnOn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
rbtnActionPerformed(evt);
}
});
// radio button rbtnOff properties
rbtnOff.setFont(new java.awt.Font("Segoe UI", 1, 14));
rbtnOff.setForeground(new java.awt.Color(0, 0, 0));
rbtnOff.setSelected(false);
on = true;
rbtnOff.setText("Off");
rbtnOff.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
rbtnActionPerformed(evt);
}
});
// radio button rbtnLeft properties
rbtnLeft.setFont(new java.awt.Font("Segoe UI", 1, 14));
rbtnLeft.setForeground(new java.awt.Color(0, 0, 0));
rbtnLeft.setSelected(true);
left = true;
rbtnLeft.setText("Left Click");
rbtnLeft.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
rbtnActionPerformed(evt);
}
});
// radio button rbtnRight properties
rbtnRight.setFont(new java.awt.Font("Segoe UI", 1, 14));
rbtnRight.setForeground(new java.awt.Color(0, 0, 0));
rbtnRight.setText("Right Click");
rbtnRight.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
rbtnActionPerformed(evt);
}
});
// txtKey Properties
txtKey.setEditable(false);
txtKey.setBackground(new java.awt.Color(0, 204, 204));
txtKey.setFont(new java.awt.Font("Segoe UI", 1, 14));
txtKey.setForeground(new java.awt.Color(0, 0, 0));
txtKey.setText("Key:");
txtKey.setBorder(null);
// txtHotkey properties
txtHotkey.setBackground(new java.awt.Color(0, 204, 204));
txtHotkey.setFont(new java.awt.Font("Segoe UI", 1, 14));
txtHotkey.setForeground(new java.awt.Color(0, 0, 0));
txtHotkey.setText("R");
txtHotkey.setBorder(null);
javax.swing.GroupLayout panelLayout = new javax.swing.GroupLayout(panel);
panel.setLayout(panelLayout);
panelLayout.setHorizontalGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelLayout.createSequentialGroup().addContainerGap()
.addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelLayout.createSequentialGroup().addGap(85, 85, 85)
.addComponent(txtKey, javax.swing.GroupLayout.PREFERRED_SIZE, 30,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtHotkey, javax.swing.GroupLayout.PREFERRED_SIZE, 13,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
panelLayout.createSequentialGroup().addGroup(panelLayout
.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(panelLayout.createSequentialGroup()
.addComponent(rbtnLeft, javax.swing.GroupLayout.PREFERRED_SIZE,
98, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.RELATED, 45,
Short.MAX_VALUE)
.addComponent(rbtnRight, javax.swing.GroupLayout.PREFERRED_SIZE,
98, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(panelLayout.createSequentialGroup()
.addComponent(rbtnOn, javax.swing.GroupLayout.PREFERRED_SIZE,
98, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.RELATED,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(rbtnOff, javax.swing.GroupLayout.PREFERRED_SIZE,
98, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(29, 29, 29)))));
panelLayout.setVerticalGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelLayout.createSequentialGroup().addContainerGap()
.addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(rbtnOn).addComponent(rbtnOff))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(rbtnLeft).addComponent(rbtnRight))
.addGap(18, 18, 18)
.addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtKey, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(txtHotkey, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(17, Short.MAX_VALUE)));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(
panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));
layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(
panel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE));
pack();
}
private void rbtnActionPerformed(java.awt.event.ActionEvent e) {
if (e.getSource().equals(rbtnOn)) {
rbtnOn.setSelected(true);
rbtnOff.setSelected(false);
on = true;
if (txtHotkey.getText().length() > 1) {
txtHotkey.setText("R");
}
txtHotkey.setText(txtHotkey.getText().toUpperCase());
}
if (e.getSource().equals(rbtnOff)) {
rbtnOff.setSelected(true);
rbtnOn.setSelected(false);
on = false;
}
if (e.getSource().equals(rbtnLeft)) {
rbtnLeft.setSelected(true);
rbtnRight.setSelected(false);
left = true;
}
if (e.getSource().equals(rbtnRight)) {
rbtnRight.setSelected(true);
rbtnLeft.setSelected(false);
left = false;
}
}
public static void main(String args[]) {
Logger l = Logger.getLogger(GlobalScreen.class.getPackage().getName());
l.setLevel(Level.OFF);
try {
GlobalScreen.registerNativeHook();
} catch (NativeHookException e) {
e.printStackTrace();
}
GlobalScreen.addNativeMouseListener(new Main());
// JOptionPane
JOptionPane.showMessageDialog(null, "Use only 1 Key as Hotkey!");
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Main().setVisible(true);
}
});
}
private boolean left;
private boolean on;
private Robot robot;
private javax.swing.JPanel panel;
private javax.swing.JRadioButton rbtnLeft;
private javax.swing.JRadioButton rbtnOff;
private javax.swing.JRadioButton rbtnOn;
private javax.swing.JRadioButton rbtnRight;
private javax.swing.JTextField txtHotkey;
private javax.swing.JTextField txtKey;
@Override
public void nativeMouseClicked(NativeMouseEvent e) {
}
@Override
public void nativeMousePressed(NativeMouseEvent e) {
if (e.getButton() == NativeMouseEvent.BUTTON1 & on == true & left == true) {
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
if (e.getButton() == NativeMouseEvent.BUTTON3 & left == false & on == true) {
robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK);
}
}
@Override
public void nativeMouseReleased(NativeMouseEvent e) {
}
@Override
public void nativeMouseDragged(NativeMouseEvent e) {
}
@Override
public void nativeMouseMoved(NativeMouseEvent e) {
}
}
【问题讨论】:
-
我已经有一段时间没有使用这个了。
getSource()方法可以帮助您区分您的点击和 java.awt.Robot 的点击吗?如果没有,您将需要一种解决方法。就像使用左键单击自己并使机器人始终右键单击一样。 (希望我理解正确的问题)。 -
您正在询问如何修复您的实施中的“错误”。我建议将“机器人”鼠标按下包装在对方法
invokeLater的调用中。话虽如此,我很想知道您的应用程序做了什么,导致您使用“机器人”来实现它,并且需要在桌面上的任何位置而不是在您的应用程序的JFrame中监听鼠标点击。 -
我是为 Minecraft 做的。您在 Minecraft 中的点击次数越多,您获得的击退就越少。应用程序会重复我的点击次数。
-
所以基本上你是想在Minecraft中作弊。我有一个建议。使用Key Bindings 绑定未使用的键,例如 F12,这样当您按下 F12 时,它会模拟多次鼠标点击。顺便说一句,你不需要jnativehook 来实施我的建议。
-
为什么我不需要 JNativeHook?是的,我试图在 Minecraft 中作弊,不,我不想像你说的那样做,因为我仍然想点击。
标签: java recursion minecraft mouselistener robot