Note: To embed the following HTML and JavaScript within <pre></pre> tags and
make it display as desired, I used the JavaScript Code to HTML Converter
at http://www.itadmintools.com/2013/06/javascript-code-to-html-converter.html
I also avoided Blogger's Compose editor and only used the HTML editor.
<h1 id="betterStopwatchDisplay">Newest stopwatch!</h1>
<br>
<button onclick="betterStopwatch.pressLeftButton()">Left</button>
<button onclick="betterStopwatch.pressTopButton()">Top</button>
<br>
<script>
/** Timer ********************************************
*
* A timer is a specialized type of clock for
* measuring time intervals.
*
* Source: https://en.wikipedia.org/wiki/Timer
* retrieved on 13 Oct 2016
*/
function Timer() {
var timeStarted = null;
var timeStopped = null;
this.reset = function() {
timeStarted = null;
timeStopped = null;
}
this.start = function() {
timeStarted = new Date();
}
this.stop = function() {
timeStopped = new Date();
}
this.isStarted = function() {
return timeStarted != null;
}
this.isStopped = function() {
return timeStopped != null;
}
this.isRunning = function() {
return this.isStarted() && !this.isStopped();
}
this.elapsedTimeInMs = function() {
if (timeStarted != null) {
if (timeStopped != null) {
return timeStopped - timeStarted;
}
else {
return new Date() - timeStarted;
}
}
else {
return 0;
}
}
}
/** Horology *********************************************************
*
* Horology (via Latin horologium ... literally "the study of time")
* ... is the art or science of measuring time.
*
* Source: https://en.wikipedia.org/wiki/Horology
* retrieved 13 Oct 2016
*/
/** Movement *********************************************************
*
* In horology, a movement, also known as a caliber, is the mechanism
* of a clock or watch, as opposed to the case, which encloses and
* protects the movement, and the face which displays the time.
*
* Source: https://en.wikipedia.org/wiki/Movement_(clockwork)
* retrieved on 13 Oct 2016
*/
function StopwatchMovement(timer) {
var isFrozenBit = false;
var previousElapsedTimeInMs = 0;
/** METHOD: onTopButtonPress
* I. Manages the movement's timer:
* If the timer has not been not started:
* Then sets previous elapsed time to zero,
* And then starts the timer.
* Else if the timer is running:
* Then stops timer.
* Else:
* Sets previous elapsed time to current elapsed time,
* And then restarts the timer.
* II. Sets a value that may affect the display:
* Sets isFrozenBit equal to false.
* Returns:
* Total elapsed time in milliseconds as of the point
* in time when the timer was stopped or when the method
* returns.
*/
this.onTopButtonPressed = function() {
if (!timer.isStarted()) {
previousElapsedTimeInMs = 0;
timer.start();
}
else if (timer.isRunning()) {
timer.stop();
}
else {
previousElapsedTimeInMs = this.elapsedTimeInMs();
timer.reset();
timer.start();
}
isFrozenBit = false;
return this.elapsedTimeInMs();
}
/** METHOD: onLeftButtonPress
* I. Manages the movement's timer and values that may
* affect the display:
* If the timer is running:
* Toggles the (boolean) value of isFrozenBit,
* And then returns the current elapsed time.
* Else:
* Resets the timer,
* Sets the previous elapsed time to zero,
* Sets the value of isFrozenBit to false,
* And then returns zero.
* Returns:
* Total elapsed time in milliseconds as of the point
* in time when the method returns.
*/
this.onLeftButtonPressed = function() {
if (timer.isRunning()) {
isFrozenBit = !isFrozenBit;
return this.elapsedTimeInMs();
}
else {
timer.reset();
previousElapsedTimeInMs = 0;
isFrozenBit = false;
return 0;
}
}
this.isRunning = function() {
return timer.isRunning();
}
this.isFrozen = function() {
return isFrozenBit;
}
this.elapsedTimeInMs = function() {
return previousElapsedTimeInMs + timer.elapsedTimeInMs();
}
}
/** Stopwatch **************************************************
*
* A stopwatch is a handheld timepiece designed to measure
* the amount of time elapsed from a particular time when it
* is activated to the time when the piece is deactivated.
*
* The timing functions are traditionally controlled by two
* buttons on the case. Pressing the top button starts the
* timer running, and pressing the button a second time stops
* it, leaving the elapsed time displayed. A press of the
* second button then resets the stopwatch to zero. The second
* button is also used to record split times or lap times.
* When the split time button is pressed while the watch is
* running, the display freezes, allowing the elapsed time to
* that point to be read, but the watch mechanism continues
* running to record total elapsed time. Pressing the split
* button a second time allows the watch to resume display of
* total time.
*
* Source: https://en.wikipedia.org/wiki/Stopwatch
* retrieved on 12 Oct 2016
*/
function TraditionalStopwatch(movement, face, refreshPeriod) {
function periodicallyUpdateDisplay() {
function doItAndRepeat() {
if (!movement.isFrozen()) {
face.display(movement.elapsedTimeInMs());
}
periodicallyUpdateDisplay();
}
if (movement.isRunning()) {
setTimeout(doItAndRepeat, refreshPeriod);
}
}
this.pressTopButton = function() {
face.display(movement.onTopButtonPressed());
periodicallyUpdateDisplay();
}
this.pressLeftButton = function() {
face.display(movement.onLeftButtonPressed());
}
}
/** A Clock Face ****************************************************
*
* Clocks existed before clock faces. The first mechanical clocks,
* built in 13th-century Europe, were striking clocks: their purpose
* was to ring bells upon the canonical hours, to call the public to
* prayer. ... These were erected as tower clocks in public places,
* to ensure that the bells were audible. It was not until these
* mechanical clocks were in place that their creators realized that
* their wheels could be used to drive an indicator on a dial on the
* outside of the tower, where it could be widely seen.
*
* Source: https://en.wikipedia.org/wiki/Clock_face
* retrieved on 13 Oct 2016
*/
var clockFace = {
display: function(value) {
document.getElementById("betterStopwatchDisplay").innerHTML = value;
}
}
/** A New Stopwatch **/
var betterStopwatch
= new TraditionalStopwatch(new StopwatchMovement(new Timer()), clockFace, 25);
</script>
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/** Timer ********************************************
*
* A timer is a specialized type of clock for
* measuring time intervals.
*
* Source: https://en.wikipedia.org/wiki/Timer
* retrieved on 13 Oct 2016
*/
class Timer {
private long timeStarted;
private long timeStopped;
Timer() {
this.reset();
}
void reset() {
this.timeStarted = -1;
this.timeStopped = -1;
}
void start() {
this.timeStarted = System.currentTimeMillis();
}
void stop() {
this.timeStopped = System.currentTimeMillis();
}
boolean isStarted() {
return this.timeStarted != -1;
}
boolean isStopped() {
return this.timeStopped != -1;
}
boolean isRunning() {
return this.isStarted() && !this.isStopped();
}
long elapsedTimeInMs() {
if (this.timeStarted != -1) {
if (this.timeStopped != -1) {
return this.timeStopped - this.timeStarted;
}
else {
return System.currentTimeMillis() - this.timeStarted;
}
}
else {
return -1;
}
}
}
/** Horology *********************************************************
*
* Horology (via Latin horologium ... literally "the study of time")
* ... is the art or science of measuring time.
*
* Source: https://en.wikipedia.org/wiki/Horology
* retrieved 13 Oct 2016
*/
/** Movement *********************************************************
*
* In horology, a movement, also known as a caliber, is the mechanism
* of a clock or watch, as opposed to the case, which encloses and
* protects the movement, and the face which displays the time.
*
* Source: https://en.wikipedia.org/wiki/Movement_(clockwork)
* retrieved on 13 Oct 2016
*/
class StopwatchMovement {
private boolean isFrozenBit = false;
private long previousElapsedTimeInMs = 0;
private Timer timer;
StopwatchMovement(Timer timer) {
this.timer = timer;
}
/** METHOD: onTopButtonPress
* I. Manages the movement's timer:
* If the timer has not been not started:
* Then sets previous elapsed time to zero,
* And then starts the timer.
* Else if the timer is running:
* Then stops timer.
* Else:
* Sets previous elapsed time to current elapsed time,
* And then restarts the timer.
* II. Sets a value that may affect the display:
* Sets isFrozenBit equal to false.
* Returns:
* Total elapsed time in milliseconds as of the point
* in time when the timer was stopped or when the method
* returns.
*/
long onTopButtonPressed() {
if (!timer.isStarted()) {
previousElapsedTimeInMs = 0;
timer.start();
}
else if (timer.isRunning()) {
timer.stop();
}
else {
previousElapsedTimeInMs = this.elapsedTimeInMs();
timer.reset();
timer.start();
}
isFrozenBit = false;
return this.elapsedTimeInMs();
}
/** METHOD: onLeftButtonPress
* I. Manages the movement's timer and values that may
* affect the display:
* If the timer is running:
* Toggles the (boolean) value of isFrozenBit,
* And then returns the current elapsed time.
* Else:
* Resets the timer,
* Sets the previous elapsed time to zero,
* Sets the value of isFrozenBit to false,
* And then returns zero.
* Returns:
* Total elapsed time in milliseconds as of the point
* in time when the method returns.
*/
long onLeftButtonPressed() {
if (timer.isRunning()) {
isFrozenBit = !isFrozenBit;
return this.elapsedTimeInMs();
}
else {
timer.reset();
previousElapsedTimeInMs = 0;
isFrozenBit = false;
return 0;
}
}
boolean isRunning() {
return timer.isRunning();
}
boolean isFrozen() {
return isFrozenBit;
}
long elapsedTimeInMs() {
return previousElapsedTimeInMs + timer.elapsedTimeInMs();
}
}
/** Stopwatch **************************************************
*
* A stopwatch is a handheld timepiece designed to measure
* the amount of time elapsed from a particular time when it
* is activated to the time when the piece is deactivated.
*
* The timing functions are traditionally controlled by two
* buttons on the case. Pressing the top button starts the
* timer running, and pressing the button a second time stops
* it, leaving the elapsed time displayed. A press of the
* second button then resets the stopwatch to zero. The second
* button is also used to record split times or lap times.
* When the split time button is pressed while the watch is
* running, the display freezes, allowing the elapsed time to
* that point to be read, but the watch mechanism continues
* running to record total elapsed time. Pressing the split
* button a second time allows the watch to resume display of
* total time.
*
* Source: https://en.wikipedia.org/wiki/Stopwatch
* retrieved on 12 Oct 2016
*/
class TraditionalStopwatch {
private StopwatchMovement movement;
private ClockFace face;
private int refreshPeriod;
TraditionalStopwatch(
StopwatchMovement movement,
ClockFace face,
int refreshPeriod) {
this.movement = movement;
this.face = face;
this.refreshPeriod = refreshPeriod;
}
void periodicallyUpdateDisplay() {
face.display(movement.elapsedTimeInMs());
/* still working on it... */
}
void pressTopButton() {
face.display(movement.onTopButtonPressed());
periodicallyUpdateDisplay();
}
void pressLeftButton() {
face.display(movement.onLeftButtonPressed());
}
}
/** A Clock Face ****************************************************
*
* Clocks existed before clock faces. The first mechanical clocks,
* built in 13th-century Europe, were striking clocks: their purpose
* was to ring bells upon the canonical hours, to call the public to
* prayer. ... These were erected as tower clocks in public places,
* to ensure that the bells were audible. It was not until these
* mechanical clocks were in place that their creators realized that
* their wheels could be used to drive an indicator on a dial on the
* outside of the tower, where it could be widely seen.
*
* Source: https://en.wikipedia.org/wiki/Clock_face
* retrieved on 13 Oct 2016
*/
class ClockFace {
JLabel output;
ClockFace() {
this.output = new JLabel("Java stopwatch!");
JFrame frame = new JFrame("Traditional Stopwatch");
frame.getContentPane().add(output, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
}
void display(Long value) {
output.setText(value.toString());
}
}
class BetterStopwatch {
public static void main(String[] args) {
TraditionalStopwatch betterStopwatch
= new TraditionalStopwatch(new StopwatchMovement(new Timer()), new ClockFace(), 1000);
}
}