import java.awt.*; import java.applet.*; public class Stopwatch extends Applet { Repainter repainter = new Repainter( this ); // the Repainter class regularly repaints Thread tRepainter = new Thread( repainter, "Repainter thread" ); // define the buttons of the stopwatch Button start = new Button( "Start" ); Button stop = new Button( "Stop" ); Button reset = new Button( "Reset" ); Label counter = new Label( "0" ); // the Label "counter" is the time display long msStart = 0; // time the stopwatch started running long msTotal = 0; // accumulated run time so far // the init() method is the 'main' for applets public void init() { // layout the components from the left of the frame setLayout(new FlowLayout( FlowLayout.LEFT )); resize( 300, 60 ); // start the repaint thread tRepainter.start(); // but wait a bit before actually repainting tRepainter.suspend(); // add our controls to the frame add( start ); add( stop ); add( reset ); add( counter ); msStart = 0; msTotal = 0; // initialize the display to 0.0 _updateCounter();} // MS Windows-ish handler of all events for the applet public boolean handleEvent(Event e) { // e.id is the event type switch (e.id) { // I think I should actually handle DESTROY differently for applet vs application case Event.WINDOW_DESTROY: repainter.exit(); // should stop the thread by returning from the 'run' method // (after the sleep? who cares...) System.exit(0); return true; // ACTION_EVENTS are the button pushes, etc. case Event.ACTION_EVENT: // I could rework this section to delegate functionality to // a "StopwatchState" object (Pattern: State) if( e.target == start ) { if( 0 == msStart ) // not started { // start ticking msStart = System.currentTimeMillis(); _updateCounter(); tRepainter.resume(); } } else if( e.target == stop ) { if( 0 != msStart ) // running { // stop ticking, and add up the total msTotal += System.currentTimeMillis() - msStart; msStart = 0; // stopped tRepainter.suspend(); // we don't need to be repainting frequently _updateCounter(); } } else if( e.target == reset ) { msTotal = 0; if( 0 != msStart ) // started, then keep counting from 0 { msStart = System.currentTimeMillis(); } _updateCounter(); } return true; // we've handled the message default: return false; // the message has not yet been handled } } // static 'main' is the starting function for applications public static void main(String args[]) { // In an application, we don't automagically get a frame from the browser Frame f = new Frame("Stopwatch"); // and the browser doesn't instantiate our applet, so we have to make our // own 'this' Stopwatch Stopwatch = new Stopwatch(); // do the Applet-style initialization Stopwatch.init(); // and start going... Stopwatch.start(); // add the Stopwatch to the frame we created f.add("Center", Stopwatch); f.resize( Stopwatch.size() ); // display the frame f.show(); } // take care of updating the display with the appropriate string protected void _updateCounter() { long seconds; if( 0 != msStart ) { seconds = ( msTotal + System.currentTimeMillis() - msStart ) / 1000; } else { seconds = msTotal / 1000; } counter.setText( Long.toString( seconds ) + " sec" ); getLayout().layoutContainer( this ); } } // class Stopwatch // class to continually repaint class Repainter implements Runnable { Stopwatch applet; boolean fExit; // On construction, we take the applet we should repaint public Repainter( Stopwatch applet ) { this.applet = applet; fExit = false; // we're not done yet }public void exit() { fExit = true; // set the flag that we are done } // while running, update the display every second // we could update it much more frequently, but that eats too much CPU public void run() { while( !fExit ) { applet._updateCounter(); try { Thread.sleep( 1000 ); // wait 1 second... } catch( Exception e ) { // we don't really care about the exception... } } } } // class Repainter
import java.applet.*;
public class Stopwatch extends Applet { Repainter repainter = new Repainter( this ); // the Repainter class regularly repaints
Thread tRepainter = new Thread( repainter, "Repainter thread" ); // define the buttons of the stopwatch
Button start = new Button( "Start" );
Button stop = new Button( "Stop" );
Button reset = new Button( "Reset" ); Label counter = new Label( "0" ); // the Label "counter" is the time display long msStart = 0; // time the stopwatch started running
long msTotal = 0; // accumulated run time so far // the init() method is the 'main' for applets
public void init() {
// layout the components from the left of the frame
setLayout(new FlowLayout( FlowLayout.LEFT ));
resize( 300, 60 ); // start the repaint thread
tRepainter.start();
// but wait a bit before actually repainting
tRepainter.suspend(); // add our controls to the frame
add( start );
add( stop );
add( reset ); add( counter ); msStart = 0;
msTotal = 0; // initialize the display to 0.0
_updateCounter();} // MS Windows-ish handler of all events for the applet
public boolean handleEvent(Event e) { // e.id is the event type
switch (e.id) {
// I think I should actually handle DESTROY differently for applet vs application
case Event.WINDOW_DESTROY:
repainter.exit(); // should stop the thread by returning from the 'run' method
// (after the sleep? who cares...)
System.exit(0);
return true; // ACTION_EVENTS are the button pushes, etc.
case Event.ACTION_EVENT:
// I could rework this section to delegate functionality to
// a "StopwatchState" object (Pattern: State)
if( e.target == start )
{
if( 0 == msStart ) // not started
{
// start ticking
msStart = System.currentTimeMillis();
_updateCounter();
tRepainter.resume();
}
}
else if( e.target == stop )
{
if( 0 != msStart ) // running
{
// stop ticking, and add up the total
msTotal += System.currentTimeMillis() - msStart;
msStart = 0; // stopped
tRepainter.suspend(); // we don't need to be repainting frequently
_updateCounter();
}
}
else if( e.target == reset )
{
msTotal = 0;
if( 0 != msStart ) // started, then keep counting from 0
{
msStart = System.currentTimeMillis();
}
_updateCounter();
}
return true; // we've handled the message
default:
return false; // the message has not yet been handled
}
} // static 'main' is the starting function for applications
public static void main(String args[]) {
// In an application, we don't automagically get a frame from the browser
Frame f = new Frame("Stopwatch");
// and the browser doesn't instantiate our applet, so we have to make our
// own 'this'
Stopwatch Stopwatch = new Stopwatch();
// do the Applet-style initialization
Stopwatch.init();
// and start going...
Stopwatch.start(); // add the Stopwatch to the frame we created
f.add("Center", Stopwatch);
f.resize( Stopwatch.size() );
// display the frame
f.show();
} // take care of updating the display with the appropriate string
protected void _updateCounter() {
long seconds;
if( 0 != msStart )
{
seconds = ( msTotal + System.currentTimeMillis() - msStart ) / 1000;
}
else
{
seconds = msTotal / 1000;
}
counter.setText( Long.toString( seconds ) + " sec" );
getLayout().layoutContainer( this );
}
} // class Stopwatch
// class to continually repaint
class Repainter implements Runnable {
Stopwatch applet;
boolean fExit; // On construction, we take the applet we should repaint
public Repainter( Stopwatch applet ) {
this.applet = applet;
fExit = false; // we're not done yet
}public void exit() {
fExit = true; // set the flag that we are done
} // while running, update the display every second
// we could update it much more frequently, but that eats too much CPU
public void run() {
while( !fExit )
{
applet._updateCounter();
try {
Thread.sleep( 1000 ); // wait 1 second...
}
catch( Exception e ) {
// we don't really care about the exception...
}
}
}
} // class Repainter
import java.util.*;
import java.awt.*;public class Timer extends JApplet implements Runnable{
private Thread thr;
private Calendar date;
private String s;
private JLabel l;
public void run(){
Thread me = Thread.currentThread();
while(thr==me){
try{
Thread.currentThread().sleep(100);
}catch(InterruptedException e){
System.out.println("Interrupted");
}
repaint();
}
}
public void update(Graphics g){
date=Calendar.getInstance();
s=date.get(Calendar.HOUR)+":"
+date.get(Calendar.MINUTE)+":"+date.get(Calendar.SECOND);
g.clearRect(0, 0, 100, 100);
g.drawString(s,10,15);
}
public void init(){
l=new JLabel();
getContentPane().add(l);
}
public void start(){
thr=new Thread(this);
thr.start();
}
public void stop(){
thr=null;
}
}
// g.drawString(s,10,15);
l.setText(s);
我觉得这样似乎更好一点。(但需要使用布局管理器或setBound()把这个JLabel的位置控制一下)如下列代码:
public void init(){
l=new JLabel();
getContentPane().add(l, BorderLayout.NORTH);
}