首页 > 解决方案 > Java MouseListener 还检测来自机器人类的点击

问题描述

我制作了一个程序,当我单击时模拟使用 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) {

    }

}

标签: javarecursionminecraftmouselistenerrobot

解决方案


使用布尔值怎么样,比如“点击”?每次点击被触发时,您都会切换它,并且只有在它为真时才会触发另一个。

所以你点击-> 这是真的,机器人点击 -> 它是假的,在您再次点击之前不会再次点击?


推荐阅读