/** * DegreeEntryPanel provides a data entry panel for Latitude and Longitude. * It is always expressed by a subclass (LatitudeField or LongitudeField)<p> * * Copyright &copy; 1998-89 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> * * Based on DateGUI.java in Mastering JavaBeans. * @see <a href="http://www.sybase.com">Sybase</a>, click on *  "Catalog>Updates>Mastering JavaBeans". * @author <a href="mailto:minow@pobox.com">Martin Minow</a> * @version 1.0a0 * Set tabs every 8 characters. */package org.minow.applets.sunsphere;import java.beans.*;import java.util.*;import java.awt.*;import java.awt.event.*;import java.text.*;public class DegreeEntryPanel extends Panel{    /*     * These are the property events we distribute.     */    public static final String DEGREE_CHANGE	= "degree";    private static final char	degreeSign	= '\u00B0';	// 'd';    private static final char	minuteSign	= '\'';		// 'm';    private static final char	secondSign	= '"';		// 's';    protected IntegerField	degreeField;    protected IntegerField	minuteField;    protected IntegerField	secondField;    protected Checkbox		northEastCheck;        private double		value;        public DegreeEntryPanel()    {	this(0.0, 360, "East");    }    public DegreeEntryPanel(    	    double		value,    	    int			maximum,	    String		checkBoxLabel	)    {        /*         * Since maximum will be 90 or 360, a clever user can         * conceivably set the value just beyond the true maximum.         * Note also that longitude > 180 is valid, as is longitude < 0         */	degreeField	= new IntegerField(3, 0, 0, maximum);	minuteField	= new IntegerField(2, 0, 0, 59);	secondField	= new IntegerField(2, 0, 0, 59);	northEastCheck	= new Checkbox(checkBoxLabel);	/*	 * Construct the display Panel.	 */	GridBagLayout gridbag	= new GridBagLayout();	setLayout(gridbag);	GridBagConstraints c	= new GridBagConstraints();	c.gridy			= 0;	c.weightx		= 0.0;	c.anchor		= GridBagConstraints.WEST;	c.fill			= GridBagConstraints.NONE;	addField(c, degreeField);	addField(c, new Label("\u00B0"));	/* Degree mark  */	addField(c, minuteField);	addField(c, new Label("'"));	addField(c, secondField);	addField(c, new Label("\""));	addField(c, northEastCheck);			setValue(Utility.MOD(value + 180.0, 360.0) - 180.0);    }    private void addField(	    GridBagConstraints	c,	    Component			component	)    {	add(component);	((GridBagLayout) getLayout()).setConstraints(component, c);    }    /*     * Accessor functions.     */    public synchronized void setValue(	    double		value	)    {    	this.value		= value;	int seconds	    	= (int) Math.round(value * 3600.0);	boolean isPositive	= (seconds >= 0.0);	seconds		   	 = Math.abs(seconds);	int degrees	   	= seconds / 3600;	seconds			-= (degrees * 3600);	int minutes		= seconds / 60;	seconds			-= (minutes * 60);	degreeField.setText(String.valueOf(degrees));	minuteField.setText(String.valueOf(minutes));	secondField.setText(String.valueOf(seconds));	northEastCheck.setState(isPositive);    }    public synchronized double getValue()    {	try {	    long seconds	= Integer.parseInt(secondField.getText());	    long minutes	= Integer.parseInt(minuteField.getText());	    long degrees	= Integer.parseInt(degreeField.getText());	    value		=	    	((double) degrees)	    	+ (((double) minutes) / 60.0)	    	+ (((double) seconds) / 3600.0);	}	catch (NumberFormatException e) { }	return (value);    }}