/** * SimpleSunApplet displays a world map showing the sunrise and sunset terminators.<p> * * Copyright &copy; 1996-98 Martin Minow. All Rights Reserved.<p> * World map copyright &copy; 1992-97 Apple Computer Inc. All Rights Reserved. * Used by permission.<p> * * Permission to use, copy, modify, and redistribute this software and its * documentation for personal, non-commercial use is hereby granted provided that * this copyright notice and appropriate documentation appears in all copies. This * software may not be distributed for fee or as part of commercial, "shareware," * and/or not-for-profit endevors including, but not limited to, CD-ROM collections, * online databases, and subscription services without specific license.<p> * * @author <a href="mailto:minow@merrymeet.com">Martin Minow</a> * @version 1.1 (from SunClock 1.1) * 1996.09.21 * 1997.05.29 - Added GMT time string, removed Astro class. * 1997.11.12 - Use SunrisePixels.java to consruct and manage the image. * Set tabs every 4 characters. */import java.applet.Applet;import java.applet.AudioClip;import java.awt.*;import java.util.*;import java.net.*;public class SimpleSunApplet	extends java.applet.Applet	implements java.lang.Runnable{	public static final String copyright	=							"Copyright 1996-98 Martin Minow. All Rights Reserved";	public static final String author		= "mailto:minow@merrymeet.com";	public static final String name    	= "SimpleSunApplet";	public static final String version		= "1.0.1";	public static final String imageName	= "EarthImage270.gif";	public static final String chimeName	= "DecClockTower.au";	public static final String parameterInfo[][] = {			{ "bgcolor", "color",	"The background color, #RRGGBB (in hex)"	},		};	protected SimpleTimeBarCanvas	timeBarCanvas;	protected SunriseCanvas		sunriseCanvas;	protected AudioClip			hourBell;	protected int					currentHour		= new Date().getHours();	protected Font					displayFont		= new Font("Helvetica", Font.PLAIN, 10);	protected Thread				runner;	protected boolean				test			= false;	protected long					testDate		= new Date().getTime();	/**	 * Applet initialization.	 */	public void init()	{		showStatus(copyright + ", version " + version);		try {			new Thread().sleep(100L);	/* Force the copyright to the display	*/		} catch (Exception e) {}		showStatus("");		this.setFont(displayFont);		sunriseCanvas			= new SunriseCanvas(getImage(getCodeBase(), imageName));		timeBarCanvas			= new SimpleTimeBarCanvas(sunriseCanvas);		getBackgroundColor();		/* */		/* setBackground(new Color(0xCCCCFF));		*/		Panel panel				= new Panel();		GridBagLayout gridbag	= new GridBagLayout();		GridBagConstraints c	= new GridBagConstraints();		c.gridx					= 0;		c.gridy					= 0;		c.gridwidth				= 1;		c.gridheight			= 1;		c.fill					= GridBagConstraints.HORIZONTAL;		c.anchor				= GridBagConstraints.SOUTH;		c.insets				= new Insets(0, 0, 0, 0);		gridbag.setConstraints(sunriseCanvas, c);		panel.add(sunriseCanvas);		c.gridy					= 1;		c.anchor				= GridBagConstraints.NORTH;		gridbag.setConstraints(timeBarCanvas, c);		panel.add(timeBarCanvas);		this.setLayout(new BorderLayout());		this.add("Center", panel);		Label gmtNote			= new Label(			    "Time values are referenced to GMT, not local time",			    Label.CENTER			);		validate();	}	/**	 * Paint the applet - essentially, just the background with a frame around it.	 */	public void paint(Graphics g)	{		g.setColor(getBackground());		g.fillRect(0, 0, size().width - 1, size().height - 1);		g.setColor(Color.black);		g.drawRect(0, 0, size().width - 1, size().height - 1);	}	/**	 * The applet is initialized: start it by creating the asynchronous thread.	 */	public void start()	{		if (runner == null) {			runner = new Thread(this);			runner.start();		}		if (hourBell == null) {			try {				hourBell = getAudioClip(getCodeBase(), chimeName);				/* hourBell.play(); */	/* Debug */			}			catch (Exception e) {				hourBell = null;			}		}	}	/**	 * The applet thread is running.	 */	public void run()	{		showStatus("");			/* Clean out the status line	*/		while (runner != null) {			Date		now;			if (test) {				/*				 * Self test. Increment the date by one day + 15 minutes.				 */				now				= new Date(testDate);				testDate		+= (24 * 60 * 60 * 1000) + (15 * 60 * 1000);			}			else {				now				= new Date();				int thisHour	= now.getHours();				if (hourBell != null && thisHour != currentHour) {					currentHour = thisHour;					hourBell.play();				}			}			sunriseCanvas.setDate(now);			timeBarCanvas.repaint();			showStatus(now.toGMTString());			long sleepTime;			if (test) {				sleepTime = 500;			}			else {				/*				 * Sleep until the start of the next minute. Get the current				 * time (in milliseconds), round it up to the next minute,				 * and sleep for the difference. To avoid choking slow browsers,				 * make sure that we sleep at least 30 seconds.				 */				sleepTime = 60000 - (System.currentTimeMillis() % 60000);				while (sleepTime < 30000) {					sleepTime += 60000;				}			}			try {				runner.sleep(sleepTime);			}			catch (InterruptedException e) {}		}	}	/**	 * The applet context wants to stop us. Just delete the thread.	 */	public void stop()	{		runner = null;		hourBell = null;	}	/**	 * We're all done for now. Make sure that the thread is deleted.	 */	public void destroy()	{		stop();	}	/**	 * For debugging, return some information about our applet.	 */	public String getAppletInfo()	{		String result = getClass().getName()			+ ", " + copyright			+ ", " + author;		return (result);	}	public String[][] getParameterInfo()	{		return (parameterInfo);	}	public void getBackgroundColor()	{		String		colorName	= getParameter("bgcolor");		if (colorName != null) {			if (colorName.charAt(0) == '#') {				colorName = colorName.substring(1);			}			try {				int	color = Integer.parseInt(colorName, 16);				setBackground(new Color(color));			}			catch (NumberFormatException e) {}		}	}}