/* * javex.java - 19 Jan 1996 - Version 1.00 * * Note: This source code is subject to perpetual refinement! * * Copyright 1996 by Bill Giel * * E-mail: rvdi@usa.nai.net * WWW: http://www.nai.net/~rvdi/home.htm * * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and * without fee is hereby granted, provided that any use properly credits * the author, i.e. "Javex Clock courtesy of * Bill Giel. * * * THE AUTHOR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHOR SHALL NOT BE LIABLE * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. * * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). YOU WOULD * HAVE TO BE OUT OF YOUR MIND TO USE THIS SOFTWARE IN A HIGH-RISK ENVIRONMENT * AND, AS SUCH MAY BE THE CASE, THE AUTHOR SPECIFICALLY DISCLAIMS ANY EXPRESS * OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES, INCLUDING BUT NOT * LIMITED TO USE OR MISUSE OF THIS SOFTWARE RESULTING IN NUCLEAR EXPLOSIONS, * GLOBAL WARMING OR OZONE-LAYER DEPLETION. */ import java.awt.*; import java.applet.*; import java.lang.*; import java.util.*; import java.net.*; class hms extends Date { public hms(){super();} public double get_hours() { return (double)super.getHours()+(double)getMinutes()/60.0; } } abstract class clockHand { protected int baseX[], baseY[]; protected int transX[],transY[]; protected int numberOfPoints; public clockHand(int originX, int originY, int length,int thickness,int points){ baseX= new int[points]; baseY=new int[points]; transX= new int[points]; transY=new int[points]; initiallizePoints(originX,originY,length,thickness); numberOfPoints=points; } abstract protected void initiallizePoints( int originX, int originY, int length, int thickness); abstract public void draw(Color color, double angle, Graphics g); protected void transform(double angle) { for(int i=0;i"}, {"faceColor", "string", "hex color triplet of clock face, i.e. 000000 for black "}, {"sweepColor", "string", "hex color triplet of seconds hand, i.e. FF0000 for red "}, {"minuteColor", "string", "hex color triplet of minutes hand, i.e. C0C0C0 for lt.gray "}, {"hourColor", "string", "hex color triplet of hours hand, i.e. FFFFFF for white "}, {"textColor", "string", "hex color triplet of numbers, etc., i.e. FFFFFF for white "}, {"caseColor", "string", "hex color triplet of case, i.e. 000000 for black "}, {"trimColor", "string", "hex color triplet of case outliners, i.e. C0C0C0 for lt.gray "}, {"bgImageURL", "string", "URL of background image, if any "}, {"logoString", "string", "Name to display on watch face "}, {"logoImageURL","string", "URL of logo image to display on watch face "}, }; return info; } //Applet name, author and info lines public String getAppletInfo() { return "JAVEX - analog clock applet by Bill Giel, 17 Jan 96\nhttp://www.nai.net/~rvdi/home.htm or rvdi@usa.nai.net"; } void showURLerror(Exception e) { String errorMsg = "JAVEX URL error: "+e; showStatus(errorMsg); System.err.println(errorMsg); } // This lets us create clocks of various sizes, but with the same // proportions. private int size(int percent) { return (int)((double)percent/100.0 * (double)minDimension); } public void init() { URL imagesURL[] = new URL[2]; String szImagesURL[] = new String[2]; tracker = new MediaTracker(this); String paramString = getParameter( "WIDTH" ); if( paramString != null ) width = Integer.valueOf(paramString).intValue(); paramString = getParameter( "HEIGHT" ); if( paramString != null ) height = Integer.valueOf(paramString).intValue(); paramString = getParameter( "BGCOLOR"); if( paramString != null ) bgColor=parseColorString(paramString); paramString = getParameter( "FACECOLOR"); if( paramString != null ) faceColor=parseColorString(paramString); paramString = getParameter( "SWEEPCOLOR"); if( paramString != null ) sweepColor=parseColorString(paramString); paramString = getParameter( "MINUTECOLOR"); if( paramString != null ) minuteColor=parseColorString(paramString); paramString = getParameter( "HOURCOLOR"); if( paramString != null ) hourColor=parseColorString(paramString); paramString = getParameter( "TEXTCOLOR"); if( paramString != null ) textColor=parseColorString(paramString); paramString = getParameter( "CASECOLOR"); if( paramString != null ) caseColor=parseColorString(paramString); paramString = getParameter( "TRIMCOLOR"); if( paramString != null ) trimColor=parseColorString(paramString); logoString = getParameter( "LOGOSTRING"); if( logoString == null ) logoString=JAVEX; else if(logoString.length() > 8) logoString= logoString.substring(0,8); //Max 8 characters! szImagesURL[BACKGROUND] = getParameter("BGIMAGEURL"); szImagesURL[LOGO] = getParameter("LOGOIMAGEURL"); for(int i=0; i<2; i++){ if(szImagesURL[i] != null){ try{ imagesURL[i]=new URL(getDocumentBase(),szImagesURL[i]); } catch (MalformedURLException e) { showURLerror(e); imagesURL[i]=null; images[i]=null; } if(imagesURL[i] != null){ showStatus("Javex loading image: " + imagesURL[i].toString()); images[i]=getImage(imagesURL[i]); if(images[i] != null) tracker.addImage(images[i],i); showStatus(""); } if(images[i] != null) try{ tracker.waitForID(i); }catch (InterruptedException e) { images[i]=null; } } else images[i]=null; } cur_time=new hms(); lastHour=-1.0; lastMinute=-1; lastSecond=-1; x1=width/2; y1=height/2; minDimension= Math.min(width, height); originX=(width-minDimension)/2; originY=(height-minDimension)/2; xPoints[1]=x1-size(3); xPoints[2]=x1+size(3); xPoints[0]=x1; yPoints[1]=y1-size(38);yPoints[2]=y1-size(38); yPoints[0]=y1-size(27); sweep=new sweepHand(x1,y1,size(40),3); minuteHand=new hmHand(x1,y1,size(40),size(6),6); hourHand=new hmHand(x1,y1,size(25),size(8),6); font=new Font("TXT",Font.BOLD,size(10)); offScrImage = createImage(width,height); offScrGC = offScrImage.getGraphics(); } public void start() { if(clockThread == null){ clockThread = new Thread(this); clockThread.start(); } } public void stop() { clockThread.stop(); clockThread=null; } private void drawHands(Graphics g) { double angle; int i,j; int x,y; angle=MINSEC * lastSecond; sweep.draw(faceColor, angle, g); if(cur_time.getMinutes() != lastMinute){ minuteHand.draw(faceColor,MINSEC*lastMinute,g); if(cur_time.get_hours() != lastHour) hourHand.draw(faceColor,HOUR*lastHour,g); } g.setColor(textColor); g.fillRect(originX+size(12),y1-size(2),size(10),size(4)); g.fillRect(x1-size(2),originY + minDimension-size(22),size(4),size(10)); g.fillPolygon( xPoints, yPoints, 3); for(i=1;i<12;i+=3) for(j=i;j 0 && y > 0) offScrGC.drawImage(images[LOGO], x, y, this); } lastHour=cur_time.get_hours(); hourHand.draw(hourColor,HOUR*lastHour,g); lastMinute=cur_time.getMinutes(); minuteHand.draw(minuteColor,MINSEC*lastMinute,g); g.setColor(minuteColor); g.fillOval(x1-size(4),y1-size(4),size(8),size(8)); g.setColor(sweepColor); g.fillOval(x1-size(3),y1-size(3),size(6),size(6)); lastSecond=cur_time.getSeconds(); angle=MINSEC*lastSecond; sweep.draw(sweepColor, angle,g); g.setColor(trimColor); g.fillOval(x1-size(1),y1-size(1),size(2),size(2)); } private Color parseColorString(String colorString) { if(colorString.length()==6){ int R = Integer.valueOf(colorString.substring(0,2),16).intValue(); int G = Integer.valueOf(colorString.substring(2,4),16).intValue(); int B = Integer.valueOf(colorString.substring(4,6),16).intValue(); return new Color(R,G,B); } else return Color.lightGray; } public void run() { //Let's not hog the system, now... Thread.currentThread().setPriority(Thread.MIN_PRIORITY); repaint(); for(;;){ cur_time=new hms(); repaint(); try{ Thread.sleep(1000); } catch (InterruptedException e) {} } } public void paint(Graphics g) { int i,x0,y0,x2,y2; if(images[BACKGROUND] == null){ offScrGC.setColor(bgColor); offScrGC.fillRect(0,0,width,height); } else offScrGC.drawImage(images[BACKGROUND], 0, 0, this); offScrGC.setColor(caseColor); //Shrink one pixel so we don't clip anything off... offScrGC.fillOval( originX+1, originY+1, minDimension-2, minDimension-2); offScrGC.setColor(faceColor); offScrGC.fillOval( originX + size(5), originY + size(5), minDimension - size(10), minDimension - size(10)); offScrGC.setColor(trimColor); offScrGC.drawOval( originX+1, originY+1, minDimension-2, minDimension-2); offScrGC.drawOval( originX + size(5), originY + size(5), minDimension - size(10), minDimension - size(10)); offScrGC.setColor(textColor); //Draw graduations, a longer index every fifth mark... for(i=0;i<60;i++){ if(i==0 || (i>=5 && i%5 == 0)){ x0=(int)(x1+size(40)*Math.sin(MINSEC*i)); y0=(int)(y1+size(40)*Math.cos(MINSEC*i)); } else{ x0=(int)(x1+size(42)*Math.sin(MINSEC*i)); y0=(int)(y1+size(42)*Math.cos(MINSEC*i)); } x2=(int)(x1+size(44)*Math.sin(MINSEC*i)); y2=(int)(y1+size(44)*Math.cos(MINSEC*i)); offScrGC.drawLine(x0,y0,x2,y2); } drawHands(offScrGC); g.drawImage(offScrImage,0,0,this); isPainted=true; } public synchronized void update(Graphics g) { if(!isPainted) paint(g); else{ drawHands(offScrGC); g.drawImage(offScrImage,0,0,this); } } }