简体   繁体   English

使用JButton停止java.awt.Robot

[英]Stopping java.awt.Robot with a JButton

So I'm making a program which utilizes a Robot to copy and paste text. 因此,我正在编写一个利用机器人复制和粘贴文本的程序。 However, I've hit a wall when it comes to how to stop the Robot in the middle of its actions (I prefer using a button since the whole application is in a GUI). 但是,在如何停止机器人动作的过程中,我遇到了麻烦(我更喜欢使用按钮,因为整个应用程序都在GUI中)。 Right now I have it so that the Robot is created and starts when a different button is clicked, and it stops after a certain amount of messages. 现在,我有了它,以便创建机械手并在单击其他按钮时启动,在收到一定数量的消息后停止。 From what I understand you need to stop the thread it's on, but I'm not sure how to do that. 据我了解,您需要停止正在运行的线程,但是我不确定该怎么做。

public void initSpam() throws AWTException
{

    Robot bot = new Robot();
    isRunning = true;

    int delayTime;
    if(isDefault)
        delayTime = DEFAULT;
    else
        delayTime = customTime;

    StringSelection selection = new StringSelection(spam);
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    clipboard.setContents(selection, selection);

    bot.delay(1250);

    for (int i = 0; i < buffer; i++) {
        bot.keyPress(KeyEvent.VK_CONTROL);
        bot.keyPress(KeyEvent.VK_V);
        bot.keyRelease(KeyEvent.VK_CONTROL);
        bot.keyRelease(KeyEvent.VK_V);
        bot.keyPress(KeyEvent.VK_ENTER);
        bot.keyRelease(KeyEvent.VK_ENTER);
        bot.delay(delayTime);
    }

}

The above is the method that's called when the other JButton is pressed. 上面是按下另一个JButton时调用的方法。 If anyone could guide me how to do this and explain how all of this threading works/how to work with it properly (assume I don't know much), I'd greatly appreciate it. 如果有人可以指导我如何执行此操作并解释所有这些线程的工作方式/如何正确使用它(假定我不太了解),我将不胜感激。 Thank you! 谢谢!

Thread workThread=new Thread(new Runnable() {
    @Override
    public void run() {
        //WORK initspam here
    }
});

to stop work, on click call: 要停止工作,请点击通话:

workThread.interrupt();

in the initSpam add: 在initSpam中添加:

   for (..) {
      if (Thread.interrupted()) {
          break;
      }
   }

If you need to continuously execute a series of repeating actions, javax.swing.Timer is the way to go: 如果需要连续执行一系列重复操作,则可以使用javax.swing.Timer

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;

public class Main {
    private static final Timer timer = new Timer(1000, Main::run);

    public static void main(final String[] args) {
        final JFrame frame = new JFrame();
        frame.setLayout(new FlowLayout());
        frame.setMinimumSize(new Dimension(200, 200));

        final JButton startButton = new JButton("start");
        startButton.addActionListener(e -> timer.start());
        frame.add(startButton);

        final JButton stopButton = new JButton("stop");
        stopButton.addActionListener(e -> timer.stop());
        frame.add(stopButton);

        frame.setVisible(true);
    }

    private static void run(final ActionEvent e) {
        System.out.println("do stuff");
    }
}

You should not call sleep or delay or they will make your button unresponsive. 您不应该呼叫sleepdelay否则它们会使您的按钮无响应。 The delays should be only controlled by Timer object. 延迟应仅由Timer对象控制。

If your action is more complex and you need sleeps/delays in random places, it might be easier to create new thread: 如果您的操作更为复杂,并且需要在随机的位置进行睡眠/延迟,则创建新线程可能会更容易:

private static Thread thread;

public static void main(final String[] args) {

    ...

    startButton.addActionListener(e -> {
        thread = new Thread(Main::run);
        thread.start();
    });
    stopButton.addActionListener(e -> thread.interrupt());
}

private static void run() {
    try {
        while (true) {
            Thread.sleep(1000);
            System.out.println("do stuff");
        }
    } catch (final InterruptedException e) {
        return;
    }
}

Each time you call Thread.sleep from your worker thread it will throw InterruptedException if the main thread interrupted it. 每次您从辅助线程调用Thread.sleep ,如果主线程中断了它,它将抛出InterruptedException

Keep in mind, that you cannot interact with most of AWT components from your new thread. 请记住,您不能与新线程中的大多数AWT组件进行交互。 Even if you want to change a text on a label you have to do that through SwingUtilities.invokeAndWait . 即使您想更改标签上的文本,也必须通过SwingUtilities.invokeAndWait You should also not share any mutable state between those threads - unless properly synchronized. 您也不应在这些线程之间共享任何可变状态-除非正确同步。 Stick with the first option, even if it slightly complicates your code - not having to deal with threads is usually worth it. 坚持使用第一个选项,即使它会使您的代码稍微复杂化-不必处理线程通常也是值得的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM