/** * SimpleTimeBarCanvas displays the time for the world map.<p> * * Copyright &copy; 1996-98 Martin Minow. All Rights Reserved.<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 * Set tabs every 4 characters. */// package Classes;import java.util.*;import java.awt.*;/** * This must be installed centered, north, directly under SunriseCanvas. */public class SimpleTimeBarCanvas extends Canvas{	protected SunriseCanvas		sunriseCanvas;	protected Date					instant = new Date();	protected double				theTimeAtGMT;	/**	 * Initialize the panel.	 */	public SimpleTimeBarCanvas(			SunriseCanvas			sunriseCanvas		)	{		this.sunriseCanvas	= sunriseCanvas;	}	public Dimension preferredSize()	{		/*		 * The timebar is slightly wider than the world map it illustrates.		 */		FontMetrics		fontMetrics		= getFontMetrics(getFont());		Dimension		d				= new Dimension(					sunriseCanvas.size().width + fontMetrics.charWidth('0') * 10,					fontMetrics.getHeight()				);		return (d);	}	public Dimension getPreferredSize()	{		return (preferredSize());	}	/**	 * Draw the display.	 * @param g		the current graphics context.	 * Note: this presumes that the TimeBarCanvas is directly centered above or below	 * the sunImageCanvas (the layout method will decide).	 */	public synchronized void paint(			Graphics			g		)	{		/*		 * Delay display until the sunImageCanvas is initialized.		 */		if (sunriseCanvas.bounds() != null) {			FontMetrics fontMetrics		= g.getFontMetrics();			/*			 * We need the width of the sunriseImage and it's left origin			 * translated into the timeBar coordinates.			 */			instant							= sunriseCanvas.getDate();			theTimeAtGMT					=				((double) (instant.getTime() % 86400000L)) / 3600000.0;			Rectangle	worldMapBounds		= sunriseCanvas.bounds();			int			worldMapWidth		= worldMapBounds.width;			int			stepSize			= worldMapWidth / 6;			int			origin				= worldMapBounds.x - this.bounds().x;			if (fontMetrics.stringWidth(" 00:00") < stepSize) {			   origin -= (fontMetrics.stringWidth("00:00") / 2);				/*				 * The <= in the for loop is intentional: we need to traverse				 * the loop an extra time to avoid a fencepost error.				 */				for (int xPixel = 0; xPixel <= worldMapWidth; xPixel += stepSize) {					double	timeAtXPixel	= xPixelToTime(xPixel);					g.drawString(						timeString(timeAtXPixel),						xPixel + origin,						fontMetrics.getAscent()					);				}			}		}	}	/**	 * Convert a pixel offset in the range 0 .. worldMapRect.width to the time at this	 * location (using the current time at this.instant and the observer's timezone).	 * @param xPixel	The pixel offset to convert.	 * @return the time (hour.fraction) at this pixel offset.	 */	private double xPixelToTime(			int					xPixel		)	{		try {			int			worldMapWidth		= sunriseCanvas.bounds().width;			/*			 * Convert xPixel to a time value referenced to GMT. Note that			 * xPixel == 0 -> -0.5, xPixel == worldMapRect.width / 2 -> 0.0;			 */			double xFraction	= ((double) (xPixel - worldMapWidth / 2))								/ ((double) worldMapWidth);			double now			= theTimeAtGMT + (xFraction * 24.0);			while (now >= 24.0)				now -= 24.0;			while (now < 0.0)				now += 24.0;			return (now);		}		catch (Exception e) {	/* Handle no image present yet case	*/			return (0.0);		}	}	/*	 * Convert a time (in the range 0.0 .. 24.0) to a time string.	 */	public static String timeString(			double				value		)	{		int		hour		= (int) Math.floor(value);		value				= (value - (double) hour) * 60.0;		int		minute		= (int) (value + 0.5);		if (minute >= 60) {			++hour;			minute -= 60;		}		if (hour >= 24) {			hour -= 24;		}		StringBuffer	result = new StringBuffer();		if (hour < 10) {			result.append('0');		}		result.append(new Integer(hour).toString());		result.append(':');		if (minute < 10) {			result.append('0');		}		result.append(new Integer(minute).toString());		return (result.toString());	}}