home *** CD-ROM | disk | FTP | other *** search
Java Source | 1995-10-08 | 17.9 KB | 543 lines |
- /*
- * javex.java - 19 Jan 1996 - Version 1.03
- *
- * 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
- *
- *
- * Revision 1.01 - revised hms class to calculate GMT. This permits the clock
- * 10 Feb 96 to be used to display the time at any location by supplying
- * a TIMEZONE parameter in the HTML call.
- *
- * Revision 1.02 - revised timezone to accept real numbers, for places like
- * 11 Feb 96 India, with a 5.5 hour time difference. I learn something
- * new everyday!
- *
- * Revision 1.03 - fixed loop in run() to exit if clockThread==null, rather
- * than simple for(;;)
- *
- * Usage:
- *
- *
- * 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 <A HREF="mailto:rvdi@usa.nai.net">
- * Bill Giel</A>.
- *
- *
- * 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
- {
- //Note that localOffset is hours difference from GMT
- //west of Greenwich meridian is positive, east is negative.
- //i.e. New York City (Eastern Standard Time) is +5
- // Eastern Daylight Time is +4
-
- public hms(double localOffset){
- super();
- long tzOffset=getTimezoneOffset()*60L*1000L;
- setTime(getTime() + tzOffset - (long)(localOffset*3600.0*1000.0));
- }
-
- 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<numberOfPoints;i++){
- transX[i]=(int)( (baseX[0]-baseX[i]) * Math.cos(angle) -
- (baseY[0]-baseY[i]) * Math.sin(angle) +
- baseX[0]);
-
- transY[i]=(int)( (baseX[0]-baseX[i]) * Math.sin(angle) +
- (baseY[0]-baseY[i]) * Math.cos(angle) +
- baseY[0]);
- }
- }
- }
-
- class sweepHand extends clockHand
- {
- public sweepHand(int originX,int originY, int length, int points)
- {
- super(originX,originY,length,0,points);
- }
-
- protected void initiallizePoints(int originX,int originY, int length, int unused)
- {
- unused=unused; //We don't use the thickness parameter in this class
- //This comes from habit to prevent compiler warning
- //concerning unused arguments.
-
- baseX[0]=originX; baseY[0]=originY;
- baseX[1]=originX; baseY[1]=originY-length/5;
- baseX[2]=originX; baseY[2]=originY+length;
- }
-
- public void draw(Color color, double angle, Graphics g)
- {
- transform(angle);
- g.setColor(color);
- g.drawLine(transX[1],transY[1],transX[2],transY[2]);
- }
- }
-
- class hmHand extends clockHand
- {
- public hmHand(int originX,int originY, int length,int thickness, int points){
- super(originX,originY,length,thickness,points);
- }
-
- protected void initiallizePoints( int originX,
- int originY,
- int length,
- int thickness)
- {
- baseX[0]=originX;
- baseY[0]=originY;
-
- baseX[1]=baseX[0]-thickness/2;
- baseY[1]=baseY[0]+thickness/2;
-
- baseX[2]=baseX[1];
- baseY[2]=baseY[0]+length- thickness;
-
- baseX[3]=baseX[0];
- baseY[3]=baseY[0]+length;
-
- baseX[4]=baseX[0]+thickness/2;
- baseY[4]=baseY[2];
-
- baseX[5]=baseX[4];
- baseY[5]=baseY[1];
- }
-
- public void draw(Color color,double angle, Graphics g)
- {
- transform(angle);
- g.setColor(color);
- g.fillPolygon(transX,transY,numberOfPoints);
- }
- }
-
- public class Javex extends Applet implements Runnable
- {
- //JAVADRAW Wizard.Cut.Start
- String AText = "SFS Software";
- Font AFont = new Font ("TimesRoman", Font.PLAIN, 10);
- Color ABackgroundcolor = Color.black;
- Color AFacecolor = Color.green;
- Color ASweepcolor = Color.white;
- Color AMinutecolor = Color.red;
- Color AHourcolor = Color.magenta;
- Color ATextcolor = Color.black;
- Color ACasecolor = Color.gray;
- Color ATrimcolor = Color.pink;
- int width = 100;
- int height = 100;
- //JAVADRAW Wizard.Cut.End
- static final int BACKGROUND=0; //Background image index
- static final int LOGO=1; //Logo image index
- static final double MINSEC=0.104719755; //Radians per minute or second
- static final double HOUR=0.523598776; //Radians per hour
-
- Thread clockThread = null;
-
- //User options, see getParameterInfo(), below.
-
-
- String logoString=null;
-
- Image images[] = new Image[2]; //Array to hold optional images
-
- boolean isPainted=false; //Force painting on first update, if not painted
-
- //Center point of clock
- int x1,y1;
-
- //Array of points for triangular icon at 12:00
- int xPoints[]=new int[3], yPoints[]=new int[3];
-
- //Class to hold time, with method to return (double)(hours + minutes/60)
- hms cur_time;
-
- //The clock's seconds, minutes, and hours hands.
- sweepHand sweep;
- hmHand minuteHand,
- hourHand;
-
- //The last parameters used to draw the hands.
- double lastHour;
- int lastMinute,lastSecond;
-
-
- //Offscreen image and device context, for buffered output.
- Image offScrImage;
- Graphics offScrGC;
-
- // Use to test background image, if any.
- MediaTracker tracker;
-
-
- int minDimension; // Ensure a round clock if applet is not square.
- int originX; // Upper left corner of a square enclosing the clock
- int originY; // with respect to applet area.
-
- double tzDifference=0;
-
-
- //Users' parameters - self-explanatory?
- public String[][] getParameterInfo()
- {
- String[][] info = {
- {"bgImageURL", "string", "URL of background image, if any <null>"},
- {"logoString", "string", "Name to display on watch face <JAVEX>"},
- {"logoImageURL","string", "URL of logo image to display on watch face <null>"},
- {"timezone", "real", "Timezone difference from GMT (decimal hours,+ West/- East)<0>"},
- };
- return info;
- }
-
- //Applet name, author and info lines
- public String getAppletInfo()
- {
- return "JAVEX 1.03 - analog clock applet by Bill Giel, 2 Mar 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( "TIMEZONE" );
- if( paramString != null )
- tzDifference = Double.valueOf(paramString).doubleValue();
-
- logoString = getParameter( "LOGOSTRING");
- if( logoString == null )
- logoString=AText;
- 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(tzDifference);
- 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);
-
-
-
- offScrImage = createImage(width,height);
- offScrGC = offScrImage.getGraphics();
- }
-
- public void start()
- {
- if(clockThread == null){
- clockThread = new Thread(this);
- clockThread.start();
- }
- }
-
- public void stop()
- {
- if(null != clockThread){
- clockThread.stop();
- clockThread=null;
- }
- }
-
- private void drawHands(Graphics g)
- {
-
- double angle;
- int i,j;
- int x,y;
-
- angle=MINSEC * lastSecond;
- sweep.draw(AFacecolor, angle, g);
-
- if(cur_time.getMinutes() != lastMinute){
- minuteHand.draw(AFacecolor,MINSEC*lastMinute,g);
- if(cur_time.get_hours() != lastHour)
- hourHand.draw(AFacecolor,HOUR*lastHour,g);
- }
-
- g.setColor(ATextcolor);
- 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<i+2;j++){
- x=(int)(x1+Math.sin(HOUR*j)*size(35));
- y=(int)(y1-Math.cos(HOUR*j)*size(35));
- g.fillOval(x-size(3),y-size(3),size(6),size(6));
- }
-
- //Set the font and get font info...
- g.setFont(AFont);
- FontMetrics fm=g.getFontMetrics();
-
- //Paint our logo...
- g.drawString(logoString,x1-fm.stringWidth(logoString)/2,y1-size(12));
-
- //Get the day of the month...
- String day=Integer.toString(cur_time.getDate(),10);
-
- //Paint it...
- g.drawString( day,
- originX + minDimension-size(14)-fm.stringWidth(day),
- y1+size(5));
-
- //and put a box around it.
- g.drawRect( originX + minDimension-size(14)-fm.stringWidth(day)-size(2),
- y1-size(5)-size(2),
- fm.stringWidth(day)+size(4),
- size(10)+size(4));
-
- if(images[LOGO] != null){
- x = originX + (minDimension-images[LOGO].getWidth(this))/2;
- y = y1 + (minDimension/2 - size(22) - images[LOGO].getHeight(this))/2;
- if(x > 0 && y > 0)
- offScrGC.drawImage(images[LOGO], x, y, this);
- }
-
- lastHour=cur_time.get_hours();
- hourHand.draw(AHourcolor,HOUR*lastHour,g);
-
- lastMinute=cur_time.getMinutes();
- minuteHand.draw(AMinutecolor,MINSEC*lastMinute,g);
-
- g.setColor(AMinutecolor);
- g.fillOval(x1-size(4),y1-size(4),size(8),size(8));
- g.setColor(ASweepcolor);
- g.fillOval(x1-size(3),y1-size(3),size(6),size(6));
-
- lastSecond=cur_time.getSeconds();
- angle=MINSEC*lastSecond;
- sweep.draw(ASweepcolor, angle,g);
-
- g.setColor(ATrimcolor);
- 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();
- while(null != clockThread){
- cur_time=new hms(tzDifference);
- repaint();
- try{
- Thread.sleep(1000);
- } catch (InterruptedException e) {}
- }
- System.exit(0);
- }
-
- public void paint(Graphics g)
- {
- int i,x0,y0,x2,y2;
-
- if(images[BACKGROUND] == null){
- offScrGC.setColor(ABackgroundcolor);
- offScrGC.fillRect(0,0,width,height);
- }
- else
- offScrGC.drawImage(images[BACKGROUND], 0, 0, this);
-
- offScrGC.setColor(ACasecolor);
-
- //Shrink one pixel so we don't clip anything off...
- offScrGC.fillOval( originX+1,
- originY+1,
- minDimension-2,
- minDimension-2);
-
- offScrGC.setColor(AFacecolor);
- offScrGC.fillOval( originX + size(5),
- originY + size(5),
- minDimension - size(10),
- minDimension - size(10));
-
- offScrGC.setColor(ATrimcolor);
- 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(ATextcolor);
-
- //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);
- }
- }
- }
-