有没有办法在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;
}
答案 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给用户,决定他是想要中止还是继续这个过程。
我认为这是一种更轻松的方式来做你想做的事。