1

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

想法是这样的:当您按住左键单击时,机器人将为您左键单击,每次单击之间有 300 毫秒。

然而,问题是当我左键单击时,我没有执行代码来使机器人运行。当我添加“test.run();”行时 在 nativeMousePressed 侦听器中,是的,它确实自动单击,但是当我释放左键单击时,它仍然运行。然后停止它的唯一方法是单击 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);

}
}
4

2 回答 2

3

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

当您开始第一次单击鼠标时,它会在300 毫秒后触发单击,会触发另一次单击,依此类推..

基本上,程序卡在了一个infinite loop of clicking,我有时称之为Clickening。

如果我知道您到底想做什么,我可能会为您提供更好的答案。

但正如我现在理解你的问题一样,一个简单的解决方案就是只触发鼠标释放 robot.mouseRelease(InputEvent.BUTTON1_DOWN_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) {
    }
    
    }
    
于 2017-12-22T18:53:29.707 回答
0

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

于 2021-04-23T19:49:17.820 回答