一个接一个地延迟显示JLabel的问题

时间:2013-06-13 15:42:03

标签: java swing jframe jlabel event-dispatch-thread

我有这段代码:

public class Bum extends JFrame implements ActionListener
{
    JButton  button;

    JLabel[] labels;

    public Bum()
    {
        setTitle("Bum!");
        setLayout(null);

        button = new JButton();
        button.setBounds(10, 10, 190, 190);
        button.addActionListener(this);
        add(button);

        labels = new JLabel[10];
        for(int i=0; i<10; i++)
        {
            labels[i] = new JLabel("YES");
            labels[i].setBounds(200, 200 + i * 50, 100, 30);
            add(labels[i]);
        }
    }

    @Override
    public void actionPerformed(ActionEvent arg0)
    {
        for(int i=0; i<10; i++)
        {
            labels[i].setText("NO");
            try 
            {
                Thread.sleep(400);
            } 
            catch (InterruptedException e) 
            {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) 
    {
        Bum bum = new Bum();
        bum.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        bum.setVisible(true);
        bum.setExtendedState(bum.getExtendedState() | JFrame.MAXIMIZED_BOTH);
    }
}

有一个按钮,它有一个ActionListener。如果我单击按钮,那么我想要更改所有标签,但是一个接一个地在它们之间有小间隔(我使用Thread.sleep(400))。该程序错误,因为它同时更改了所有标签。

2 个答案:

答案 0 :(得分:1)

Swing是单线程的。通过调用Thread.sleep,您将阻止EDT中的更新。请改用Swing Timer

答案 1 :(得分:1)

通过调用Thread.sleep(),您只是冻结EDT (事件派发线程)

使用Swing Timer来安排将来的事件触发。

来自Oracle网站:

  

Swing由三种线程组成:

     
      
  • 初始线程,执行初始应用程序代码的线程。

  •   
  • 事件调度线程,执行所有事件处理代码。大多数与Swing框架交互的代码也必须   在这个帖子上执行。

  •   
  • 工作线程,也称为后台线程,执行耗时的后台任务。

  •