Question
Countdown Timer 1. This app counts down from 10 seconds to zero, one second at a time. 2. Only make changes to CountdownWorker.java 3. On
Countdown Timer 1. This app counts down from 10 seconds to zero, one second at a time. 2. Only make changes to CountdownWorker.java 3. On MinuteSecondDisplay, use this method to display the number of seconds left: public void setSeconds(int seconds) 4. Sleep between calls to setSeconds, but be careful to adjust your sleep time to keep from drifting off. 5. Use System.currentTimeMillis() to find out the currnet time in ms. Calculate the actual elapsed time and compare it to the expected elapsed time and adjust the next sleep time accordingly. 6. After reaching 0, print the actual total elapsed time using System.out.println(). It should be between 9960 ms and 10040 ms. If you get something more like 10500 ms, that is too far off.
CountdownTimer class
import java.awt.*; import java.awt.event.*;
import javax.swing.*;
public class CountdownTimer extends JPanel { private MinuteSecondDisplay display;
public CountdownTimer() { display = new MinuteSecondDisplay();
JButton startB = new JButton("Start"); startB.addActionListener(new ActionListener() { @SuppressWarnings("unused") @Override public void actionPerformed(ActionEvent e) { new CountdownWorker(10, display); } });
setLayout(new FlowLayout()); add(startB); add(display); }
public static void main(String[] args) { JPanel p = new JPanel(new GridLayout(0, 1)); p.add(new CountdownTimer()); p.add(new CountdownTimer()); p.add(new CountdownTimer());
JFrame f = new JFrame("CountdownTimer Demo"); f.setContentPane(p); f.pack(); f.setVisible(true); f.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } }
CountdownWorker Class
public class CountdownWorker { private final int totalSeconds; private final MinuteSecondDisplay display;
public CountdownWorker(int totalSeconds, MinuteSecondDisplay display) { this.totalSeconds = totalSeconds; this.display = display;
// do the self-run pattern to spawn a thread to do the counting down... // ...
}
// TODO - add methods to do the counting down and time correction.... // call: display.setSeconds(...
}
MinuteSecondDisplay class
import java.awt.*; import java.text.*;
import javax.swing.*;
public class MinuteSecondDisplay extends JPanel { private static final Font TIME_FONT = new Font("Monospaced", Font.BOLD, 24); private static final NumberFormat FORMATTER;
static { NumberFormat f = NumberFormat.getInstance(); f.setMaximumFractionDigits(0); f.setMaximumIntegerDigits(2); f.setMinimumIntegerDigits(2); FORMATTER = f; }
private volatile int seconds; private boolean delayOn; private Runnable updateTask; private JLabel timeL;
public MinuteSecondDisplay() { seconds = 0; delayOn = true;
updateTask = new Runnable() { @Override public void run() { updateTimeLabel(); } };
timeL = new JLabel("00:00", JLabel.CENTER); timeL.setFont(TIME_FONT); timeL.setForeground(Color.BLACK); updateTimeLabel();
setLayout(new GridLayout()); setBorder(BorderFactory.createEtchedBorder()); add(timeL); }
public void setSeconds(int seconds) { this.seconds = seconds; SwingUtilities.invokeLater(updateTask);
if ( delayOn && (seconds > 0) ) { // exaggerates time to run this method takeRandomMiniNap(); } }
private void takeRandomMiniNap() { try { // sleep for 0 to 99 ms long napTime = (long) (Math.random() * 100.0); Thread.sleep(napTime); } catch ( InterruptedException x ) { Thread.currentThread().interrupt(); // reassert intr return; } }
private void updateTimeLabel() { int totalSec = seconds; // capture current value snapshot int sec = totalSec % 60; int min = (totalSec / 60) % 60; timeL.setText(FORMATTER.format(min) + ":" + FORMATTER.format(sec)); } }
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started