Java:如何在GUI中等待1秒

时间:2015-08-09 13:35:10

标签: java swing

我正在尝试使用Java制作卡拉OK机,但我不知道如何在GUI中延迟程序。我搜索了这个网站上的大量主题,但我还没有找到适用于此的解决方案。

import javax.swing.*;
import java.awt.event.*;
public class KaraokeMachine extends JFrame implements ActionListener
{
    ClassLoader Idr = this.getClass().getClassLoader();
    JLabel lbl1 = new JLabel( "" );
    JLabel lbl2 = new JLabel( "" );
    JLabel lbl3 = new JLabel( "" );
    JLabel lbl4 = new JLabel( "" );
    JButton btn = new JButton( "Play" );
    int x = 0;
    int y = 0;
    int z = 0;
    JPanel pnl = new JPanel();

    public KaraokeMachine()
    {
        super( "Karaoke" );
        setSize( 520, 280 );
        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        pnl.add( lbl1 );
        pnl.add( lbl2 );
        pnl.add( lbl3 );
        pnl.add( lbl4 );
        pnl.add( btn );
        btn.addActionListener( this );
        add( pnl ); setVisible( true );
    }

    public void actionPerformed( ActionEvent event )
    {
        if( event.getSource() == btn )
        {
            //
        }
    }
    public static void main( String[] args ) throws InterruptedException
    {
        KaraokeMachine karaoke = new KaraokeMachine();
    }
}

我想在1秒后制作标签更改文字。我已经在catch语句中尝试了Thread.sleep而没有//,但没有一个,编译器说它是一个错误,只有一个,程序只是延迟几秒钟并显示最后的结果,但没有结果在中间。有人可以告诉我如何让lbl1说出"一切",然后一秒钟后#34;一切都是"然后再过一秒"一切都很棒!"?感谢。

2 个答案:

答案 0 :(得分:3)

你不应该在你的gui线程中调用sleep()方法,否则你的所有界面都会冻结。您应该使用单独的线程并与您的gui线程通信,告诉他何时更新界面。

在Swing应用程序中使用线程的最佳方法是使用SwingWorker对象。特别是,它提供了两个钩子方法,processdone,它们直接在你的gui线程中调用,是一种发布工作线程完成进度的强大方法。在你的情况下,你应该做这样的事情:

SwingWorker<Void, String> worker = new SwingWorker<Void, String>(){

        @Override
        protected Void doInBackground() throws Exception {
            this.publish("Everything");
            Thread.sleep(1000);
            this.publish("Everything is");
            Thread.sleep(1000);
            this.publish("Everything is Awesome!");
            return null;
        }

        @Override
        protected void process(List<String> res){
            for(String text : res){
                 label.setText(text); 
            }
        }

    };

    worker.execute();

P.S。:您只能在工作对象上调用execute()方法一次。如果你想多次调用它,你必须实例化新对象。

答案 1 :(得分:2)

您可以使用javax.swing.Timer执行此操作。它应该足以通过以下代码替换代码中的//

        final AtomicInteger frame = new AtomicInteger(0);
        final String[] text = {
                "Everything",
                "Everything is",
                "Everything is Awesome!"
        };
        final Timer timer = new Timer(1000, null);
        timer.addActionListener((e) -> {
            lbl1.setText(text[frame.getAndIncrement()]);
            if (frame.get() >= text.length) {
                timer.stop();
            }
        });
        timer.start();