有没有办法在Robot类启动后停止它

时间:2014-07-06 14:37:11

标签: java awtrobot

有没有办法在Java Robot启动后停止执行?我有一个模拟鼠标左键单击的程序,但我还有一个名为STOP的未使用的JButton,它应该停止这个我开始使用Robot类的点击。我注意到Robot比Thread类要难得多。有什么想法吗?

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.util.Random;

public class Click{
Robot robot = new Robot();

private void leftClick(){
    int no = new Random().nextInt(6) + 1;
    robot.mousePress(InputEvent.BUTTON1_MASK);
    robot.delay(50 * no);
    robot.mouseRelease(InputEvent.BUTTON1_MASK);
    robot.delay(220 * no);
  }

public Click() throws AWTException{
    while (true) {
        leftClick();
        System.out.println("Click");            
    }       
  } 
}

在GUI类中,我有一个看起来像这样的JButton:

private JButton getBtnStart() {
    if (btnStart == null) {
        btnStart = new JButton("Start");
        btnStart.setBackground(Color.WHITE);
        btnStart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    c = new Click();
                } catch (AWTException e1) {
                    e1.printStackTrace();
                }
            }
        });
    }
    return btnStart;
}

2 个答案:

答案 0 :(得分:1)

有几个问题。构造函数中的无条件循环是不行的。除此之外,你阻止了EDT,所以我想知道这是否可行。

我甚至不清楚你想如何阻止这种咔哒声,因为你在机器人工作的时候几乎无能为力。

然而,这里有一个草图,说明如何根据您目前提供的信息解决这个问题:

import java.awt.AWTException;
import java.awt.GridLayout;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class RobotControlTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final RobotControl robotControl = new RobotControl();

        f.getContentPane().setLayout(new GridLayout(1,2));

        final JButton startButton = new JButton("Start");
        f.getContentPane().add(startButton);

        final JButton stopButton = new JButton("Stop");
        stopButton.setEnabled(false);
        f.getContentPane().add(stopButton);

        startButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                startButton.setEnabled(false);
                stopButton.setEnabled(true);
                robotControl.startClicking();
            }
        });

        stopButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                robotControl.stopClicking();
                startButton.setEnabled(true);
                stopButton.setEnabled(false);
            }
        });

        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class RobotControl
{
    private final Random random = new Random();
    private final Robot robot;
    private volatile boolean running = false;

    RobotControl()
    {
        try
        {
            robot = new Robot();
        }
        catch (AWTException e)
        {
            e.printStackTrace();
            throw new RuntimeException(e);
        }        
    }

    void startClicking()
    {
        Thread thread = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                running = true;
                performClicks();
            }
        });
        thread.start();
    }

    void stopClicking()
    {
        System.out.println("Stopping");
        running = false;
    }

    private void performClicks()
    {
        System.out.println("Starting");
        while (running)
        {
            leftClick();
            System.out.println("Clicked");
        }
    }

    private void leftClick()
    {
        int no = random.nextInt(6) + 1;
        robot.mousePress(InputEvent.BUTTON1_MASK);
        robot.delay(50 * no);
        robot.mouseRelease(InputEvent.BUTTON1_MASK);
        robot.delay(220 * no);
      }    
}

  

根据评论编辑:

当然可以检测鼠标移动,并在每次鼠标移动后暂停点击一会儿。但是,我不喜欢这个方向。答案的第一部分只是一个快速草图,用于说明{strong} reading a bit about threads时自行开发的想法。此草图的任何扩展都是不合适的。我的直觉是,这将以一系列进一步的要求结束,这些要求可能会以某种方式被归入原始答案中,但应该从一开始就说明

但我看到你的问题:“开发一个能满足我需要的程序”并不是一个有效的问题。

但至少要回答一下“如何检测鼠标移动?”的“隐含”问题:

您可以使用MouseInfo.getPointerInfo().getLocation()获取鼠标位置,并定期检查此点以查看它是否与上一点不同。

克服原始计划:

import java.awt.AWTException;
import java.awt.GridLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class ExtendedRobotControlTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final RobotControl robotControl = new RobotControl();

        f.getContentPane().setLayout(new GridLayout(1,2));

        final JButton startButton = new JButton("Start");
        f.getContentPane().add(startButton);

        final JButton stopButton = new JButton("Stop");
        stopButton.setEnabled(false);
        f.getContentPane().add(stopButton);

        startButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                startButton.setEnabled(false);
                stopButton.setEnabled(true);
                robotControl.startControl();
            }
        });

        stopButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                robotControl.stopControl();
                startButton.setEnabled(true);
                stopButton.setEnabled(false);
            }
        });

        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class RobotControl
{
    private final Random random = new Random();
    private final Robot robot;

    private Thread clickingThread;
    private Thread observingThread;

    private long lastMovementMillis = -1;
    private Point lastMousePosition = null;

    private volatile boolean running = false;

    RobotControl()
    {
        try
        {
            robot = new Robot();
        }
        catch (AWTException e)
        {
            e.printStackTrace();
            throw new RuntimeException(e);
        }        
    }

    void startObserver()
    {
        observingThread = new Thread(new Runnable(){

            @Override
            public void run()
            {
                observeMovement();
            }
        });
        observingThread.start();
    }

    private void observeMovement()
    {
        while (running)
        {
            Point p = MouseInfo.getPointerInfo().getLocation();
            if (!p.equals(lastMousePosition))
            {
                System.out.println("Movement detected");
                lastMovementMillis = System.currentTimeMillis();
                lastMousePosition = p;
            }
            try
            {
                Thread.sleep(50);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
                Thread.currentThread().interrupt();
                return;
            }
        }
    }


    void startControl()
    {
        stopControl();
        System.out.println("Starting");
        lastMovementMillis = System.currentTimeMillis();
        lastMousePosition = MouseInfo.getPointerInfo().getLocation();
        running = true;
        startClicking();
        startObserver();
    }    

    private void startClicking()
    {
        clickingThread = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                performClicks();
            }
        });
        clickingThread.start();
    }

    void stopControl()
    {
        if (running)
        {
            System.out.println("Stopping");
            running = false;
            try
            {
                clickingThread.join(5000);
                observingThread.join(5000);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }
    }

    private void performClicks()
    {
        System.out.println("Starting");
        while (running)
        {
            long t = System.currentTimeMillis();
            if (t > lastMovementMillis + 1000)
            {
                leftClick();
                System.out.println("Clicked");
            }
            else
            {
                System.out.println("Waiting before clicks...");
                try
                {
                    Thread.sleep(50);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                    return;
                }
            }
        }
    }

    private void leftClick()
    {
        int no = random.nextInt(6) + 1;
        robot.mousePress(InputEvent.BUTTON1_MASK);
        robot.delay(50 * no);
        robot.mouseRelease(InputEvent.BUTTON1_MASK);
        robot.delay(220 * no);
      }    
}

答案 1 :(得分:0)

我在每次机器人动作后都会出现以下情况: 如果按Esc然后睡觉。 在那一刻,我会弹出一个JOptionPane给用户,决定他是想要中止还是继续这个过程。

我认为这是一种更轻松的方式来做你想做的事。