/** * SunSphereOptionDialog displays help text and provides for configuration.<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> * * Based, vaguely, on the YesNoDialog class in Java in a Nutshell, 2nd edition, * but that was a long time ago. * * @author <a href="mailto:minow@pobox.com">Martin Minow</a> * @version 1.0 * This class is Java 1.1 compatible. * Set tabs every 8 characters. */package org.minow.applets.sunsphere;import java.util.*;import java.awt.*;import java.awt.event.*;/** * SunSphereOptionDialog implements a very simple dialog.  */class SunSphereOptionDialog extends Dialog	implements		TextListener{    protected Button		okButton	= new Button(" OK ");    protected Button		cancelButton    = new Button(" Cancel ");    protected TextArea		textArea;    protected Checkbox		systemDateCheckbox;    protected Checkbox		longitudeOnlyCheckbox;    protected Checkbox		showPerformanceCheckbox;    protected Checkbox		logErrorsCheckbox;    /* */    protected DateEntryPanel	dateEntryPanel;    protected TimeEntryPanel	timeEntryPanel;    protected DayTimeEntryPanel	dateUpdateQuantum;    protected TimeEntryPanel	dateUpdateInterval;    protected LatitudeField	latitudeField;    protected LongitudeField	longitudeField;    protected TextField		latitudeButtonField;    protected TextField		latitudeSpinField;    protected TextField		longitudeButtonField;    protected TextField		longitudeSpinField;    protected TextField		spinIntervalField;        protected Label		spinWarning;        protected GridBagLayout	gridbag		= new GridBagLayout();    protected SunSphere		sunSphereApplet;    private int			dialogRow	= 0;    private static final String	spinWarningText	= "Non-zero latitude spins are slow";    private static final String noWarningText	= " ";    private boolean		isSpinWarning	= false;    public SunSphereOptionDialog(	    SunSphere	    applet	)    {	super(getFrame(applet), "Configure " + SunSphere.appletName, false);	setResizable(true);	setBackground(Color.white);	/* Force a common background color	*/	setForeground(Color.black);	/* Force a common foreground color	*/	sunSphereApplet	    = applet;	textArea = new TextArea(		SunSphere.appletName + " " + SunSphere.version + "\n"		+ SunSphere.copyright + "\n"		+ SunSphere.aboutSunSphere	    );	textArea.setEditable(false);	textArea.setFont(new Font("Serif", Font.PLAIN, 12));	textArea.setBackground(Color.white);	textArea.setForeground(Color.black);	systemDateCheckbox	= new Checkbox(			"Use System Date",			applet.isSystemDateUsed()		    );	longitudeOnlyCheckbox	= new Checkbox(			"Grabbing hand changes longitude and latitude",			applet.isLatitudeGrabOK()		    );	showPerformanceCheckbox	= new Checkbox(			"Show graphics performance",			applet.isGraphicsPerformance()		    );	logErrorsCheckbox	= new Checkbox(			"Enable error logging",			applet.isLogErrors()		    );	Date date		= applet.getDate();	dateEntryPanel		= new DateEntryPanel(date);	timeEntryPanel		= new TimeEntryPanel(date);	dateUpdateQuantum	= new DayTimeEntryPanel(			applet.getDateUpdateQuantum()		    );	dateUpdateInterval	= new TimeEntryPanel(			applet.getDateUpdateInterval()		    );	/* */	latitudeField		= new LatitudeField(applet.getLatitude());	latitudeButtonField	= makeTextField(applet.getLatitudeDelta());	latitudeSpinField	= makeTextField(applet.getLatitudeSpin());	latitudeSpinField.addTextListener(this);	/* */	longitudeField		= new LongitudeField(applet.getLongitude());		longitudeButtonField	= makeTextField(applet.getLongitudeDelta());	longitudeSpinField	= makeTextField(applet.getLongitudeSpin());	spinIntervalField	= new TextField(String.valueOf(applet.getSpinInterval()), 7);	/* */	setLayout(gridbag);	GridBagConstraints c	= new GridBagConstraints();	c.gridx			= 0;	c.gridy			= dialogRow++;	c.gridwidth		= 2;	c.gridheight		= 1;	c.fill			= GridBagConstraints.BOTH;	c.anchor		= GridBagConstraints.CENTER;	c.weightx		= 1.0;	c.weighty		= 1.0;	c.insets		= new Insets(2, 2, 2, 2);	gridbag.setConstraints(textArea, c);	add(textArea);	/* */	spinWarning		= new Label(noWarningText);	spinWarning.setForeground(Color.red);	c.gridy			= dialogRow++;	c.fill			= GridBagConstraints.HORIZONTAL;	c.anchor		= GridBagConstraints.WEST;	c.weighty		= 0.0;	gridbag.setConstraints(spinWarning, c);	add(spinWarning);	/* */	addBorder("Date");	addDialogField("Date",				dateEntryPanel);	addDialogField("Time (UTC)",			timeEntryPanel);	addDialogField("Date Update Quantum",		dateUpdateQuantum);	addDialogField("Date Update Interval",		dateUpdateInterval);	addDialogField("",				systemDateCheckbox);	/* */	addBorder("Location");	addDialogField("Latitude (Degrees)",		latitudeField);	addDialogField("Button Increment (Degrees)",	latitudeButtonField);	addDialogField("Longitude (Degrees)",		longitudeField);	addDialogField("Button Increment (Degrees)",	longitudeButtonField);	/* */	addBorder("Spinning and Configuration");	addDialogField("Spin Interval (Msec.)",		spinIntervalField);	addDialogField("Latitude Spin Increment (Degrees)", latitudeSpinField);	addDialogField("Longitude Spin Increment (Degrees)", longitudeSpinField);	addDialogField("",				longitudeOnlyCheckbox);	addDialogField("",				showPerformanceCheckbox);	addDialogField("",				logErrorsCheckbox);	/* */	/*	 * Create the OK and Cancel buttons in a separate panel so they don't	 * stretch across the entire bottom of the window.	 */	Panel buttonPanel = new Panel();	buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 8, 4));	buttonPanel.add(cancelButton);	buttonPanel.add(new Label("        "));	buttonPanel.add(okButton);	c.gridy			= dialogRow++;	c.fill			= GridBagConstraints.HORIZONTAL;	c.weighty		= 0.0;	gridbag.setConstraints(buttonPanel, c);	add(buttonPanel);	pack();	textValueChanged(new TextEvent(latitudeSpinField, TextEvent.TEXT_VALUE_CHANGED));	setVisible(true);    }    private void addBorder(    	    String		labelText    	)    {	GridBagConstraints c	= new GridBagConstraints();	c.gridx		= 0;	c.gridy		= dialogRow++;	c.gridwidth	= 2;	c.gridheight	= 1;	c.fill		= GridBagConstraints.HORIZONTAL;	c.anchor	= GridBagConstraints.WEST;	c.weightx	= 1.0;	c.insets	= new Insets(0, 0, 0, 0);	OptionBorder border	= new OptionBorder(labelText);	gridbag.setConstraints(border, c);	add(border);    }    private TextField makeTextField(    	    int			initialValue    	)    {    	TextField result	= new TextField(Integer.toString(initialValue), 3);    	return (result);    }    private TextField makeTextField(    	    double		initialValue    	)    {    	TextField result	= new TextField(Utility.format(initialValue), 7);    	return (result);    }    private void addDialogField(	    String		labelString,	    Component		valueField	)    {	GridBagConstraints c	= new GridBagConstraints();	c.gridx		= 0;	c.gridy		= dialogRow++;	c.gridwidth	= 1;	c.gridheight	= 1;	c.fill		= GridBagConstraints.HORIZONTAL;	c.anchor	= GridBagConstraints.EAST;	c.weightx	= 1.0;	c.insets	= new Insets(0, 0, 0, 0);	Label label	= new Label(labelString, Label.RIGHT);	gridbag.setConstraints(label, c);	add(label);	c.fill		= GridBagConstraints.NONE;	c.weightx	= 0.0;	c.gridx		= 1;	c.insets	= new Insets(0, 4, 0, 0);	c.anchor	= GridBagConstraints.WEST;	gridbag.setConstraints(valueField, c);	add(valueField);    }    public void textValueChanged(    	    TextEvent		event    	)    {    	if (event.getSource() == latitudeSpinField) {	    try {		double latitudeSpin	= doubleTextValue(latitudeSpinField, 0.0, 0.0);		boolean wantWarning	= (latitudeSpin != 0.0);		if (wantWarning != isSpinWarning) {		    spinWarning.setText((wantWarning) ? spinWarningText : noWarningText);		    isSpinWarning	= wantWarning;		}	    }	    catch (NumberFormatException e) {	    }	}	    }    public boolean handleEvent(	    Event		event	)    {	if (event.target == okButton	 && event.id == Event.ACTION_EVENT) {	    if (extractValuesAndUpdateApplet()) {		dispose();		return (true);	    }	}	else if (event.target == cancelButton	 && event.id == Event.ACTION_EVENT) {	    dispose();	    return (true);	}	else if (event.id == Event.WINDOW_DESTROY) {	    dispose();	    return (true);	}	else {	    // Someone else's problem	}	return (false);    }    private boolean extractValuesAndUpdateApplet()    {	boolean result		= true;	try {	    double		latitude;	    double		latitudeButton;	    double		latitudeSpin;	    double		longitude;	    double		longitudeButton;	    double		longitudeSpin;	    int			spinInterval;	    latitude		= latitudeField.getValue();	    latitudeButton	= doubleTextValue(latitudeButtonField,	0.0, 0.0);	    latitudeSpin	= doubleTextValue(latitudeSpinField,	0.0, 0.0);	    longitude		= longitudeField.getValue();	    longitudeButton	= doubleTextValue(longitudeButtonField,	0.0, 0.0);	    longitudeSpin	= doubleTextValue(longitudeSpinField,	0.0, 0.0);	    spinInterval	= intTextValue(spinIntervalField, 1, Integer.MAX_VALUE);	    /*	     * Although the setXXX methods can throw NumberFormatExceptions,	     * the data should be in range by now.	     */	    sunSphereApplet.setSystemDateUsed(systemDateCheckbox.getState());	    if (sunSphereApplet.isSystemDateUsed() == false) {		Date date	= dateEntryPanel.getDate();		long time	= timeEntryPanel.getTime();		sunSphereApplet.setDate(new Date(date.getTime() + time));		sunSphereApplet.setDateUpdateInterval(				dateUpdateInterval.getTime()			    );		sunSphereApplet.setDateUpdateQuantum(				dateUpdateQuantum.getTime()			    );	    }	    sunSphereApplet.setLatitudeDelta(latitudeButton);	    sunSphereApplet.setLatitudeSpin(latitudeSpin);	    sunSphereApplet.setLongitudeDelta(longitudeButton);	    sunSphereApplet.setLongitudeSpin(longitudeSpin);	    sunSphereApplet.setSpinInterval(spinInterval);	    sunSphereApplet.setLatitudeGrabOK(longitudeOnlyCheckbox.getState());	    sunSphereApplet.setGrapicsPerformance(showPerformanceCheckbox.getState());	    sunSphereApplet.setLogErrors(logErrorsCheckbox.getState());	    sunSphereApplet.setObserverLocation(latitude, longitude);	}	catch (NumberFormatException e) {	    result	    = false;	}	return (result);    }    private double doubleTextValue(	    TextField	    textField,	    double	    minValue,	    double	    maxValue	)    {	double		    result;		try {	    result = new Double(textField.getText()).doubleValue();	    if (maxValue > minValue	     && (result < minValue || result >= maxValue)) {		throw new NumberFormatException("Outside valid range");	    }	}	catch (NumberFormatException e) {	    String range    = "";	    if (maxValue > minValue) {		range = " in the range "		    + Utility.format(minValue)		    + " <= value < "		    + Utility.format(maxValue);	    }	    AlertDialog d = new AlertDialog(		    this,		    "Incorrect Entry",		    "Please enter a number" + range + ". \""		    + textField.getText() + "\" is invalid: " + e,		    true /* Modal */		);	    throw (e);	}	return (result);    }    private int intTextValue(    	    TextField		textField    	)    {    	return (intTextValue(textField, 0, 0));    }    private int intTextValue(	    TextField	    textField,	    int		    minimum,	    int		    maximum	)    {	int		    result;		try {	    result = Integer.parseInt(textField.getText());	    if (maximum > minimum	     && (result < minimum || result > maximum)) {		throw new NumberFormatException("Invalid value");	    }	}	catch (NumberFormatException e) {	    AlertDialog d = new AlertDialog(		    this,		    "Invalid Entry \"" + textField.getText() + "\"",		    "Please enter a valid positive integer\ngreater than zero."		    + " \"" + textField.getText() + "\" is invalid: ",		    true /* Modal */		);	    throw (e);	}	return (result);    }    public static Frame getFrame(	    Component	    component	)    {	while (component != null && !(component instanceof Frame)) {	    component = component.getParent();	}	return ((Frame) component);    }}   