【问题标题】:How could I add a simple delay in a Java Swing application?如何在 Java Swing 应用程序中添加一个简单的延迟?
【发布时间】:2012-10-07 08:48:07
【问题描述】:

我想知道如何在 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 时能帮助我或解决我的疑惑。

【问题讨论】:

  • 首先,永远不要延迟事件调度线程,并且始终只使用 EDT 更新 UI。其次,我会看看javax.swing.Timerexamples

标签: java multithreading swing timer swingworker


【解决方案1】:

这是一个使用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();            
        }        
    }    
}

【讨论】:

    【解决方案2】:

    幸好您删除了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,而我只是提供了一些 sn-ps(无需为此启动我的 IDE)
    • 我现在应该有一个示例目录:P
    【解决方案3】:

    如果您想指定操作的延迟,您需要使用Timer

    【讨论】:

    • 一个动作的延迟,例如2秒
    猜你喜欢
    • 2012-10-07
    • 2017-04-08
    • 2017-09-09
    • 2012-08-27
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多