import java.awt.*;
import java.util.*;
import java.text.*;

public class ClockComp extends Component {
	// Using a variation on the "Self-Running Object"
	// technique from Chapter 11 of "Java Thread Programming".
	// See that chapter of the book for more on internal threads

	private volatile String timeStr;
	private volatile boolean noStopRequested;
	private Thread internalThread;
	private DateFormat df;
	private Dimension prefSize;
	private Font font;

	public ClockComp() {
		prefSize = new Dimension(200, 40);
		font = new Font("Monospaced", Font.BOLD, 14);

		df = DateFormat.getTimeInstance(DateFormat.LONG);
		updateTime();
	}

	public Dimension getPreferredSize() {
		return prefSize;
	}

	public void paint(Graphics g) {
		g.setFont(font);
		g.setColor(Color.blue);
		g.drawString(timeStr, 0, 20);
	}

	private void updateTime() {
		timeStr = df.format(
				new Date(System.currentTimeMillis()));
	}

	private void runWork() {
		try {
			while ( noStopRequested ) {
				updateTime();
				repaint();
				Thread.sleep(300);
			}

			timeStr = "STOPPED - by flag";
		} catch ( InterruptedException x ) {
			timeStr = "STOPPED - by InterruptedException";
		} finally {
			repaint();
			System.out.println("clock is stopped");
		}
	}

	public synchronized void start() {
		if ( ( internalThread != null ) && 
			 ( internalThread.isAlive() == true )
		   ) {

			// running already, ignore
			System.out.println(
				"clock is already running --ignoring start");
			return;
		}

		noStopRequested = true;
		Runnable r = new Runnable() {
				public void run() {
					runWork();
				}
			};

		internalThread = new Thread(r, "clock");
		internalThread.start();
		System.out.println("clock started");
	}

	public synchronized void interruptOnly() {
		if ( ( internalThread != null ) && 
		   	 ( internalThread.isAlive() == true )
		   ) {
			internalThread.interrupt();
			System.out.println(
					"clock received interrupt only");
		}
	}

	public synchronized void stopRequest() {
		if ( noStopRequested ) {
			noStopRequested = false;
			internalThread.interrupt();
			System.out.println(
					"clock received stop request");
		}
	}
}
