Java 有没有在JFrame中生成计时器的方法?
我在做游戏。在BorderLayoutNorth中,我想在您播放时显示计时器。当您丢失时,在JOptionPane.showMessage对话框中显示播放时间。获胜时,在JOptionPane.showMessageDialog中显示获胜的最佳时间 我知道如何使用JOptionPane.showMessageDialog,但我不知道java中是否有生成计时器、获取值、设置值等的方法。Java 有没有在JFrame中生成计时器的方法?,java,swing,timer,Java,Swing,Timer,我在做游戏。在BorderLayoutNorth中,我想在您播放时显示计时器。当您丢失时,在JOptionPane.showMessage对话框中显示播放时间。获胜时,在JOptionPane.showMessageDialog中显示获胜的最佳时间 我知道如何使用JOptionPane.showMessageDialog,但我不知道java中是否有生成计时器、获取值、设置值等的方法。 谢谢如果有人需要更多信息或其他信息,请告诉我……您正在寻找一种方法,以了解某件事情需要多长时间。在编程中,通常不
谢谢如果有人需要更多信息或其他信息,请告诉我……您正在寻找一种方法,以了解某件事情需要多长时间。在编程中,通常不是计时器 您可能希望在开始时记录时间,然后在结束时再次记录时间,并计算差值以获得所用的时间 解释如何将其转换为秒
编辑:瓦肯有一个很好的观点。更值得信赖,因为它能够适应用户对系统时间的更改,并提供更高的分辨率。但请注意,正如它所说的:该方法提供纳秒精度,但不一定是纳秒分辨率,即值的变化频率-除了分辨率至少与currentTimeMillis的分辨率一样好外,不作任何保证。这是一个关于纳米时间的讨论。您正在寻找一种方法来确定某件事情需要多长时间。在编程中,通常不是计时器 您可能希望在开始时记录时间,然后在结束时再次记录时间,并计算差值以获得所用的时间 解释如何将其转换为秒
编辑:瓦肯有一个很好的观点。更值得信赖,因为它能够适应用户对系统时间的更改,并提供更高的分辨率。但请注意,正如它所说的:该方法提供纳秒精度,但不一定是纳秒分辨率,即值的变化频率-除了分辨率至少与currentTimeMillis的分辨率一样好外,不作任何保证。这是一个关于纳米时间的讨论。首先要注意的是 Swing是一个单线程环境,也就是说,与UI的所有交互都应该在事件调度线程的上下文中执行。同样,您不应该阻止EDT,因为这将阻止它处理新事件,包括重新绘制请求 为此,最简单的方法是使用javax.swing.Timer之类的东西,它允许您按照在EDT上下文中执行的常规间隔安排重复回调 有关更多详细信息,请参阅
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.util.concurrent.TimeUnit;
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 CountDownTimer {
public static void main(String[] args) {
new CountDownTimer();
}
public CountDownTimer() {
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 static class TestPane extends JPanel {
private JLabel label;
private long startTime = -1;
private long timeOut = 10;
public TestPane() {
label = new JLabel("...");
final Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (startTime == -1) {
startTime = System.nanoTime();
} else {
long endTime = startTime + TimeUnit.SECONDS.toNanos(10);
long time = System.nanoTime();
if (time < endTime) {
long timeLeft = (endTime - time);
label.setText(Long.toString(TimeUnit.NANOSECONDS.toSeconds(timeLeft)) + " seconds");
} else {
label.setText("Time out");
((Timer) e.getSource()).stop();
}
revalidate();
repaint();
}
}
});
timer.setInitialDelay(0);
timer.start();
setLayout(new GridBagLayout());
add(label);
}
}
}
首先要注意的是 Swing是一个单线程环境,也就是说,与UI的所有交互都应该在事件调度线程的上下文中执行。同样,您不应该阻止EDT,因为这将阻止它处理新事件,包括重新绘制请求 为此,最简单的方法是使用javax.swing.Timer之类的东西,它允许您按照在EDT上下文中执行的常规间隔安排重复回调 有关更多详细信息,请参阅
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.util.concurrent.TimeUnit;
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 CountDownTimer {
public static void main(String[] args) {
new CountDownTimer();
}
public CountDownTimer() {
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 static class TestPane extends JPanel {
private JLabel label;
private long startTime = -1;
private long timeOut = 10;
public TestPane() {
label = new JLabel("...");
final Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (startTime == -1) {
startTime = System.nanoTime();
} else {
long endTime = startTime + TimeUnit.SECONDS.toNanos(10);
long time = System.nanoTime();
if (time < endTime) {
long timeLeft = (endTime - time);
label.setText(Long.toString(TimeUnit.NANOSECONDS.toSeconds(timeLeft)) + " seconds");
} else {
label.setText("Time out");
((Timer) e.getSource()).stop();
}
revalidate();
repaint();
}
}
});
timer.setInitialDelay(0);
timer.start();
setLayout(new GridBagLayout());
add(label);
}
}
}
应该使用System.nanoTime,而不是System.currentTimeMillis,它用于日历时间,而不是经过的时间事实上,您可以通过更改计算机的时钟来修改System.currentTimeMillis的输出。我看不到该问答中列出的任何警告,除非你使用的是早于WinXP SP2的windows版本。纳米时代的讨论似乎都不太可信,因为许多讨论都没有提供支持其主张的链接。总而言之,它似乎是一种可靠的测量时间的方法。应该使用System.nanoTime,而不是System.currentTimeMillis,它用于日历时间,而不是经过的时间。事实上,您可以通过更改计算机的时钟来修改System.currentTimeMillis的输出。我看不到该问答中列出的任何警告,除非你使用的是早于WinXP SP2的windows版本。纳米时代的讨论似乎都不太可信,因为许多讨论都没有提供支持其主张的链接。总而言之,它似乎是一种可靠的时间测量方法。