使用按钮退出无限循环 - Java

时间:2011-12-12 10:04:11

标签: java swing

我已经为我的问题搜索了一个解决方案,但我找不到任何接近的东西。这是我的问题:我刚开始学习Java中的Swing,我有一个应用程序,它会在最短和最长时间之间随机点击。用户输入最小和最大时间,然后单击启动此代码的按钮:

    class CalcButtonListener implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent arg0) {
        //get data from text fields and store as integers in milliseconds. 

        //create a robot and random number between min and max

        while(run == true){

            robot.mousePress(InputEvent.BUTTON1_MASK);
            robot.mouseRelease(InputEvent.BUTTON1_MASK);
            robot.delay(num.nextInt(max-min+1)+min);

            }
        }
    }
}

我删除了一些代码,因为它与问题无关。 问题是我有另一个按钮将变量run设置为false但是一旦点击第一个按钮,我就无法点击顶部的第二个按钮或退出按钮。

我确定我的错误是一个非常基本的错误,但我看不到它。 感谢您的任何回复,以帮助我更好地理解这一主题。

编辑:将while循环从“while(run = true)”更改为“while(run == true)”。

8 个答案:

答案 0 :(得分:4)

 while(run == true){

“=”将运行设置为true “==”将run的值与true进行比较

你也可以使用

 while(run){

答案 1 :(得分:3)

看看SwingWorker。只需while(run)

答案 2 :(得分:2)

每个事件都将由一个名为Event Dispatch thread(EDT)的线程处理。如果您在其中一个事件中有无限调用,则EDT无法处理事件队列中的下一个事件。

答案 3 :(得分:2)

<强>更新 这个答案已经更新了,因为@uckelman指出我,在条件run = true的情况下,停止按钮永远不会打破while循环,因为在循环中需要将其更改为run = false。然后我发布一个简单的替代解决方案来解决这个逻辑问题,用计时器重复安排一个任务。有关详细信息,请查看this SO问题。

关于按钮的事件:如果你有两个按钮,一个用于启动循环,另一个用于结束循环,只需尝试以下代码:

    class CalcButtonListener implements ActionListener{

        private boolean run = true;
        private java.util.Timer timer = new java.util.Timer();
        private JButton start_loop, end_loop;

        //here the buttons initialization


        @Override
        public void actionPerformed(ActionEvent ae){
        if(ae.getSource()==start_loop){


            java.util.TimerTask task = new java.util.TimerTask() {
        @Override
        public void run() {
            doStuff();
        }
    };
    timer.schedule(task, java.util.Calendar.getInstance().getTime(), 500);//here the '500' means the time, 500 ms,
the task is repeatedly executed. 


        }

        if(ae.getSource()==end_loop){
            timer.cancel();//cancel the tasks scheduled
            System.out.println("Task cancelled!");
        }
    }

    private void doStuff(){
        robot.mousePress(InputEvent.BUTTON1_MASK);
            robot.mouseRelease(InputEvent.BUTTON1_MASK);
            robot.delay(num.nextInt(max-min+1)+min);


    }
    }

现在,任务doStuff()计划每500毫秒执行一次。

有关java.util.Timerjava.util.TimerTask的其他信息。

关于您的问题:

  

问题是我有另一个按钮将变量run设置为false   但是一旦点击第一个按钮,我就无法点击第二个按钮   或者顶部的退出按钮。

与之前的questionthis页面一样,它是这样写的:

  

Swing的单线程规则说Swing组件只能是   由单个线程访问。此规则适用于获取和设置,   并且单个线程称为事件派发线程。

     

单线程规则是UI组件的良好匹配,因为它们   无论如何,大多数操作都倾向于以单线程方式使用   由用户发起。此外,建立线程安全   组件既困难又乏味:不做的事情是件好事   如果可以避免的话。但是为了它的所有好处,单线程规则   具有深远的影响。

     

Swing组件通常不符合单线程规则   除非他们的所有活动都是在事件发送时发送和接收的   线。例如,应该在上发送属性更改事件   应该接收事件派发线程和模型更改事件   事件派遣线程。

     

对于基于模型的组件,如JTable和JTree,单线程   规则意味着模型本身只能被访问   事件派遣线程。因此,模型的方法必须   快速执行,永远不应阻止,或整个用户界面   将没有反应。

然后,如果使用单个线程开发GUI,则在执行按钮事件时,GUI将冻结,等待相关按钮事件的完整执行。在您的情况下,在无限循环中,您的GUI将始终冻结。

我的建议是为您的GUI使用SwingWorker或扩展Thread类(然后在单独的线程中开发GUI),或实现Runnable接口。另一种方法是使用javax.swing.Timer包中的Timer

您可以阅读有关SwingWorker的旧问题:How do I use SwingWorker in Java?

SwingWorker教程:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

制作主题的教程:http://docs.oracle.com/javase/tutorial/essential/concurrency/

关于TimerUpdate JPanel and attributes in a gui, with a user-specified timer?

的问题

关于计时器的教程:http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html

答案 4 :(得分:1)

您应该阅读有关Swing计时器的信息:

http://java.sun.com/products/jfc/tsc/articles/timer/

也就是说,让你的程序事件驱动。 Swing应用程序已经有一个循环在它们内部运行,称为事件循环。如果你开始另一个,这没有任何帮助。

答案 5 :(得分:1)

请注意像while(something)这样的方法,这可能会使程序成为frezee,我建议您实施 事件监听器 以避免此问题... < / p>

答案 6 :(得分:0)

run=true;
while(run == true){

...

答案 7 :(得分:0)

while (run = true)几乎肯定不是你想要的。这样做的是每次执行循环条件时将true赋给run,这可确保循环始终继续。

你可能想说的是while (run == true)只测试run是否属实。更好的只是说while (run),它做同样的事情。

如果您从其他主题分配给run,请注意您应该让run成为您班级的volatile成员。如果你在其他地方分配run,那么你就有一个逻辑错误,因为没有办法摆脱循环。在这种情况下,您需要在循环内添加测试,并在希望循环停止时将run设置为false。 (或者,您可以拥有while (true)并在循环中使用break。)