import java.util.*; import javax.swing.*; import java.awt.BorderLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.Container; import java.awt.event.*; public class Clock extends JFrame implements Runnable { private Thread clockThread = null; private Time time; private long accumTime = 0L; private long startTime = -1L; public static void main( String[] args ) { Clock clock = new Clock(); clock.show(); } public Clock() { super( "Clock" ); setDefaultCloseOperation( EXIT_ON_CLOSE ); JPanel buttons = new JPanel(); JButton bStart = new JButton( "start" ); bStart.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { start(); } } ); JButton bStop = new JButton( "stop" ); bStop.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { stop(); } } ); JButton bReset = new JButton( "reset" ); bReset.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { reset(); } } ); buttons.add( bStart ); buttons.add( bStop ); buttons.add( bReset ); Container content = getContentPane(); content.add( buttons, BorderLayout.NORTH ); time = new Time(); content.add( time, BorderLayout.CENTER ); setSize( 240, 120 ); startTime = System.currentTimeMillis(); } private void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); startTime = System.currentTimeMillis(); clockThread.start(); } } private void stop() { if ( clockThread != null ) { clockThread = null; accumTime += System.currentTimeMillis() - startTime; } time.repaint(); } private void reset() { accumTime = 0L; startTime = System.currentTimeMillis(); time.repaint(); } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { time.repaint(); try { Thread.sleep(100); } catch (InterruptedException e){} } } private class Time extends JPanel { Font timeFont = new Font( "SansSerif", Font.BOLD, 32 ); private static final int timeX = 60; private static final int timeY = 40; public void paintComponent(Graphics g) { super.paintComponent( g ); long ticks; if ( clockThread == null ) ticks = accumTime; else ticks = System.currentTimeMillis() - startTime + accumTime; long tenths = ticks/100L; long seconds = tenths/10L; tenths %= 10; long minutes = seconds/60L; seconds %= 60; StringBuffer sb = new StringBuffer(); if ( minutes < 10 ) sb.append( '0' ); sb.append( minutes ); sb.append( ':' ); if ( seconds < 10 ) sb.append( '0' ); sb.append( seconds ); sb.append( '.' ); sb.append( tenths ); g.setFont( timeFont ); g.drawString(sb.toString(), timeX, timeY); } } }