2 * Copyright © 2011 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 import java.awt.event.*;
26 import java.lang.Math;
28 import java.net.URLConnection;
30 class AltosMapPos extends Box {
39 public void set_value(double new_value) {
46 new_value = -new_value;
48 d = Math.floor(new_value);
49 deg.setText(String.format("%3.0f", d));
50 m = (new_value - d) * 60.0;
51 min.setText(String.format("%7.4f", m));
52 hemi.setSelectedIndex(h);
55 public double get_value() throws NumberFormatException {
56 int h = hemi.getSelectedIndex();
57 String d_t = deg.getText();
58 String m_t = min.getText();
61 d = Double.parseDouble(d_t);
62 } catch (NumberFormatException ne) {
63 JOptionPane.showMessageDialog(owner,
64 String.format("Invalid degrees \"%s\"",
67 JOptionPane.ERROR_MESSAGE);
74 m = Double.parseDouble(m_t);
75 } catch (NumberFormatException ne) {
76 JOptionPane.showMessageDialog(owner,
77 String.format("Invalid minutes \"%s\"",
80 JOptionPane.ERROR_MESSAGE);
89 public AltosMapPos(AltosUI in_owner,
92 double default_value) {
93 super(BoxLayout.X_AXIS);
95 label = new JLabel(label_value);
96 hemi = new JComboBox(hemi_names);
97 hemi.setEditable(false);
98 deg = new JTextField(5);
99 deg.setMinimumSize(deg.getPreferredSize());
100 deg.setHorizontalAlignment(JTextField.RIGHT);
101 deg_label = new JLabel("°");
102 min = new JTextField(9);
103 min.setMinimumSize(min.getPreferredSize());
104 min_label = new JLabel("'");
105 set_value(default_value);
107 add(Box.createRigidArea(new Dimension(5, 0)));
109 add(Box.createRigidArea(new Dimension(5, 0)));
111 add(Box.createRigidArea(new Dimension(5, 0)));
113 add(Box.createRigidArea(new Dimension(5, 0)));
115 add(Box.createRigidArea(new Dimension(5, 0)));
125 public String toString() {
129 public AltosSite(String in_name, double in_latitude, double in_longitude) {
131 latitude = in_latitude;
132 longitude = in_longitude;
135 public AltosSite(String line) throws ParseException {
136 String[] elements = line.split(":");
138 if (elements.length < 3)
139 throw new ParseException(String.format("Invalid site line %s", line), 0);
144 latitude = Double.parseDouble(elements[1]);
145 longitude = Double.parseDouble(elements[2]);
146 } catch (NumberFormatException ne) {
147 throw new ParseException(String.format("Invalid site line %s", line), 0);
152 class AltosSites extends Thread {
153 AltosSiteMapPreload preload;
155 LinkedList<AltosSite> sites;
157 void notify_complete() {
158 SwingUtilities.invokeLater(new Runnable() {
165 void add(AltosSite site) {
169 void add(String line) {
171 add(new AltosSite(line));
172 } catch (ParseException pe) {
178 URLConnection uc = url.openConnection();
179 //int length = uc.getContentLength();
181 InputStreamReader in_stream = new InputStreamReader(uc.getInputStream(), Altos.unicode_set);
182 BufferedReader in = new BufferedReader(in_stream);
185 String line = in.readLine();
190 } catch (IOException e) {
196 public AltosSites(AltosSiteMapPreload in_preload) {
197 sites = new LinkedList<AltosSite>();
198 preload = in_preload;
200 url = new URL(Altos.launch_sites_url);
201 } catch (java.net.MalformedURLException e) {
208 public class AltosSiteMapPreload extends AltosDialog implements ActionListener, ItemListener {
215 final static int radius = 4;
216 final static int width = (radius * 2 + 1);
217 final static int height = (radius * 2 + 1);
222 JLabel site_list_label;
225 JToggleButton load_button;
227 JButton close_button;
229 static final String[] lat_hemi_names = { "N", "S" };
230 static final String[] lon_hemi_names = { "E", "W" };
232 class updatePbar implements Runnable {
236 public updatePbar(int x, int y, String in_s) {
237 n = (x + radius) + (y + radius) * width + 1;
244 if (n < width * height) {
250 load_button.setSelected(false);
256 class bgLoad extends Thread {
260 public bgLoad(AltosSiteMap in_map) {
265 for (int y = -map.radius; y <= map.radius; y++) {
266 for (int x = -map.radius; x <= map.radius; x++) {
268 pngfile = map.initMap(new Point(x,y));
269 SwingUtilities.invokeLater(new updatePbar(x, y, pngfile));
275 public void set_sites() {
277 for (AltosSite site : sites.sites) {
278 site_list.insertItemAt(site, i);
283 public void itemStateChanged(ItemEvent e) {
284 int state = e.getStateChange();
286 if (state == ItemEvent.SELECTED) {
287 Object o = e.getItem();
288 if (o instanceof AltosSite) {
289 AltosSite site = (AltosSite) o;
290 lat.set_value(site.latitude);
291 lon.set_value(site.longitude);
296 public void actionPerformed(ActionEvent e) {
297 String cmd = e.getActionCommand();
299 if (cmd.equals("close"))
302 if (cmd.equals("load")) {
305 final double latitude = lat.get_value();
306 final double longitude = lon.get_value();
307 map.setBaseLocation(latitude,longitude);
308 map.draw_circle(latitude,longitude);
310 bgLoad thread = new bgLoad(map);
312 } catch (NumberFormatException ne) {
313 load_button.setSelected(false);
319 public AltosSiteMapPreload(AltosUI in_owner) {
322 Container pane = getContentPane();
323 GridBagConstraints c = new GridBagConstraints();
324 Insets i = new Insets(4,4,4,4);
326 pane.setLayout(new GridBagLayout());
328 map = new AltosSiteMap(4);
330 c.fill = GridBagConstraints.BOTH;
331 c.anchor = GridBagConstraints.CENTER;
339 c.anchor = GridBagConstraints.CENTER;
343 pbar = new JProgressBar();
345 pbar.setMaximum(width * height);
348 pbar.setStringPainted(true);
350 c.fill = GridBagConstraints.HORIZONTAL;
351 c.anchor = GridBagConstraints.CENTER;
362 site_list_label = new JLabel ("Known Launch Sites:");
364 c.fill = GridBagConstraints.NONE;
365 c.anchor = GridBagConstraints.CENTER;
374 pane.add(site_list_label, c);
376 site_list = new JComboBox(new String[] { "Site List" });
377 site_list.addItemListener(this);
379 sites = new AltosSites(this);
381 c.fill = GridBagConstraints.HORIZONTAL;
382 c.anchor = GridBagConstraints.CENTER;
391 pane.add(site_list, c);
393 lat = new AltosMapPos(owner,
397 c.fill = GridBagConstraints.NONE;
398 c.anchor = GridBagConstraints.CENTER;
406 c.anchor = GridBagConstraints.CENTER;
410 lon = new AltosMapPos(owner,
415 c.fill = GridBagConstraints.NONE;
416 c.anchor = GridBagConstraints.CENTER;
424 c.anchor = GridBagConstraints.CENTER;
428 load_button = new JToggleButton("Load Map");
429 load_button.addActionListener(this);
430 load_button.setActionCommand("load");
432 c.fill = GridBagConstraints.NONE;
433 c.anchor = GridBagConstraints.CENTER;
441 c.anchor = GridBagConstraints.CENTER;
443 pane.add(load_button, c);
445 close_button = new JButton("Close");
446 close_button.addActionListener(this);
447 close_button.setActionCommand("close");
449 c.fill = GridBagConstraints.NONE;
450 c.anchor = GridBagConstraints.CENTER;
458 c.anchor = GridBagConstraints.CENTER;
460 pane.add(close_button, c);
463 setLocationRelativeTo(owner);