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.
18 package org.altusmetrum.altosuilib_11;
21 import java.awt.event.*;
26 import java.lang.Math;
28 import java.net.URLConnection;
29 import org.altusmetrum.altoslib_11.*;
31 class AltosUIMapPos extends Box implements ActionListener {
32 AltosUIMapPreload preload;
41 /* ActionListener interface */
42 public void actionPerformed(ActionEvent e) {
46 public void set_value(double new_value) {
53 new_value = -new_value;
55 d = Math.floor(new_value);
56 deg.setText(String.format("%3.0f", d));
57 m = (new_value - d) * 60.0;
58 min.setText(String.format("%7.4f", m));
59 hemi.setSelectedIndex(h);
62 public double get_value() throws ParseException {
63 int h = hemi.getSelectedIndex();
64 String d_t = deg.getText();
65 String m_t = min.getText();
68 d = AltosParse.parse_double_locale(d_t);
69 } catch (ParseException pe) {
70 JOptionPane.showMessageDialog(owner,
71 String.format("Invalid degrees \"%s\"",
74 JOptionPane.ERROR_MESSAGE);
81 m = AltosParse.parse_double_locale(m_t);
82 } catch (ParseException pe) {
83 JOptionPane.showMessageDialog(owner,
84 String.format("Invalid minutes \"%s\"",
87 JOptionPane.ERROR_MESSAGE);
96 public AltosUIMapPos(AltosUIFrame in_owner,
97 AltosUIMapPreload preload,
100 double default_value) {
101 super(BoxLayout.X_AXIS);
103 this.preload = preload;
104 label = new JLabel(label_value);
105 hemi = new JComboBox<String>(hemi_names);
106 hemi.setEditable(false);
107 deg = new JTextField(5);
108 deg.addActionListener(this);
109 deg.setMinimumSize(deg.getPreferredSize());
110 deg.setHorizontalAlignment(JTextField.RIGHT);
111 deg_label = new JLabel("°");
112 min = new JTextField(9);
113 min.addActionListener(this);
114 min.setMinimumSize(min.getPreferredSize());
115 min_label = new JLabel("'");
116 set_value(default_value);
118 add(Box.createRigidArea(new Dimension(5, 0)));
120 add(Box.createRigidArea(new Dimension(5, 0)));
122 add(Box.createRigidArea(new Dimension(5, 0)));
124 add(Box.createRigidArea(new Dimension(5, 0)));
126 add(Box.createRigidArea(new Dimension(5, 0)));
131 public class AltosUIMapPreload extends AltosUIFrame implements ActionListener, ItemListener, AltosLaunchSiteListener, AltosMapLoaderListener, AltosUnitsListener, AltosFontListener {
140 JLabel site_list_label;
141 JComboBox<AltosLaunchSite> site_list;
143 JToggleButton load_button;
144 JButton close_button;
146 JCheckBox[] maptypes = new JCheckBox[AltosMap.maptype_terrain - AltosMap.maptype_hybrid + 1];
148 JComboBox<Integer> min_zoom;
149 JComboBox<Integer> max_zoom;
151 JComboBox<Double> radius;
154 Integer[] zooms = { -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 };
156 Double[] radius_mi = { 1.0, 2.0, 5.0, 10.0, 20.0 };
157 Double radius_def_mi = 5.0;
158 Double[] radius_km = { 2.0, 5.0, 10.0, 20.0, 30.0 };
159 Double radius_def_km = 10.0;
161 AltosMapLoader loader;
163 static final String[] lat_hemi_names = { "N", "S" };
164 static final String[] lon_hemi_names = { "E", "W" };
166 double latitude, longitude;
168 long loader_notify_time;
170 /* AltosMapLoaderListener interfaces */
171 public void loader_start(final int max) {
172 loader_notify_time = System.currentTimeMillis();
174 SwingUtilities.invokeLater(new Runnable() {
176 pbar.setMaximum(max);
183 public void loader_notify(final int cur, final int max, final String name) {
184 long now = System.currentTimeMillis();
186 if (now - loader_notify_time < 100)
189 loader_notify_time = now;
191 SwingUtilities.invokeLater(new Runnable() {
194 pbar.setString(name);
199 public void loader_done(int max) {
201 SwingUtilities.invokeLater(new Runnable() {
205 load_button.setSelected(false);
210 public void debug(String format, Object ... arguments) {
211 if (AltosSerial.debug)
212 System.out.printf(format, arguments);
216 private int all_types() {
218 for (int t = AltosMap.maptype_hybrid; t <= AltosMap.maptype_terrain; t++)
219 if (maptypes[t].isSelected())
220 all_types |= (1 << t);
224 void center_map(double latitude, double longitude) {
225 map.map.centre(new AltosLatLon(latitude, longitude));
227 map.add_mark(latitude, longitude, AltosLib.ao_flight_boost);
232 center_map(lat.get_value(), lon.get_value());
233 } catch (ParseException pe) {
237 public void itemStateChanged(ItemEvent e) {
238 int state = e.getStateChange();
240 if (state == ItemEvent.SELECTED) {
241 Object o = e.getItem();
242 if (o instanceof AltosLaunchSite) {
243 AltosLaunchSite site = (AltosLaunchSite) o;
244 lat.set_value(site.latitude);
245 lon.set_value(site.longitude);
246 center_map(site.latitude, site.longitude);
251 public void actionPerformed(ActionEvent e) {
252 String cmd = e.getActionCommand();
254 if (cmd.equals("close")) {
260 if (cmd.equals("load")) {
261 if (loader == null) {
263 latitude = lat.get_value();
264 longitude = lon.get_value();
265 int min_z = (Integer) min_zoom.getSelectedItem();
266 int max_z = (Integer) max_zoom.getSelectedItem();
269 Double r = (Double) radius.getSelectedItem();
271 if (AltosPreferences.imperial_units())
272 r = AltosConvert.miles_to_meters(r);
276 center_map(latitude, longitude);
278 loader = new AltosMapLoader(this,
283 } catch (ParseException pe) {
284 load_button.setSelected(false);
290 public void notify_launch_sites(final java.util.List<AltosLaunchSite> sites) {
291 SwingUtilities.invokeLater(new Runnable() {
294 for (AltosLaunchSite site : sites) {
295 site_list.insertItemAt(site, i);
302 private void set_radius_values() {
303 radius_label.setText(String.format("Map Radius (%s)",
304 AltosPreferences.imperial_units() ? "mi" : "km"));
308 if (AltosPreferences.imperial_units())
313 radius.removeAllItems();
314 for (Double r : radii) {
317 radius.setSelectedItem(radii[2]);
318 radius.setMaximumRowCount(radii.length);
321 public void units_changed(boolean imperial_units) {
322 map.units_changed(imperial_units);
326 public void font_size_changed(int font_size) {
327 map.font_size_changed(font_size);
330 public AltosUIMapPreload(AltosUIFrame in_owner) {
333 Container pane = getContentPane();
334 GridBagConstraints c = new GridBagConstraints();
335 Insets i = new Insets(4,4,4,4);
337 setTitle("AltOS Load Maps");
339 pane.setLayout(new GridBagLayout());
341 addWindowListener(new WindowAdapter() {
343 public void windowClosing(WindowEvent e) {
344 AltosUIPreferences.unregister_font_listener(AltosUIMapPreload.this);
345 AltosPreferences.unregister_units_listener(AltosUIMapPreload.this);
350 AltosPreferences.register_units_listener(this);
351 AltosUIPreferences.register_font_listener(this);
353 map = new AltosUIMap();
355 c.fill = GridBagConstraints.BOTH;
356 c.anchor = GridBagConstraints.CENTER;
364 c.anchor = GridBagConstraints.CENTER;
368 pbar = new JProgressBar();
373 pbar.setStringPainted(true);
375 c.fill = GridBagConstraints.HORIZONTAL;
376 c.anchor = GridBagConstraints.CENTER;
387 site_list_label = new JLabel ("Known Launch Sites:");
389 c.fill = GridBagConstraints.NONE;
390 c.anchor = GridBagConstraints.CENTER;
399 pane.add(site_list_label, c);
401 site_list = new JComboBox<AltosLaunchSite>(new AltosLaunchSite[] { new AltosLaunchSite("Site List", 0, 0) });
402 site_list.addItemListener(this);
404 new AltosLaunchSites(this);
406 c.fill = GridBagConstraints.HORIZONTAL;
407 c.anchor = GridBagConstraints.CENTER;
416 pane.add(site_list, c);
418 lat = new AltosUIMapPos(owner, this,
422 c.fill = GridBagConstraints.NONE;
423 c.anchor = GridBagConstraints.CENTER;
431 c.anchor = GridBagConstraints.CENTER;
435 lon = new AltosUIMapPos(owner, this,
440 c.fill = GridBagConstraints.NONE;
441 c.anchor = GridBagConstraints.CENTER;
449 c.anchor = GridBagConstraints.CENTER;
453 load_button = new JToggleButton("Load Map");
454 load_button.addActionListener(this);
455 load_button.setActionCommand("load");
457 c.fill = GridBagConstraints.NONE;
458 c.anchor = GridBagConstraints.CENTER;
466 c.anchor = GridBagConstraints.CENTER;
468 pane.add(load_button, c);
470 close_button = new JButton("Close");
471 close_button.addActionListener(this);
472 close_button.setActionCommand("close");
474 c.fill = GridBagConstraints.NONE;
475 c.anchor = GridBagConstraints.CENTER;
483 c.anchor = GridBagConstraints.CENTER;
485 pane.add(close_button, c);
487 JLabel types_label = new JLabel("Map Types");
491 pane.add(types_label, c);
495 for (int type = AltosMap.maptype_hybrid; type <= AltosMap.maptype_terrain; type++) {
496 maptypes[type] = new JCheckBox(AltosMap.maptype_labels[type],
497 type == AltosMap.maptype_hybrid);
498 c.gridx = 2 + (type >> 1);
499 c.fill = GridBagConstraints.HORIZONTAL;
500 c.gridy = (type & 1) + 3;
501 pane.add(maptypes[type], c);
504 JLabel min_zoom_label = new JLabel("Minimum Zoom");
507 pane.add(min_zoom_label, c);
509 min_zoom = new JComboBox<Integer>(zooms);
510 min_zoom.setSelectedItem(zooms[10]);
511 min_zoom.setEditable(false);
514 pane.add(min_zoom, c);
516 JLabel max_zoom_label = new JLabel("Maximum Zoom");
519 pane.add(max_zoom_label, c);
521 max_zoom = new JComboBox<Integer>(zooms);
522 max_zoom.setSelectedItem(zooms[14]);
523 max_zoom.setEditable(false);
526 pane.add(max_zoom, c);
528 radius_label = new JLabel();
532 pane.add(radius_label, c);
534 radius = new JComboBox<Double>();
535 radius.setEditable(true);
543 setLocationRelativeTo(owner);