在无限循环中执行事件

时间:2014-10-26 01:35:59

标签: java swing jbutton jlabel infinite-loop

public void actionPerformed(ActionEvent event)
    {
        // TODO Auto-generated method stub
        JButton src = (JButton) event.getSource();   //get which button is clicked

        if(src.equals(GO))     //if GO button is clicked
        {
            try {
                runHack();
            } catch (AWTException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(src.equals(STOP))   //if STOP button is clicked
        {
            //do nothing
            FeedBack.setText(null);
            FeedBack.setText("Stopped");

        }
    }

我有一个程序,当您点击按钮GO时,它会执行一个名为runHack();的方法

 private void runHack() throws AWTException 
 {
    FeedBack.setText(null);
    FeedBack.setText("Running(This doesn't print out)");

   while(true)//infinite loop
   {
        FeedBack.setText("This doesn't print out");
   }
}

runHack()是运行无限循环的方法。当我单击GO按钮时,程序在执行runHack()方法时冻结。字符串"Running"未显示在JLabel FeedBack

我的问题是当程序处于无限循环时,如何使事件仍然可用?我想要它,这样当我按下STOP按钮时,程序退出无限循环。另外,我希望JLabel FeedBack在循环内部工作。

2 个答案:

答案 0 :(得分:2)

你需要在一个新线程里面运行这个infine。这是如何使用timer .swing timer在单独的thread.set延迟到零运行。所以它作为一个while(true)循环。 在您的代码中,由于持久性任务(无限循环),您阻止EDT。由于EDT被阻止,您对textfield所做的更改无法更新。

你需要swing timer而不是java.util.Timer

import import javax.swing.Timer; 

宣告计时器

Timer t;//global declaration;

初始化//

 t=new Timer(0, new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        FeedBack.setText("This doesn't print out");
    }
});

按钮点击//

 JButton src = (JButton) event.getSource();   //get which button is clicked

    if(src.equals(GO))     //if GO button is clicked
    {
        try {
            t.start();
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }
    if(src.equals(STOP))   //if STOP button is clicked
    {
        //do nothing
        t.stop();
        FeedBack.setText(null);
        FeedBack.setText("Stopped");

    }

...更新

一个完整的例子

import java.awt.AWTException;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.Timer;

public class example extends JFrame implements ActionListener{

    Timer t;
    private final JTextField FeedBack;
    private JButton go;
    private JButton stop;
    int i=0;

    public example() {
         FeedBack=new JTextField("initial text");
         go=new JButton("go");
         stop=new JButton("stop");
           go.addActionListener(this);
           stop.addActionListener(this);

        this.setLayout(new GridLayout(1, 3));
        this.add(go);
        this.add(stop);
        this.add(FeedBack);
        this.setVisible(true);

        t = new Timer(0, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                FeedBack.setText(i+"");
                i++;
            }
        });

    }

    public void actionPerformed(ActionEvent event) {

        JButton src = (JButton) event.getSource();
        System.out.println(src);
        if (src==go) //if GO button is clicked
        {               
            t.start();
        }
        if (src==stop) //if STOP button is clicked
        {
            //stop timer
            t.stop();
            //FeedBack.setText(null);
            FeedBack.setText("Stopped");

        }
    }

    public static void main(String[] args) {
        example f = new example();
    }
}

输出>>

enter image description here

答案 1 :(得分:1)

简短回答:

SwingUtilities.invokeLater(new Runnable() {
 @Override
 public void run(){
   runHack();
 }
}).start();

请注意,有更好的方法来生成新的线程,比如使用Executor。就像有人评论一样,Threads是一个广泛的主题,你应该阅读文档。

[编辑] 就像@Hovercraft Full Of Eels所说的不是线程安全调用UI的新线程修改。