I am making a game. In a BorderLayout(North)
I want to show a timer while you are playing. When you lose, in a JOptionPane.showMessageDialog
show the time playing. When you win, show in a JOptionPane.showMessageDialog
the best time of the wins.
I know how to use the JOptionPane.showMessageDialog
, but I don't know if there is a method in java to generate a timer, and get the values, set values, etc.
Thanks! If someone needs more info or something, please let me know...
Some caveats to begin with...
Swing is a single threaded environment, that is, all interactions with the UI are expected to be executed from within the context of the Event Dispatching Thread. Equally, you should never block the EDT as this will prevent it from processing new events, including repaint requests.
To that end, the simplest approach would be to use something like a javax.swing.Timer
which allows you to schedule a repeating call back on a regular interval which are executed within the context of the EDT
See How to use Timers for more details...
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);
}
}
}
You are looking for a way to find out how long something takes. In programming that is usually not a timer.
You are probably looking for System.currentTimeMillis to record the time at the beginning and then again at the end and take the difference to get the "time that it took".
This thread explains how to convert that to seconds.
EDIT: Vulcan has a good point. System.nanoTime is more trustworthy because it is resilient to user changes of the system time and provides a higher resolution. Be aware though, as it states in the documentation: "This method provides nanosecond precision, but not necessarily nanosecond resolution (that is, how frequently the value changes) - no guarantees are made except that the resolution is at least as good as that of currentTimeMillis()". Here is a discussion on nanoTime.