带有JNativeHook的Java AutoClicker可以无限运行

带有JNativeHook的Java AutoClicker可以无限运行,java,jnativehook,Java,Jnativehook,我一直在尝试用java编写这个autoclicker,现在已经有7个小时了。我根据别人的代码写了一些,一些是我自己写的。我使用JNativeHook在Eclipse/控制台之外的windows中捕获点击 这个想法是这样的:当你按住左键点击时,机器人会为你左键点击,每次点击间隔为300毫秒 然而,问题是,当我左键单击时,我没有执行使机器人运行的代码。当我在nativeMousePressed侦听器中添加行“test.run();”时,是的,它会自动单击,但当我释放左键单击时,它仍会运行。然后停止它

我一直在尝试用java编写这个autoclicker,现在已经有7个小时了。我根据别人的代码写了一些,一些是我自己写的。我使用JNativeHook在Eclipse/控制台之外的windows中捕获点击

这个想法是这样的:当你按住左键点击时,机器人会为你左键点击,每次点击间隔为300毫秒

然而,问题是,当我左键单击时,我没有执行使机器人运行的代码。当我在nativeMousePressed侦听器中添加行“test.run();”时,是的,它会自动单击,但当我释放左键单击时,它仍会运行。然后停止它的唯一方法是单击eclipse上的停止按钮

现在,我明白我需要让它在一个新线程中运行,这样我仍然可以使用它的侦听器,我试图在我的鼠标按下的侦听器中这样做:

            Thread test = new Thread(new Runnable() {
            public void run() {
                try {
                    Robot robot = new Robot();
                    System.out.println("GOT HERE 1");
                    System.out.println("Got HERE 4");
                    try {
                        Thread.sleep(300);
                        System.out.println("Got HERE 5");
                        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
                        // robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
                        System.out.println("Got HERE 6");
                        // if ();
                    } catch (InterruptedException ex) {
                    }
                } catch (AWTException e1) {
                }
                ;
            }
        });
我已经删除了我的循环,因为这似乎没有改变它。有人能解释一下这里出了什么问题吗

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;

public class AutoClicker implements NativeMouseInputListener {

public void nativeMouseClicked(NativeMouseEvent e) {
    // dont need
}

public void nativeMousePressed(NativeMouseEvent e) {
    if (e.getButton() == NativeMouseEvent.BUTTON1) {
        System.out.println("Mouse Pressed: " + e.getButton());
        run = true;
        System.out.println(run);

        Thread test = new Thread(new Runnable() {
            public void run() {
                try {
                    Robot robot = new Robot();
                    System.out.println("GOT HERE 1");
                    System.out.println("Got HERE 4");
                    try {
                        Thread.sleep(300);
                        System.out.println("Got HERE 5");
                        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
                        // robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
                        System.out.println("Got HERE 6");
                        // if ();
                    } catch (InterruptedException ex) {
                    }
                } catch (AWTException e1) {
                }
                ;
            }
        });
    }

}

public void nativeMouseReleased(NativeMouseEvent e) {
    if (e.getButton() == NativeMouseEvent.BUTTON1) {
        System.out.println("Mouse Released: " + e.getButton());
        run = false;
        System.out.println(run);
    }
}

public void nativeMouseMoved(NativeMouseEvent e) {
    // dont need
}

public void nativeMouseDragged(NativeMouseEvent e) {
    // dont need
}

public void click() {

}

public static boolean run = false;

public static void main(String[] args) {
    try {
        GlobalScreen.registerNativeHook();
    } catch (NativeHookException ex) {
        System.err.println("There was a problem registering the native hook.");
        System.err.println(ex.getMessage());

        System.exit(1);
    }

    Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
    logger.setLevel(Level.WARNING);

    // Don't forget to disable the parent handlers.
    logger.setUseParentHandlers(false);

    // Construct the example object.
    AutoClicker clicker = new AutoClicker();

    // Add the appropriate listeners.
    GlobalScreen.addNativeMouseListener(clicker);

}
}

每次按下鼠标都会触发一次单击,因此:

当您用鼠标按下开始第一次单击时,会触发300毫秒后的单击 触发另一次单击,依此类推

基本上,程序会陷入无限循环的点击中,我有时称之为点击。

如果我知道你到底想做什么,我可能会给你一个更好的答案

但正如我现在理解你的问题,一个简单的解决方案就是,只触发鼠标释放
robot.mousererelease(InputEvent.BUTTON1\u DOWN\u MASK)并且不要按鼠标。这将在300毫秒后完成您的按键启动

更新:根据OP的评论,这里是更新的代码,它使用alt而不是鼠标左键触发单击

  • 按Alt键-->单击开始

  • Alt释放-->单击停止

  • 按Escape键-->程序退出

    import org.jnativehook.GlobalScreen;
    import org.jnativehook.NativeHookException;
    import org.jnativehook.keyboard.NativeKeyEvent;
    import org.jnativehook.keyboard.NativeKeyListener;
    
    import java.awt.*;
    import java.awt.event.InputEvent;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class AutoClicker implements NativeKeyListener {
    
    public static void main(String[] args) {
        try {
            GlobalScreen.registerNativeHook();
        } catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
    
            System.exit(1);
        }
    
        Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
        logger.setLevel(Level.WARNING);
    
        // Don't forget to disable the parent handlers.
        logger.setUseParentHandlers(false);
    
        // Construct the example object.
        AutoClicker clicker = new AutoClicker();
    
        // Add the appropriate listeners.
        GlobalScreen.addNativeKeyListener(clicker);
    }
    
    private void startClicking() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    Robot robot = new Robot();
                    while (isClicking) {
                        Thread.sleep(300);
                        System.out.println("Clicked!");
                        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
                        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);                            
                    }
                } catch (Exception ignored) {
                    System.out.println("Couldn't click");
                }
            }
        };
        Thread clickingThread = new Thread(runnable);
        clickingThread.start();
    }
    
    private boolean isClicking = false;
    
    @Override
    public void nativeKeyPressed(NativeKeyEvent key) {
        // When alt is pressed --> Start clicking
        if (key.getKeyCode() == NativeKeyEvent.VC_ALT_L || key.getKeyCode() == NativeKeyEvent.VC_ALT_R) {
            if (!isClicking) {
                System.out.println("Alt pressed, started clicking!");
                isClicking = true;
                startClicking();
            }
        }
    
        //  If escape is clicked, exit the program
        else if (key.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {
            System.out.println("Escape button Pressed.EXITING!");
            System.exit(0);
        }
    }
    
    @Override
    public void nativeKeyReleased(NativeKeyEvent key) {
        if (key.getKeyCode() == NativeKeyEvent.VC_ALT_L || key.getKeyCode() == NativeKeyEvent.VC_ALT_R) {
            // When alt is relesed --> Stop clicking
            isClicking = false;
            System.out.println("Alt released, stopped clicking!");
        }
    }
    
    @Override
    public void nativeKeyTyped(NativeKeyEvent key) {
    }
    
    }
    

考虑到这是一个旧线程,我不知道是否应该回答这个问题,但我想我可能已经找到了一种不使用ALT或触发器来启用自动点击器的方法。我已经看到,如果您按住鼠标按钮1,100毫秒后,程序会以编程方式释放鼠标按钮1,然后您会释放实际的按钮1,它会显示release两次(假设您在JNativehook中的pressed方法中添加了print语句)。当显示鼠标按钮1已释放时,这可能是关闭自动点击器的信号。希望这是有道理的

谢谢你的回答。我想告诉它点击也会触发事件。这是可行的,但缺少我想要的功能。理想情况下,我会按住鼠标左键,它会左键单击,直到它被释放。当它被释放时,它将停止点击。正如您的代码所示,鼠标左键单击会导致第二次鼠标左键单击延迟。问题是,据我所知,无法区分机器人鼠标事件和真实鼠标事件。您最好的选择是使用鼠标左键或中键来检测机器人何时应该单击以及何时应该停止。或者更好,使用NativeKeyListener,让键盘按钮作为触发器。@ChadWilson刚刚更新了帖子并添加了测试代码,使用alt作为触发器。