/* locationSelector.java Paul Carlisle This is a control panel which allows the user to enter their latitude and longitude. Entry consists of selecting individual digits in the appropriate range (0-90 for latitude, 0-180 for longitude) and selecting the modifier field (N/S for latitude, E/W for longitude. Both measures are stored internally in radian measure. South latitude are negative, north are positive. Eastern longitudes are negative, western are positive. */ import java.awt.*; import java.lang.*; public class locationSelector extends Panel { private int Width; private int Height; private double Latitude; private double Longitude; private Choice latHi; private Choice latLow; private Choice latHemi; private Choice longHi; private Choice longMid; private Choice longLow; private Choice longHemi; private GridBagLayout mainLayout; private GridBagConstraints mainConstraints; public locationSelector(int width, int height, double latitude, double longitude, Font inputFont, Font labelFont) { setFont(inputFont); // Various choice lists for the digits and modifiers. latHi = new Choice(); latLow = new Choice(); latHemi = new Choice(); longHi = new Choice(); longMid = new Choice(); longLow = new Choice(); longHemi = new Choice(); latHi.setBackground(Color.white); latLow.setBackground(Color.white); latHemi.setBackground(Color.white); longHi.setBackground(Color.white); longMid.setBackground(Color.white); longLow.setBackground(Color.white); longHemi.setBackground(Color.white); latHemi.addItem("N"); latHemi.addItem("S"); longHemi.addItem("E"); longHemi.addItem("W"); // Add the digits common to all elements. for (int i = 0; i <= 8; i++) { latLow.addItem(new String(Integer.toString(i)) ); latHi.addItem(new String(Integer.toString(i)) ); longLow.addItem(new String(Integer.toString(i)) ); longMid.addItem(new String(Integer.toString(i)) ); } // Fill in the rest manually. latHi.addItem("9"); latLow.addItem("9"); longLow.addItem("9"); longMid.addItem("9"); longHi.addItem("0"); longHi.addItem("1"); mainLayout = new GridBagLayout(); mainConstraints = new GridBagConstraints(); setLayout(mainLayout); mainConstraints.gridy = 0; mainConstraints.fill = GridBagConstraints.BOTH; mainConstraints.anchor = GridBagConstraints.CENTER; Panel pad = new Panel(); mainConstraints.gridx = 0; mainLayout.setConstraints(pad, mainConstraints); add(pad); /* Latitude selector */ mainConstraints.gridx = 1; mainLayout.setConstraints(latHi, mainConstraints); add(latHi); mainConstraints.gridx = 2; mainLayout.setConstraints(latLow, mainConstraints); add(latLow); Label degree = new Label(" ", Label.CENTER); degree.setFont(labelFont); mainConstraints.gridx = 3; mainLayout.setConstraints(degree, mainConstraints); add(degree); mainConstraints.gridx = 4; mainLayout.setConstraints(latHemi, mainConstraints); add(latHemi); /* Spacer */ Label space = new Label(" "); mainConstraints.gridx = 5; mainLayout.setConstraints(space, mainConstraints); add(space); /* Longitude selector */ mainConstraints.gridx = 6; mainLayout.setConstraints(longHi, mainConstraints); add(longHi); mainConstraints.gridx = 7; mainLayout.setConstraints(longMid, mainConstraints); add(longMid); mainConstraints.gridx = 8; mainLayout.setConstraints(longLow, mainConstraints); add(longLow); Label degree2 = new Label(" ", Label.CENTER); degree2.setFont(labelFont); mainConstraints.gridx = 9; mainLayout.setConstraints(degree2, mainConstraints); add(degree2); mainConstraints.gridx = 10; mainLayout.setConstraints(longHemi, mainConstraints); add(longHemi); } // Event handling. public boolean action(Event e, Object what) { // If the user changed a latitude digit... if ( (e.target == latHi) || (e.target == latLow) || (e.target == latHemi) ) { double temp = 10 * latHi.getSelectedIndex() + latLow.getSelectedIndex(); if (latHemi.getSelectedItem() == "S") temp = -temp; setLatitude(degreesToRadians(temp)); } else if ( (e.target == longHi) || (e.target == longMid) || (e.target == longLow) || (e.target == longHemi) ) { double temp = 100 * longHi.getSelectedIndex() + 10 * longMid.getSelectedIndex() + longLow.getSelectedIndex(); if (longHemi.getSelectedItem() == "E") temp = -temp; setLongitude(degreesToRadians(temp)); } // Consume all events. return false; } // Utility functions. private double degreesToRadians(double degrees) { return Math.PI * degrees / 180; } // Returns the latitude, in radians. public double getLatitude() { return Latitude; } // Returns the longitude, in radians. public double getLongitude() { return Longitude; } private double radiansToDegrees(double radians) { return 180 * radians / Math.PI; } // Sets the Latitude and display to the passed value. // The value is in radians; display is set in degrees. public void setLatitude(double latitude) { if (Math.abs(latitude) > Math.PI/2) { double temp = Math.PI/2; if (latitude < 0) temp = -temp; latitude = temp; } // We make a small adjustment here, to take care of an apparent // bug in Java's comparison routines. if (latitude < 0) latitude = latitude - (1e-7); else latitude = latitude + (1e-7); Latitude = latitude; double degrees = radiansToDegrees(Latitude); // Set the display. latHi.select((int)Math.abs(degrees) / 10); latLow.select((int)Math.abs(degrees) % 10); if (Latitude < 0) latHemi.select("S"); else latHemi.select("N"); } // Sets the longitude and display to the passed value. // The value is in radians; the display is set in degrees. public void setLongitude(double longitude) { if (Math.abs(longitude) > Math.PI) { double temp = Math.PI; if (longitude < 0) temp = -temp; longitude = temp; } Longitude = longitude; longitude = Math.abs(Longitude); double degrees = radiansToDegrees(longitude); longHi.select( (int)degrees / 100 ); longMid.select( ((int)degrees / 10) % 10); longLow.select( (int)degrees % 10); if (Longitude < 0) longHemi.select("E"); else longHemi.select("W"); } }