即使在单独的线程中实现睡眠之后,GUI执行也没有延迟

时间:2014-08-01 16:02:10

标签: java multithreading swing

我正在编写一个代码来移动特定数量的形状。我已将此代码放在循环中,以便程序将形状移动10次。但是,我不想仅显示最后一个输出,而是希望看到形状移动。所以,我在一个单独的线程中实现了sleep方法。但是,形状仍然快速移动,我只看到最终输出。

有人知道这里有什么问题,我该如何解决?

代码:

public void actionPerformed(ActionEvent e)
{
    if (e.getActionCommand().equals("START"))
    {
            for(int i=0;i<100;i++)
            {
                pf.particleFilter();
                repaint();  
                sleepFunction();
            }

    }   
}

private void sleepFunction()
{
    System.out.println("In sleep thread");
    Thread mythread = new Thread()
    {
        public void run()
        {
            try
            {
                System.out.println("Going to sleep!");
                Thread.sleep(1000);
            }
            catch(InterruptedException ex)
            {
                Thread.currentThread().interrupt(); 
            }   
        }

    };
    mythread.start();
}

public void particleFilter()
    {
            move();     
    }   

    public void move()
    {
        setXPosition_robot(robot_x);
        setYPosition_robot(robot_y);
        setXPosition_particle(particle_x);
        setYPosition_particle(particle_y);
    }

1 个答案:

答案 0 :(得分:4)

sleep函数在一个单独的线程中执行,因此它不会导致Event Dispatch Thread (EDT)进入睡眠状态,因此EDT会继续执行。

这是一件好事,因为你不想让EDT睡觉,因为这会阻止GUI重新绘制。

要制作动画,您需要使用Swing Timer。有关详细信息,请阅读How to Use Swing Timers上Swing教程中的部分。

我发现教程中的示例有点复杂,所以这是我能想到的最基本的例子:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

public class TimerTime extends JPanel implements ActionListener
{
    private JLabel timeLabel;

    public TimerTime()
    {
        timeLabel = new JLabel( new Date().toString() );
        add( timeLabel );

        Timer timer = new Timer(1000, this);
        timer.setInitialDelay(1);
        timer.start();
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        timeLabel.setText( new Date().toString() );
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("TimerTime");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new TimerTime() );
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}