如何在Java Swing应用程序中添加简单的延迟?

4

我想知道如何在Java的Swing应用程序中添加时间延迟。我使用了Thread.sleep(time),也尝试了使用SwingWorker但是没有成功。以下是我的一部分代码:

switch (state) {
    case 'A':
        if (charAux == 'A') {
            state = 'B';                    
            //Here's where I'd like to add a time delay
            jLabel13.setForeground(Color.red);
            break;
        } else {                            
            //Here's where I'd like to add a time delay
            jLabel12.setForeground(Color.red);
            break;
        }
}

我希望在使用SwingWorker时,您能够帮助我或解决我的疑问。


1
首先,永远不要在事件分派线程中放置延迟,并且始终只能从EDT中更新UI。其次,我会看一下javax.swing.Timer和示例。 - MadProgrammer
3个回答

8
这是一个使用javax.swing.Timer的示例。
public class TestBlinkingText {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new BlinkPane());
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }            
        });
    }

    protected static class BlinkPane extends JLabel {

        private JLabel label;
        private boolean state;

        public BlinkPane() {

            label = new JLabel("Look at me!");
            setLayout(new GridBagLayout());

            add(label);

            Timer timer = new Timer(500, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent ae) {                    
                    state = !state;
                    if (state) {
                        label.setForeground(Color.RED);
                    } else {
                        label.setForeground(Color.BLACK);
                    }                    
                    repaint();                    
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.setInitialDelay(0);
            timer.start();            
        }        
    }    
}

7

很好,你移除了Thread.sleep,因为这会导致UI在2秒内无响应。

你可以启动一个仅运行一次的Timer

int delay = 2000;
Timer timer = new Timer( delay, new ActionListener(){
  @Override
  public void actionPerformed( ActionEvent e ){
    jLabel12.setForeground( Color.red );
  }
} );
timer.setRepeats( false );
timer.start();

请注意,Timerjavax.swing.Timer,它保证了ActionListeneractionPerformed方法在事件派发线程上调用,遵守Swing线程规则。
这也可以通过SwingWorker实现,但我建议在此情况下使用Timer。如果您想使用SwingWorker,可以在doInBackground()方法中简单地使用Thread.sleep,并在done()方法中更新JLabel
大致如下:
class Delay extends SwingWorker<Void, Object> {
 @Override
 public void doInBackground() {
  Thread.sleep( 2000 );
 }

 @Override
 protected void done() {
   jLabel12.setForeground( Color.red );
 }
}

@MadProgrammer,你提供了一个SSCCE,而我只提供了一些代码片段(不需要启动我的IDE)。 - Robin
我现在应该已经有一个示例目录了:P - MadProgrammer

2
如果您想为某个操作指定延迟时间,您需要使用计时器(Timer)。请注意保留HTML标签。

延迟一个动作的时间,例如2秒。 - Juan Reséndiz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接