我如何使用 Java Swing Timer 在我的界面上延迟 (java swing)?

how can i have a delay on my interface (java swing) using Java Swing Timer?

我是 Java 的新手,我正在尝试在按下 Jbutton 启动时添加时间延迟。我使用了 TimeUnit.SECONDS.sleep() 但它没有用,然后我研究并发现了 java 摆动计时器,但它也没有用,我不明白为什么

btnStart.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
              Timer timer = new Timer(1000, new ActionListener() {
                 @Override
                 public void actionPerformed(ActionEvent e) {
                     System.out.println("start DONE");          
                     Object step;
                     for (int i = 1; i < n; i++) {                         
                       //code that shows on interface
                       // then i want a delay here then to carry on with the iteration of for
                       timer.start();
                       };
                 }
             });
         }
     });

你快到了。但是您似乎误解了 Timer 实际为您做了什么。

Timer 是一种伪循环,具有内置延迟。即在每个时间段之后,都会执行。这意味着,每次触发 ActionListener 时,您都希望执行逻辑中的下一步。

例如...

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Timer;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JPanel contentPane = new JPanel(new GridBagLayout());

        public TestPane() {
            setLayout(new BorderLayout());
            add(new JScrollPane(contentPane));

            JButton startButton = new JButton("Start");
            startButton.addActionListener(new ActionListener() {
                private int row = 0;
                private int count = 1000;
                private DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
                @Override
                public void actionPerformed(ActionEvent e) {
                    row = 0;
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridwidth = gbc.REMAINDER;
                    gbc.weightx = 1;
                    contentPane.removeAll();
                    contentPane.revalidate();
                    contentPane.repaint();

                    Timer timer = new Timer(100, new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            row++;
                            if (row >= count) {
                                ((Timer)(e.getSource())).stop();
                                return;
                            }

                            JLabel label = new JLabel(LocalDateTime.now().format(formatter));
                            contentPane.add(label, gbc);
                            contentPane.revalidate();
                            contentPane.repaint();
                            // This is only required because the layout pass seems
                            // to be execute in different run cycle, so the label's
                            // bounds are not been updated yet.  We force the layout
                            // pass so we can scroll to the label, but otherwise
                            // isn't needed
                            contentPane.doLayout();
                            Rectangle bounds = label.getBounds();
                            bounds.y += bounds.height;
                            contentPane.scrollRectToVisible(bounds);
                        }
                    });
                    timer.start();
                }
            });
            add(startButton, BorderLayout.NORTH);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }
}