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

Time:03-29

i'm new to Java and I'm trying to add a time delay when I press a Jbutton start. I used TimeUnit.SECONDS.sleep() but it didn't work, then i researched and found out about java swing timer, but it didn't work either and I can't figure out why

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();
                       };
                 }
             });
         }
     });

CodePudding user response:

I think you'll find a wonderful answer here that should get you going in the right direction: enter image description here

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);
        }
    }
}
  • Related