/** File: DigitalClockApplet.java Author: Angus McIntyre Date: 22.05.96 Updated: 17.03.98 23:55 Simple Java applet to display a digital clock and update it continuously. HISTORY ------- 05.03.00 SLAM Fixed minor Y2K bug in year display. 17.03.98 SLAM Added lots of new features including date, margin width control, and control over 3D appearance of clockface. 27.05.96 SLAM Bug fixes 22.05.96 SLAM First version implemented TO-DO ----- * Use clipping regions to restrict the size of the area being updated. This should reduce flashing on some browsers. LEGAL ----- This software is free. It can be used and modified in any way you choose, but it may not be sold, either separately or as part of a collection without explicit prior permission from the author. The author assumes no liability for any loss, damage or mental or physical trauma you may incur through use of or inability to use this software. This disclaimer must appear on any modified or unmodified version of the software in which the name of the author also appears. **/ /* ---------------------------------------------------------------------- * IMPORTS * ---------------------------------------------------------------------- */ import java.applet.*; import java.awt.*; import java.util.*; import ClockApplet; /* ---------------------------------------------------------------------- * CLASSES * ---------------------------------------------------------------------- */ // Class: DigitalClockApplet // // Built on top of ClockApplet, this is used to implement simple in-line // digital clock displays. public class DigitalClockApplet extends ClockApplet { // Defaults static final String default_font_face = "Helvetica"; static final int default_font_size = 14; static final Color default_display_color = Color.red; static final Color default_back_color = Color.black; static final Color default_frame_color = Color.lightGray; static final String default_date_style = "none"; static final int default_frame_width = 2; // Instance variables String font_face; int font_size; Color display_color; Color back_color; Color frame_color; Font font = null; int x,y; int string_width = 0; int string_height = 0; int baseline_offset = 0; int frame_width = default_frame_width; String date_style = ""; boolean show_date_p = false; boolean show_am_pm_p = false; boolean relief_p = true; boolean raised_p = true; // Method: getAppletInfo() // // Return information about the applet. public String getAppletInfo() { return "DigitalClockApplet 1.1 by Angus McIntyre "; } // Method: getParameterInfo() // // Return information about the applet's parameter options. Read this // if you want to see what parameters this applet supports. public String[][] getParameterInfo() { String[][] info = { {"time-zone", "int", "TZ offset in hours from Greenwich"}, {"font", "String", "name of font used for display"}, {"fontsize", "int", "size of font used for display"}, {"color", "Color", "color used for display"}, {"frame-color", "Color", "color used for frame of clock"}, {"back-color", "Color", "color used for display background"}, {"frame-width", "int", "width of frame around clock"}, {"date-style", "String", "'us' or 'euro' - default none"}, {"draw-in-relief", "boolean", "give clock a 3D look - default to true"}, {"draw-raised", "boolean", "draw clock raised rather than indented"}, {"twenty-four-hour", "boolean", "use 24-hour clock - default to true"}, {"show-am-pm", "boolean", "show am or pm marker - default to false"}, {"show-seconds", "boolean", "show seconds - default to true"} }; return info; } // Method: init() // // Initialize the digital clock. This basically consists of reading // a whole bunch of parameters and setting up the clock's font // according to any specifications given. public void init() { super.init(); twenty_four_hour_p = parseBooleanParameter("twenty-four-hour",true); show_am_pm_p = parseBooleanParameter("show-am-pm",false); relief_p = parseBooleanParameter("draw-in-relief",true); raised_p = parseBooleanParameter("draw-raised",true); font_face = parseStringParameter("font",default_font_face); font_size = parseIntegerParameter("fontsize",default_font_size); frame_width = parseIntegerParameter("frame_width",default_frame_width); display_color = parseColorParameter("color",default_display_color); back_color = parseColorParameter("back-color",default_back_color); frame_color = parseColorParameter("frame-color",default_frame_color); font = new Font(font_face,Font.BOLD,font_size); date_style = parseStringParameter("date-style",default_date_style); show_date_p = ( date_style == "none" ? false : true ); } // Method: drawClock(Graphics) // // Draw the clock. This draws the clock's frame as a raised, 3D // rectangle, and then updates the clock display. It calls the // superclass method first to ensure that the time is correctly // set. public void drawClock (Graphics g) { super.drawClock(g); g.setColor(frame_color); if (relief_p) g.fill3DRect(bounds().x,bounds().y, bounds().width,bounds().height,raised_p); else g.fillRect(bounds().x,bounds().y, bounds().width,bounds().height); updateClock(g); } // Method: updateClock(Graphics) // // Update the clock display. Call the superclass method to get the // time correctly set, then call 'getTimeString' to convert that // to a string we can display. public void updateClock (Graphics g) { super.updateClock(g); String string = getTimeString(); // To draw the clock properly, we need to know some things // about the height and width of the string in the current // font. However, since the string length won't vary subsequently // (numbers should be fixed-width in *all* fonts, and there's no // mechanism to change the font or switch on/off the display of // seconds once the clock has started) we can get these values // just once and then cache them. This block does that, using // a FontMetrics object. In addition to the obvious business of // getting height and width, and setting up the point at which // the display is drawn (centered on the clock face) it also // calculates a 'baseline_offset' needed to position the text // properly. Drawing text isn't quite like other drawing, because // it's drawn *up* and to the left of the specified pen position. // The 'baseline_offset' takes this into account. if (string_width == 0) { FontMetrics metrics = g.getFontMetrics(font); string_width = metrics.stringWidth(string); string_height = metrics.getHeight(); baseline_offset = metrics.getAscent() - string_height; x = ((bounds().width - string_width) / 2); y = ((bounds().height - string_height) / 2); } // Wipe out the existing text with a rectangle of the background // color, and then draw the new text over it. g.setColor(back_color); g.fillRect(x-frame_width,y-frame_width, string_width+(2*frame_width), string_height+(2*frame_width)); g.setColor(display_color); g.setFont(font); g.drawString(string,x,y+string_height+baseline_offset); } // Method: getTimeString() // // Return a string showing the current time as seen by this clock. // Appropriate conversions for the 12-hour clock are carried out, // and leading zeroes are inserted where needed. protected String getTimeString() { int hours = date.getHours(); int minutes = date.getMinutes(); int seconds = date.getSeconds(); String am_pm = ( hours >= 12 ? "pm" : "am" ); // Adjust for twenty-four hour clock if required if ((twenty_four_hour_p == false) && (hours > 12)) hours -= 12; // Return the appropriate string. This is rather inefficient // in that it calls 'getDateString' as often as once a second // when strictly it only needs to be called once every twenty-four // hours. Still, the computation is trivial enough that it // shouldn't really make any odds. return ( show_date_p ? getDateString() + " " : "" ) + (hours < 10 ? "0" : "") + hours + ":" + (minutes < 10 ? "0" : "") + minutes + ( show_seconds_p ? ":" + (seconds < 10 ? "0" : "") + seconds : "") + ( show_am_pm_p ? am_pm : "" ); } // Method: getDateString() // // Get a date string. This does crude formatting according to // whether the user has specified 'us' or 'euro' style dates. // I should really use the DateFormat() class in JDK 1.1, but // I want this to run on older browsers. protected String getDateString() { int year = date.getYear(); int month = date.getMonth(); int day = date.getDate(); String yearString = (year < 10 ? "0" : "") + year; if (date_style.equalsIgnoreCase("euro")) return (day < 10 ? "0" : "") + day + "." + (month < 10 ? "0" : "") + month + "." + yearString.substring(yearString.length() - 2); else return (month < 10 ? "0" : "") + month + "/" + (day < 10 ? "0" : "") + day + "/" + yearString.substring(yearString.length() - 2); } }