// // JClock.java // version 961204 // copyright 1996 by bo larsson // all rights reserved // // bugs or feedback to bliss@seagull.net // // include all the java packages that are needed. import java.awt.*; import java.util.*; import java.applet.*; // // JClock is a resizeable (through the width and height fields on the // applet tag) clock that gives the current time on the client machine. // It runs a separate thread to update the time. // // The time keeping Thread. This is done in a separate class // for clarity. It is possible to allow the applet class to // implement the runnable interface and then run itself as the // separate thread. That technique is common but not very clear. class ClockThread extends Thread { JClock parentApplet; // constructor public ClockThread(JClock applet) { // store away a reference to the calling applet. parentApplet = applet; } // every thread has a run method. It controls what // happens when the thread is started. When this // method returns, the thread is no longer running. public void run() { // a try block to catch the InterruptedException // which gets thrown if the thread is interrupted during // execution. try { // Do an infinite loop. It will get interrupted when // the thread needs to go away. while (true) { Date oToday = new Date(); // call the set date function in the applet. parentApplet.setDate(oToday.toString()); // and repaint the applet. parentApplet.repaint(); // every second. Argument is in milliseconds sleep(1000); } } catch (InterruptedException e) { return; } } } // // The applet class. It creates a ClockThread and runs it. // The Thread calls the paint routine(indirectly through repaint()) // which updates the display. // public class JClock extends Applet { String date; ClockThread clockThread; boolean showTime; boolean showDate; Image offScreenImage; public void init() { // process parameters showTime = true; showDate = true; if (getParameter("NoTime") != null) { showTime = false; } if (getParameter("NoDate") != null) { showDate = false; } // set and initial string. date = new String(); setDate(new String(new Date().toString())); // create the off screen image to make // painting smoother and reduce flicker. offScreenImage = createImage(size().width, size().height); } // be polite. only start the thread when this // applet is started. public void start() { clockThread = new ClockThread(this); clockThread.start(); } // be polite. Stop the thread when this // applet is stopped. public void stop() { if (clockThread != null) { clockThread.stop(); clockThread = null; } } // sets the date string member based on the argument and // the two parameters. The string format is in canonical form. public void setDate(String newDate) { date = ""; if (showDate && showTime) { date = newDate.substring(4, 10); date = date.concat(", "); date = date.concat(newDate.substring(newDate.length()-4, newDate.length())); date = date.concat(" "); date = date.concat(newDate.substring(11,19)); } else if (showDate) { date = newDate.substring(4, 10); date = date.concat(", "); date = date.concat(newDate.substring(newDate.length()-4, newDate.length())); } else if (showTime) { date = date.concat(newDate.substring(11,19)); } } // paint the bytes retrieved in green on black. public void paint(Graphics g) { // Create and initial font. Font tFont = new Font("Courier", Font.PLAIN, 6); // find a good size for the font, by looping // through reasonable point sizes. (I have never // seen a 400 point font, so it could be argued // that it isn't reasonable. But we never should get // there). We don't deal with font width so the // sizing is not ideal. for (int i = 6; i<400; i++) { int fw, fh; tFont = new Font("Courier", Font.PLAIN, i); fw = g.getFontMetrics(tFont).stringWidth(date); fh = g.getFontMetrics(tFont).getHeight(); // when it finds a font that is bigger in either // direction than the window pull back and // set it to the last size. if (fw > size().width || fh > size().height) { tFont = new Font("Courier", Font.PLAIN, i-1); break; } } g.setFont(tFont); int cx, cy; // center horizontally. cx = (size().width - g.getFontMetrics().stringWidth(date)) /2 ; // center vertically. The x y values for drawString refer to // the BOTTOM of the font, so compensate by ADDING the height // instead of SUBTRACTING it before dividing by 2. cy = (size().height + g.getFontMetrics().getHeight() ) /2 ; g.setColor(Color.black); g.fillRect(0, 0, size().width, size().height); g.setColor(Color.green); g.drawString(date, cx, cy); } // avoid flicker. public void update(Graphics g) { Graphics osg = offScreenImage.getGraphics(); paint(osg); g.drawImage(offScreenImage, 0, 0, this); } }