Java 摇摆计时器倒计时
Java Swing Timer Countdown
我必须制作一个倒计时程序,它还显示十分之一秒;
例如从 10.0 秒倒计时,它应该显示 9.9s,9.8s,... 0.0s
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
timer.start();
timer2.start();
}
Double timeLeft=5000; //5 seconds
Timer timer=new Timer(1,countDown);
Timer timer2=new Timer(1000,countDown2);
ActionListener countDown=new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
timeLeft--;
SimpleDateFormat df=new SimpleDateFormat("mm:ss:S");
jLabel1.setText(df.format(timeLeft));
if(timeLeft<=0)
{
timer.stop();
}
}
};
发生的情况是完成 5 秒需要超过 5 秒。
我将上面的代码与另一个 Timer 进行了比较
int timeLeft2=5;
ActionListener countDown2=new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
timeLeft2--;
jLabel2.setText(String.valueOf(timeLeft2));
if(timeLeft2<=0)
{
time2.stop();
}
}
};
他们不一样是自然的吗?
更新标签可能需要超过 1 毫秒,这就是它跟不上的原因。如果您只需要显示十分之一秒,只需降低计时器的更新频率即可。
ActionListener countDown=new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
timeLeft -= 100;
SimpleDateFormat df=new SimpleDateFormat("mm:ss:S");
jLabel1.setText(df.format(timeLeft));
if(timeLeft<=0)
{
timer.stop();
}
}
};
Timer timer=new Timer(100, countdown);
滴答之间的时间(调用actionPerfomed
的时间)是可变的,它只保证至少是n
毫秒
与其依赖一些随着时间的推移可能变得不可靠的计数器,您应该尝试计算 Timer
开始时间与当前时间之间的差异,例如...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class CountDown {
public static void main(String[] args) {
new CountDown();
}
public CountDown() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Timer timer;
private long startTime = -1;
private long duration = 5000;
private JLabel label;
public TestPane() {
setLayout(new GridBagLayout());
timer = new Timer(10, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (startTime < 0) {
startTime = System.currentTimeMillis();
}
long now = System.currentTimeMillis();
long clockTime = now - startTime;
if (clockTime >= duration) {
clockTime = duration;
timer.stop();
}
SimpleDateFormat df = new SimpleDateFormat("mm:ss:SSS");
label.setText(df.format(duration - clockTime));
}
});
timer.setInitialDelay(0);
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!timer.isRunning()) {
startTime = -1;
timer.start();
}
}
});
label = new JLabel("...");
add(label);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
我必须制作一个倒计时程序,它还显示十分之一秒; 例如从 10.0 秒倒计时,它应该显示 9.9s,9.8s,... 0.0s
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
timer.start();
timer2.start();
}
Double timeLeft=5000; //5 seconds
Timer timer=new Timer(1,countDown);
Timer timer2=new Timer(1000,countDown2);
ActionListener countDown=new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
timeLeft--;
SimpleDateFormat df=new SimpleDateFormat("mm:ss:S");
jLabel1.setText(df.format(timeLeft));
if(timeLeft<=0)
{
timer.stop();
}
}
};
发生的情况是完成 5 秒需要超过 5 秒。
我将上面的代码与另一个 Timer 进行了比较
int timeLeft2=5;
ActionListener countDown2=new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
timeLeft2--;
jLabel2.setText(String.valueOf(timeLeft2));
if(timeLeft2<=0)
{
time2.stop();
}
}
};
他们不一样是自然的吗?
更新标签可能需要超过 1 毫秒,这就是它跟不上的原因。如果您只需要显示十分之一秒,只需降低计时器的更新频率即可。
ActionListener countDown=new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
timeLeft -= 100;
SimpleDateFormat df=new SimpleDateFormat("mm:ss:S");
jLabel1.setText(df.format(timeLeft));
if(timeLeft<=0)
{
timer.stop();
}
}
};
Timer timer=new Timer(100, countdown);
滴答之间的时间(调用actionPerfomed
的时间)是可变的,它只保证至少是n
毫秒
与其依赖一些随着时间的推移可能变得不可靠的计数器,您应该尝试计算 Timer
开始时间与当前时间之间的差异,例如...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class CountDown {
public static void main(String[] args) {
new CountDown();
}
public CountDown() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Timer timer;
private long startTime = -1;
private long duration = 5000;
private JLabel label;
public TestPane() {
setLayout(new GridBagLayout());
timer = new Timer(10, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (startTime < 0) {
startTime = System.currentTimeMillis();
}
long now = System.currentTimeMillis();
long clockTime = now - startTime;
if (clockTime >= duration) {
clockTime = duration;
timer.stop();
}
SimpleDateFormat df = new SimpleDateFormat("mm:ss:SSS");
label.setText(df.format(duration - clockTime));
}
});
timer.setInitialDelay(0);
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!timer.isRunning()) {
startTime = -1;
timer.start();
}
}
});
label = new JLabel("...");
add(label);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}