我如何使用 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);
}
}
}
我是 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);
}
}
}