带有JNativeHook的Java AutoClicker无限运行

时间:2017-12-22 17:44:30

标签: java jnativehook

我一直在尝试用java编写这个autoclicker大约7个小时。我根据其他人的代码写了一些这些,有些是我自己的。我使用JNativeHook来捕获Eclipse /控制台之外的窗口中的点击。

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

但问题是,当我左键单击时,我不执行代码来使机器人运行。当我添加行" test.run();"在nativeMousePressed侦听器中,YES,它自动点击,但是当我发布左键单击时,它仍然运行。然后停止它的唯一方法是单击eclipse上的停止按钮。

现在,我知道我需要让它在一个新线程中运行,所以我仍然可以使用它,我尝试在我的MousePressed监听器中使用它:

            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);

}
}

2 个答案:

答案 0 :(得分:0)

每次按下鼠标都会触发一次点击,所以:

  

当您通过鼠标按下第一次点击时,触发 300ms 后的点击次数   触发另一次点击等等..

基本上程序卡在infinite loop of clicking中,我有时称之为点击。

如果我知道您正在尝试做什么,我可能会为您提供更好的答案。

但正如我现在理解你的问题,一个简单的解决方案就是,只触发鼠标释放 robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);而不是鼠标按下。这将完成300分钟后您的印刷机启动点击。

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

  • Alt press - >点击开始

  • Alt发布 - >点击停止

  • 退出按下 - >程序退出

    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;

    公共类AutoClicker实现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) {
    }
    

    }

答案 1 :(得分:0)

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