使用JButton打破循环

时间:2017-08-23 16:28:10

标签: java swing jframe jbutton

我为游戏创建了一个程序,在每次点击之间以 Y 时间间隔点击 X 秒的随机间隔。这是执行此操作的代码。

    try {
        Util.autoCode rand = new Util.autoCode();
        Robot robot = new Robot();
        int NoC;
        NoC = Integer.parseInt(this.numberOfClicksTF.getText().trim());

        if (NoC == 0) {
            while (NoC == 0) {
                // robot.mousePress(InputEvent.BUTTON1_MASK);
                System.out.println("Infinite Press");
                Thread.sleep(rand.clickDelay());
                System.out.println("Infinite Release");
                // robot.mouseRelease(InputEvent.BUTTON1_MASK);
                Thread.sleep(rand.interval());
                break;
            }
        } else {
            for (int i = 0; i < NoC; i++) {
                //robot.mousePress(InputEvent.BUTTON1_MASK);
                System.out.println("Click Press");
                Thread.sleep(rand.clickDelay());
                System.out.println("Click Release");
                // robot.mouseRelease(InputEvent.BUTTON1_MASK);
                Thread.sleep(rand.interval());
            }
        }

    } catch (AWTException ex) {
        Logger.getLogger(MainFrame.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (NumberFormatException ex) {
        Logger.getLogger(MainFrame.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (InterruptedException ex) {
        Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
    }

我注释了鼠标按下并释放,因此我可以检查以确保时机正确,并且它将执行每次点击。此代码由JButton在JFrame中启动。每当我按下开始按钮时,它都会启动代码,除了在Netbeans中强制关闭它之外什么也不会停止它。目标是启动一个启动按钮,一个停止按钮中断代码,但不关闭JFrame。我一直在寻找无处可寻的答案 任何帮助都受到欢迎和赞赏!

2 个答案:

答案 0 :(得分:0)

您需要使用SwingWorker,例如:

在你的JFrame中你可能有一个SwingWorker和它的构建器&#34;方法:

private SwingWorker worker;

private SwingWorker getWorker() {
    worker = worker == null ? worker = new SwingWorker() {
        @Override
        protected Object doInBackground() throws Exception {
            while (true) {
                System.out.println("doInBackground!");
                Thread.sleep(1000);
            }
        }
    } : worker;
    return worker;
}

现在,在swing主线程(用于可视组件更新)中,您需要使用后台任务调用SwingWorker:

private void jButtonActionPerformed(java.awt.event.ActionEvent evt) {                                         
    if (getWorker().getState().equals(SwingWorker.StateValue.STARTED)) {
        worker.cancel(true);
        worker = null;
    } else {
        getWorker().execute();
    }
}  

您可以根据需要多次点击该按钮,该应用将创建并运行一个SwingWorker,或者将其设置为null并将当前的SwingWorker设置为空。

答案 1 :(得分:0)

本周直截了当地遇到了同样的问题,试图做出几乎相同的事情。首先,让我建议阅读Java中的multithreading。这可能看起来很复杂,但相信我有必要理解你的程序无法正常工作的原因。 (我将对下面发生的事情进行判断)

基本上,您的GUI在需要与机器人分离的事件调度程序线程上运行。这是因为当你调用thread.sleep()时,你实际上告诉GUI线程也要睡眠,导致GUI控制丢失。在单独的线程中启动机器人和GUI,让JButtons调用方法让机器人线程启动和停止。例如:

public static void main(String[] args) {
     javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new GUI();
            }
        });

}

创建你的GUI(我不知道你的GUI是什么样的,所以我只是写了新的GUI()来代替你创建你的GUI),这就是它在线程中#&# 39; s应该在。然后在你的eventListener中,每次按下开始按钮时都会产生一个持有机器人对象的新线程:

if(actionEvent.getSource().equals(playButton)) { //listening for the play button
    if(robotThread == null) {
        autoClicker= new AutoClicker(); 
        Thread = new Thread(autoClicker);
        Thread.start();
    }
}

并像你一样在autoClicker()类中启动你的机器人对象,并让autoClicker实现runnable。

public class AutoClicker implements Runnable{
    private Robot robot;

    public void run(){
        try {
            robot = new Robot();
        } catch (AWTException e) {e.printStackTrace();}
        //you need to learn about synchronization first
        while(true){
            synchronized(this){
                //do clicks and stuff here
            }
        }

    }
}

这样,您的GUI和机器人就位于不同的线程中。为了使JButtons启动和停止您的机器人,您需要学习同步以了解如何正确地进行多线程。

另一件事是你应该使用wait()方法而不是sleep(),因为sleep()会导致更多的问题在单个答案中过多。同样,您需要首先学习并发/同步。

如果您想在下方发表评论,我们可以为我制定一种方式让您使用我现在正在处理的代码,这与您尝试制作完全相同。我可以向你解释它的每一部分,以帮助你。