From 8c20030ea4eb8e068e1ba88e01d07dfbc27bd7db Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 9 Jul 2011 18:41:15 -0700 Subject: altosui: Start adding support for scanning radio for available devices This is untested. Signed-off-by: Keith Packard --- altosui/AltosScanUI.java | 365 +++++++++++++++++++++++++++++++++++++++++++++++ altosui/AltosUI.java | 12 ++ altosui/Makefile.am | 1 + 3 files changed, 378 insertions(+) create mode 100644 altosui/AltosScanUI.java diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java new file mode 100644 index 00000000..e55f317c --- /dev/null +++ b/altosui/AltosScanUI.java @@ -0,0 +1,365 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import javax.swing.event.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.*; + +class AltosScanResult { + String callsign; + int serial; + int flight; + int channel; + int telemetry; + boolean interrupted = false; + + public String toString() { + return String.format("%-9.9s %4d %4d %2d %2d", + callsign, serial, flight, channel, telemetry); + } + + public String toShortString() { + return String.format("%s %d %d %d %d", + callsign, serial, flight, channel, telemetry); + } + + public AltosScanResult(String in_callsign, int in_serial, + int in_flight, int in_channel, int in_telemetry) { + callsign = in_callsign; + serial = in_serial; + flight = in_flight; + channel = in_channel; + telemetry = in_telemetry; + } + + public boolean equals(AltosScanResult other) { + return (callsign.equals(other.callsign) && + serial == other.serial && + flight == other.flight && + channel == other.channel && + telemetry == other.telemetry); + } +} + +class AltosScanResults extends LinkedList implements ListModel { + + LinkedList listeners = new LinkedList(); + + public boolean add(AltosScanResult r) { + for (AltosScanResult old : this) + if (old.equals(r)) + return true; + + super.add(r); + ListDataEvent de = new ListDataEvent(this, + ListDataEvent.INTERVAL_ADDED, + this.size() - 2, this.size() - 1); + for (ListDataListener l : listeners) + l.contentsChanged(de); + return true; + } + + public void addListDataListener(ListDataListener l) { + listeners.add(l); + } + + public void removeListDataListener(ListDataListener l) { + listeners.remove(l); + } + + public AltosScanResult getElementAt(int i) { + return this.get(i); + } + + public int getSize() { + return this.size(); + } +} + +public class AltosScanUI + extends JDialog + implements ActionListener +{ + JFrame owner; + AltosDevice device; + AltosTelemetryReader reader; + private JList list; + private JLabel channel_label; + private JLabel monitor_label; + private JButton ok_button; + javax.swing.Timer timer; + AltosScanResults results = new AltosScanResults(); + + static final int[] monitors = { Altos.ao_telemetry_split_len, + Altos.ao_telemetry_legacy_len }; + int monitor; + int channel; + + final static int timeout = 5 * 1000; + TelemetryHandler handler; + Thread thread; + + void scan_exception(Exception e) { + if (e instanceof FileNotFoundException) { + JOptionPane.showMessageDialog(owner, + String.format("Cannot open device \"%s\"", + device.toShortString()), + "Cannot open target device", + JOptionPane.ERROR_MESSAGE); + } else if (e instanceof AltosSerialInUseException) { + JOptionPane.showMessageDialog(owner, + String.format("Device \"%s\" already in use", + device.toShortString()), + "Device in use", + JOptionPane.ERROR_MESSAGE); + } else if (e instanceof IOException) { + IOException ee = (IOException) e; + JOptionPane.showMessageDialog(owner, + device.toShortString(), + ee.getLocalizedMessage(), + JOptionPane.ERROR_MESSAGE); + } else { + JOptionPane.showMessageDialog(owner, + String.format("Connection to \"%s\" failed", + device.toShortString()), + "Connection Failed", + JOptionPane.ERROR_MESSAGE); + } + close(); + } + + class TelemetryHandler implements Runnable { + + public void run() { + + boolean interrupted = false; + + try { + for (;;) { + try { + AltosRecord record = reader.read(); + if (record == null) + break; + if ((record.seen & AltosRecord.seen_flight) != 0) { + AltosScanResult result = new AltosScanResult(record.callsign, + record.serial, + record.flight, + channel, + monitor); + results.add(result); + } + } catch (ParseException pp) { + System.out.printf("Parse error: %d \"%s\"\n", pp.getErrorOffset(), pp.getMessage()); + } catch (AltosCRCException ce) { + } + } + } catch (InterruptedException ee) { + interrupted = true; + } catch (IOException ie) { + } finally { + reader.close(interrupted); + } + } + } + + void set_channel() { + reader.serial.set_channel(channel); + } + + void set_monitor() { + reader.serial.set_telemetry(monitors[monitor]); + } + + void next() { + ++channel; + if (channel == 10) { + channel = 0; + ++monitor; + if (monitor == monitors.length) + monitor = 0; + set_monitor(); + } + set_channel(); + } + + + void close() { + if (thread != null && thread.isAlive()) { + thread.interrupt(); + try { + thread.join(); + } catch (InterruptedException ie) {} + } + thread = null; + if (timer != null) + timer.stop(); + setVisible(false); + dispose(); + } + + void tick_timer() { + next(); + } + + public void actionPerformed(ActionEvent e) { + String cmd = e.getActionCommand(); + + if (cmd.equals("close")) { + close(); + } + } + + /* A window listener to catch closing events and tell the config code */ + class ConfigListener extends WindowAdapter { + AltosScanUI ui; + + public ConfigListener(AltosScanUI this_ui) { + ui = this_ui; + } + + public void windowClosing(WindowEvent e) { + ui.actionPerformed(new ActionEvent(e.getSource(), + ActionEvent.ACTION_PERFORMED, + "close")); + } + } + + private boolean open() { + device = AltosDeviceDialog.show(owner, Altos.product_any); + if (device != null) { + try { + reader = new AltosTelemetryReader(device); + set_channel(); + set_monitor(); + handler = new TelemetryHandler(); + thread = new Thread(handler); + thread.start(); + return true; + } catch (Exception e) { + scan_exception(e); + } + } + return false; + } + + public AltosScanUI(JFrame in_owner) { + + owner = in_owner; + + if (!open()) + return; + + Container pane = getContentPane(); + GridBagConstraints c = new GridBagConstraints(); + Insets i = new Insets(4,4,4,4); + + timer = new javax.swing.Timer(timeout, this); + timer.setActionCommand("tick"); + timer.restart(); + + owner = in_owner; + + pane.setLayout(new GridBagLayout()); + + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 1; + + c.gridx = 0; + c.gridy = 0; + c.gridwidth = 3; + c.anchor = GridBagConstraints.CENTER; + + list = new JList(results) { + //Subclass JList to workaround bug 4832765, which can cause the + //scroll pane to not let the user easily scroll up to the beginning + //of the list. An alternative would be to set the unitIncrement + //of the JScrollBar to a fixed value. You wouldn't get the nice + //aligned scrolling, but it should work. + public int getScrollableUnitIncrement(Rectangle visibleRect, + int orientation, + int direction) { + int row; + if (orientation == SwingConstants.VERTICAL && + direction < 0 && (row = getFirstVisibleIndex()) != -1) { + Rectangle r = getCellBounds(row, row); + if ((r.y == visibleRect.y) && (row != 0)) { + Point loc = r.getLocation(); + loc.y--; + int prevIndex = locationToIndex(loc); + Rectangle prevR = getCellBounds(prevIndex, prevIndex); + + if (prevR == null || prevR.y >= r.y) { + return 0; + } + return prevR.height; + } + } + return super.getScrollableUnitIncrement( + visibleRect, orientation, direction); + } + }; + + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + list.setLayoutOrientation(JList.HORIZONTAL_WRAP); + list.setVisibleRowCount(-1); + +// list.addMouseListener(new MouseAdapter() { +// public void mouseClicked(MouseEvent e) { +// if (e.getClickCount() == 2) { +// select_button.doClick(); //emulate button click +// } +// } +// }); + JScrollPane listScroller = new JScrollPane(list); + listScroller.setPreferredSize(new Dimension(400, 80)); + listScroller.setAlignmentX(LEFT_ALIGNMENT); + + //Create a container so that we can add a title around + //the scroll pane. Can't add a title directly to the + //scroll pane because its background would be white. + //Lay out the label and scroll pane from top to bottom. + JPanel listPane = new JPanel(); + listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS)); + + JLabel label = new JLabel("Select Device"); + label.setLabelFor(list); + listPane.add(label); + listPane.add(Box.createRigidArea(new Dimension(0,5))); + listPane.add(listScroller); + listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); + + pane.add(listPane, c); + + pack(); + setLocationRelativeTo(owner); + + addWindowListener(new ConfigListener(this)); + } +} \ No newline at end of file diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 7bb4ba12..6a24d8a9 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -172,6 +172,14 @@ public class AltosUI extends JFrame { } }); + + b = addButton(0, 2, "Scan Channels"); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ScanChannels(); + } + }); + setTitle("AltOS"); pane.doLayout(); @@ -226,6 +234,10 @@ public class AltosUI extends JFrame { new AltosIgniteUI(AltosUI.this); } + void ScanChannels() { + new AltosScanUI(AltosUI.this); + } + /* * Replay a flight from telemetry data */ diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 6e64acab..0a3ed0b1 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -83,6 +83,7 @@ altosui_JAVA = \ AltosReplayReader.java \ AltosRomconfig.java \ AltosRomconfigUI.java \ + AltosScanUI.java \ AltosSerial.java \ AltosSerialInUseException.java \ AltosSerialMonitor.java \ -- cgit v1.2.3 From f32a55ac9a3ebbde2b41782f22491e72258fe05a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 9 Jul 2011 19:00:12 -0700 Subject: altosui: Pop up monitor window from scan dialog Signed-off-by: Keith Packard --- altosui/AltosScanUI.java | 120 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 97 insertions(+), 23 deletions(-) diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index e55f317c..01b01720 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -35,6 +35,7 @@ class AltosScanResult { int flight; int channel; int telemetry; + boolean interrupted = false; public String toString() { @@ -104,12 +105,14 @@ public class AltosScanUI extends JDialog implements ActionListener { - JFrame owner; + AltosUI owner; AltosDevice device; AltosTelemetryReader reader; private JList list; private JLabel channel_label; private JLabel monitor_label; + private JButton fake_button; + private JButton cancel_button; private JButton ok_button; javax.swing.Timer timer; AltosScanResults results = new AltosScanResults(); @@ -228,8 +231,26 @@ public class AltosScanUI public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); - if (cmd.equals("close")) { + if (cmd.equals("fake")) { + results.add(new AltosScanResult("N0CALL", 300, 1, 0, 1)); + } + + if (cmd.equals("cancel")) { + close(); + } + + if (cmd.equals("ok")) { close(); + AltosScanResult r = (AltosScanResult) (list.getSelectedValue()); + System.out.printf("Selected channel %d telemetry %d\n", + r.channel, r.telemetry); + if (device != null) { + if (reader != null) { + reader.set_telemetry(r.telemetry); + reader.set_channel(r.channel); + owner.telemetry_window(device); + } + } } } @@ -266,12 +287,12 @@ public class AltosScanUI return false; } - public AltosScanUI(JFrame in_owner) { + public AltosScanUI(AltosUI in_owner) { owner = in_owner; - if (!open()) - return; +// if (!open()) +// return; Container pane = getContentPane(); GridBagConstraints c = new GridBagConstraints(); @@ -285,17 +306,6 @@ public class AltosScanUI pane.setLayout(new GridBagLayout()); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 1; - - c.gridx = 0; - c.gridy = 0; - c.gridwidth = 3; - c.anchor = GridBagConstraints.CENTER; - list = new JList(results) { //Subclass JList to workaround bug 4832765, which can cause the //scroll pane to not let the user easily scroll up to the beginning @@ -330,13 +340,13 @@ public class AltosScanUI list.setLayoutOrientation(JList.HORIZONTAL_WRAP); list.setVisibleRowCount(-1); -// list.addMouseListener(new MouseAdapter() { -// public void mouseClicked(MouseEvent e) { -// if (e.getClickCount() == 2) { -// select_button.doClick(); //emulate button click -// } -// } -// }); + list.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + ok_button.doClick(); //emulate button click + } + } + }); JScrollPane listScroller = new JScrollPane(list); listScroller.setPreferredSize(new Dimension(400, 80)); listScroller.setAlignmentX(LEFT_ALIGNMENT); @@ -355,11 +365,75 @@ public class AltosScanUI listPane.add(listScroller); listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 1; + + c.gridx = 0; + c.gridy = 0; + c.gridwidth = 3; + c.anchor = GridBagConstraints.CENTER; + pane.add(listPane, c); + fake_button = new JButton("fake"); + fake_button.addActionListener(this); + fake_button.setActionCommand("fake"); + + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 1; + + c.gridx = 0; + c.gridy = 1; + c.gridwidth = 1; + c.anchor = GridBagConstraints.CENTER; + + pane.add(fake_button, c); + + cancel_button = new JButton("Cancel"); + cancel_button.addActionListener(this); + cancel_button.setActionCommand("cancel"); + + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 1; + + c.gridx = 1; + c.gridy = 1; + c.gridwidth = 1; + c.anchor = GridBagConstraints.CENTER; + + pane.add(cancel_button, c); + + ok_button = new JButton("OK"); + ok_button.addActionListener(this); + ok_button.setActionCommand("ok"); + + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 1; + + c.gridx = 2; + c.gridy = 1; + c.gridwidth = 1; + c.anchor = GridBagConstraints.CENTER; + + pane.add(ok_button, c); + pack(); setLocationRelativeTo(owner); addWindowListener(new ConfigListener(this)); + + setVisible(true); } } \ No newline at end of file -- cgit v1.2.3 From d4375bc737655546c2d40f49acdfc2e60ebfea5a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 14:19:14 -0700 Subject: altosui: Remove debugging printf from AltosLog Signed-off-by: Keith Packard --- altosui/AltosLog.java | 1 - 1 file changed, 1 deletion(-) diff --git a/altosui/AltosLog.java b/altosui/AltosLog.java index 855ee2b4..6157a656 100644 --- a/altosui/AltosLog.java +++ b/altosui/AltosLog.java @@ -88,7 +88,6 @@ class AltosLog implements Runnable { close_log_file(); serial = telem.serial; flight = telem.flight; - System.out.printf("Opening telem %d %d\n", serial, flight); open(telem); } previous = telem; -- cgit v1.2.3 From ebcba28b3c09925869b617880d2919e5d0e059f0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 14:19:41 -0700 Subject: altosui: Configuration telemetry record includes flight number Mark the reported altos record as including flight information. Signed-off-by: Keith Packard --- altosui/AltosTelemetryRecordConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altosui/AltosTelemetryRecordConfiguration.java b/altosui/AltosTelemetryRecordConfiguration.java index 98dc6ab9..b029d120 100644 --- a/altosui/AltosTelemetryRecordConfiguration.java +++ b/altosui/AltosTelemetryRecordConfiguration.java @@ -57,7 +57,7 @@ public class AltosTelemetryRecordConfiguration extends AltosTelemetryRecordRaw { next.callsign = callsign; next.firmware_version = version; - next.seen |= AltosRecord.seen_deploy; + next.seen |= AltosRecord.seen_deploy | AltosRecord.seen_flight; return next; } -- cgit v1.2.3 From 7ef786276b5d5c7d17c3fe4f36aa41db61a9742f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 14:23:08 -0700 Subject: altosui: Finish radio scanning UI Scans all channels and telemetry formats, presenting visible devices in a list. Entries from the list may be selected, in which case a monitor window pops up with the appropriate configuration. Signed-off-by: Keith Packard --- altosui/AltosScanUI.java | 183 ++++++++++++++++++++++++++--------------------- 1 file changed, 103 insertions(+), 80 deletions(-) diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 01b01720..d94ac3ae 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -35,12 +35,13 @@ class AltosScanResult { int flight; int channel; int telemetry; + static final String[] short_monitor_names = { "Standard", "Original" }; boolean interrupted = false; public String toString() { - return String.format("%-9.9s %4d %4d %2d %2d", - callsign, serial, flight, channel, telemetry); + return String.format("%-9.9s serial %-4d flight %-4d (channel %-2d telemetry %s)", + callsign, serial, flight, channel, short_monitor_names[telemetry]); } public String toShortString() { @@ -109,20 +110,18 @@ public class AltosScanUI AltosDevice device; AltosTelemetryReader reader; private JList list; - private JLabel channel_label; - private JLabel monitor_label; - private JButton fake_button; + private JLabel scanning_label; private JButton cancel_button; - private JButton ok_button; + private JButton monitor_button; javax.swing.Timer timer; AltosScanResults results = new AltosScanResults(); - static final int[] monitors = { Altos.ao_telemetry_split_len, - Altos.ao_telemetry_legacy_len }; + static final String[] monitor_names = { "Standard AltOS Telemetry", "Original TeleMetrum Telemetry" }; + static final int[] monitors = { 2, 1 }; int monitor; int channel; - final static int timeout = 5 * 1000; + final static int timeout = 1200; TelemetryHandler handler; Thread thread; @@ -166,17 +165,21 @@ public class AltosScanUI try { AltosRecord record = reader.read(); if (record == null) - break; + continue; if ((record.seen & AltosRecord.seen_flight) != 0) { - AltosScanResult result = new AltosScanResult(record.callsign, + final AltosScanResult result = new AltosScanResult(record.callsign, record.serial, record.flight, channel, monitor); - results.add(result); + Runnable r = new Runnable() { + public void run() { + results.add(result); + } + }; + SwingUtilities.invokeLater(r); } } catch (ParseException pp) { - System.out.printf("Parse error: %d \"%s\"\n", pp.getErrorOffset(), pp.getMessage()); } catch (AltosCRCException ce) { } } @@ -189,24 +192,29 @@ public class AltosScanUI } } - void set_channel() { - reader.serial.set_channel(channel); - } - - void set_monitor() { - reader.serial.set_telemetry(monitors[monitor]); + void set_label() { + scanning_label.setText(String.format("Scanning: channel %d %s", + channel, + monitor_names[monitor])); } void next() { + reader.serial.set_monitor(false); + try { + Thread.sleep(100); + } catch (InterruptedException ie){ + } ++channel; - if (channel == 10) { + if (channel > 9) { channel = 0; ++monitor; if (monitor == monitors.length) monitor = 0; - set_monitor(); + reader.serial.set_telemetry(monitors[monitor]); } - set_channel(); + reader.serial.set_channel(channel); + set_label(); + reader.serial.set_monitor(true); } @@ -231,24 +239,22 @@ public class AltosScanUI public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); - if (cmd.equals("fake")) { - results.add(new AltosScanResult("N0CALL", 300, 1, 0, 1)); - } - - if (cmd.equals("cancel")) { + if (cmd.equals("cancel")) close(); - } - if (cmd.equals("ok")) { + if (cmd.equals("tick")) + tick_timer(); + + if (cmd.equals("monitor")) { close(); AltosScanResult r = (AltosScanResult) (list.getSelectedValue()); - System.out.printf("Selected channel %d telemetry %d\n", - r.channel, r.telemetry); - if (device != null) { - if (reader != null) { - reader.set_telemetry(r.telemetry); - reader.set_channel(r.channel); - owner.telemetry_window(device); + if (r != null) { + if (device != null) { + if (reader != null) { + reader.set_telemetry(monitors[r.telemetry]); + reader.set_channel(r.channel); + owner.telemetry_window(device); + } } } } @@ -270,20 +276,37 @@ public class AltosScanUI } private boolean open() { - device = AltosDeviceDialog.show(owner, Altos.product_any); - if (device != null) { - try { - reader = new AltosTelemetryReader(device); - set_channel(); - set_monitor(); - handler = new TelemetryHandler(); - thread = new Thread(handler); - thread.start(); - return true; - } catch (Exception e) { - scan_exception(e); - } + device = AltosDeviceDialog.show(owner, Altos.product_basestation); + if (device == null) + return false; + try { + reader = new AltosTelemetryReader(device); + reader.serial.set_channel(channel); + reader.serial.set_telemetry(monitors[monitor]); + handler = new TelemetryHandler(); + thread = new Thread(handler); + thread.start(); + return true; + } catch (FileNotFoundException ee) { + JOptionPane.showMessageDialog(owner, + String.format("Cannot open device \"%s\"", + device.toShortString()), + "Cannot open target device", + JOptionPane.ERROR_MESSAGE); + } catch (AltosSerialInUseException si) { + JOptionPane.showMessageDialog(owner, + String.format("Device \"%s\" already in use", + device.toShortString()), + "Device in use", + JOptionPane.ERROR_MESSAGE); + } catch (IOException ee) { + JOptionPane.showMessageDialog(owner, + device.toShortString(), + "Unkonwn I/O error", + JOptionPane.ERROR_MESSAGE); } + if (reader != null) + reader.close(false); return false; } @@ -291,8 +314,8 @@ public class AltosScanUI owner = in_owner; -// if (!open()) -// return; + if (!open()) + return; Container pane = getContentPane(); GridBagConstraints c = new GridBagConstraints(); @@ -306,6 +329,23 @@ public class AltosScanUI pane.setLayout(new GridBagLayout()); + scanning_label = new JLabel("Scanning:"); + + set_label(); + + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 1; + + c.gridx = 0; + c.gridy = 0; + c.gridwidth = 2; + c.anchor = GridBagConstraints.CENTER; + + pane.add(scanning_label, c); + list = new JList(results) { //Subclass JList to workaround bug 4832765, which can cause the //scroll pane to not let the user easily scroll up to the beginning @@ -343,7 +383,7 @@ public class AltosScanUI list.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { - ok_button.doClick(); //emulate button click + monitor_button.doClick(); //emulate button click } } }); @@ -365,24 +405,7 @@ public class AltosScanUI listPane.add(listScroller); listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 1; - - c.gridx = 0; - c.gridy = 0; - c.gridwidth = 3; - c.anchor = GridBagConstraints.CENTER; - - pane.add(listPane, c); - - fake_button = new JButton("fake"); - fake_button.addActionListener(this); - fake_button.setActionCommand("fake"); - - c.fill = GridBagConstraints.NONE; + c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; c.insets = i; c.weightx = 1; @@ -390,10 +413,10 @@ public class AltosScanUI c.gridx = 0; c.gridy = 1; - c.gridwidth = 1; + c.gridwidth = 2; c.anchor = GridBagConstraints.CENTER; - pane.add(fake_button, c); + pane.add(listPane, c); cancel_button = new JButton("Cancel"); cancel_button.addActionListener(this); @@ -405,16 +428,16 @@ public class AltosScanUI c.weightx = 1; c.weighty = 1; - c.gridx = 1; - c.gridy = 1; + c.gridx = 0; + c.gridy = 2; c.gridwidth = 1; c.anchor = GridBagConstraints.CENTER; pane.add(cancel_button, c); - ok_button = new JButton("OK"); - ok_button.addActionListener(this); - ok_button.setActionCommand("ok"); + monitor_button = new JButton("Monitor"); + monitor_button.addActionListener(this); + monitor_button.setActionCommand("monitor"); c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.CENTER; @@ -422,12 +445,12 @@ public class AltosScanUI c.weightx = 1; c.weighty = 1; - c.gridx = 2; - c.gridy = 1; + c.gridx = 1; + c.gridy = 2; c.gridwidth = 1; c.anchor = GridBagConstraints.CENTER; - pane.add(ok_button, c); + pane.add(monitor_button, c); pack(); setLocationRelativeTo(owner); -- cgit v1.2.3 From 941b90a4905e34936d24a25ca90ac04eb6f5a792 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 17:38:00 -0700 Subject: altosui: Generalize and centralize telemetry constants, parse v0.8 telemetry Move telemetry constants to Altos class, adding functions to compute names and lengths. Generalize users of these values to use all of the known values. Add support for v0.8 TeleMetrum telemetry Signed-off-by: Keith Packard --- altosui/Altos.java | 34 +++++++++++++++++++++++++++++---- altosui/AltosFlightUI.java | 14 +++++++------- altosui/AltosPreferences.java | 2 +- altosui/AltosScanUI.java | 28 +++++++++++++-------------- altosui/AltosSerial.java | 10 ++-------- altosui/AltosTelemetryRecordLegacy.java | 20 ++++++++++++------- altosui/AltosTelemetryRecordRaw.java | 7 +++++-- 7 files changed, 72 insertions(+), 43 deletions(-) diff --git a/altosui/Altos.java b/altosui/Altos.java index 96263797..8d5916ad 100644 --- a/altosui/Altos.java +++ b/altosui/Altos.java @@ -70,11 +70,23 @@ public class Altos { /* Telemetry modes */ static final int ao_telemetry_off = 0; - static final int ao_telemetry_legacy = 1; - static final int ao_telemetry_split = 2; + static final int ao_telemetry_min = 1; + static final int ao_telemetry_standard = 1; + static final int ao_telemetry_0_9 = 2; + static final int ao_telemetry_0_8 = 3; + static final int ao_telemetry_max = 3; + + static final String[] ao_telemetry_name = { + "Off", "Standard Telemetry", "TeleMetrum v0.9", "TeleMetrum v0.8" + }; + + static final int ao_telemetry_standard_len = 32; + static final int ao_telemetry_0_9_len = 95; + static final int ao_telemetry_0_8_len = 94; - static final int ao_telemetry_split_len = 32; - static final int ao_telemetry_legacy_len = 95; + static final int[] ao_telemetry_len = { + 0, 32, 95, 94 + }; static HashMap string_to_state = new HashMap(); @@ -103,6 +115,20 @@ public class Altos { map_initialized = true; } + static int telemetry_len(int telemetry) { + if (telemetry <= ao_telemetry_max) + return ao_telemetry_len[telemetry]; + throw new IllegalArgumentException(String.format("Invalid telemetry %d", + telemetry)); + } + + static String telemetry_name(int telemetry) { + if (telemetry <= ao_telemetry_max) + return ao_telemetry_name[telemetry]; + throw new IllegalArgumentException(String.format("Invalid telemetry %d", + telemetry)); + } + static String[] state_to_string = { "startup", "idle", diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 9536c4bb..04bfc90d 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -156,14 +156,14 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay { // Telemetry format menu telemetries = new JComboBox(); - telemetries.addItem("Original TeleMetrum Telemetry"); - telemetries.addItem("Standard AltOS Telemetry"); - int telemetry = 1; - telemetry = AltosPreferences.telemetry(serial); - if (telemetry > Altos.ao_telemetry_split) - telemetry = Altos.ao_telemetry_split; + for (int i = 1; i <= Altos.ao_telemetry_max; i++) + telemetries.addItem(Altos.telemetry_name(i)); + int telemetry = AltosPreferences.telemetry(serial); + if (telemetry <= Altos.ao_telemetry_off || + telemetry > Altos.ao_telemetry_max) + telemetry = Altos.ao_telemetry_standard; telemetries.setSelectedIndex(telemetry - 1); - telemetries.setMaximumRowCount(2); + telemetries.setMaximumRowCount(Altos.ao_telemetry_max); telemetries.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int telemetry = telemetries.getSelectedIndex() + 1; diff --git a/altosui/AltosPreferences.java b/altosui/AltosPreferences.java index 5029aff6..c8dee743 100644 --- a/altosui/AltosPreferences.java +++ b/altosui/AltosPreferences.java @@ -216,7 +216,7 @@ class AltosPreferences { if (telemetries.containsKey(serial)) return telemetries.get(serial); int telemetry = preferences.getInt(String.format(telemetryPreferenceFormat, serial), - Altos.ao_telemetry_split); + Altos.ao_telemetry_standard); telemetries.put(serial, telemetry); return telemetry; } diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index d94ac3ae..54be4f52 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -35,13 +35,12 @@ class AltosScanResult { int flight; int channel; int telemetry; - static final String[] short_monitor_names = { "Standard", "Original" }; boolean interrupted = false; public String toString() { - return String.format("%-9.9s serial %-4d flight %-4d (channel %-2d telemetry %s)", - callsign, serial, flight, channel, short_monitor_names[telemetry]); + return String.format("%-9.9s serial %-4d flight %-4d (channel %-2d %s)", + callsign, serial, flight, channel, Altos.telemetry_name(telemetry)); } public String toShortString() { @@ -116,9 +115,7 @@ public class AltosScanUI javax.swing.Timer timer; AltosScanResults results = new AltosScanResults(); - static final String[] monitor_names = { "Standard AltOS Telemetry", "Original TeleMetrum Telemetry" }; - static final int[] monitors = { 2, 1 }; - int monitor; + int telemetry; int channel; final static int timeout = 1200; @@ -171,7 +168,7 @@ public class AltosScanUI record.serial, record.flight, channel, - monitor); + telemetry); Runnable r = new Runnable() { public void run() { results.add(result); @@ -195,7 +192,7 @@ public class AltosScanUI void set_label() { scanning_label.setText(String.format("Scanning: channel %d %s", channel, - monitor_names[monitor])); + Altos.telemetry_name(telemetry))); } void next() { @@ -207,10 +204,10 @@ public class AltosScanUI ++channel; if (channel > 9) { channel = 0; - ++monitor; - if (monitor == monitors.length) - monitor = 0; - reader.serial.set_telemetry(monitors[monitor]); + ++telemetry; + if (telemetry > Altos.ao_telemetry_max) + telemetry = Altos.ao_telemetry_min; + reader.serial.set_telemetry(telemetry); } reader.serial.set_channel(channel); set_label(); @@ -251,7 +248,7 @@ public class AltosScanUI if (r != null) { if (device != null) { if (reader != null) { - reader.set_telemetry(monitors[r.telemetry]); + reader.set_telemetry(r.telemetry); reader.set_channel(r.channel); owner.telemetry_window(device); } @@ -282,7 +279,7 @@ public class AltosScanUI try { reader = new AltosTelemetryReader(device); reader.serial.set_channel(channel); - reader.serial.set_telemetry(monitors[monitor]); + reader.serial.set_telemetry(telemetry); handler = new TelemetryHandler(); thread = new Thread(handler); thread.start(); @@ -329,6 +326,9 @@ public class AltosScanUI pane.setLayout(new GridBagLayout()); + channel = 0; + telemetry = Altos.ao_telemetry_min; + scanning_label = new JLabel("Scanning:"); set_label(); diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java index 3666cb41..2e8ce870 100644 --- a/altosui/AltosSerial.java +++ b/altosui/AltosSerial.java @@ -326,13 +326,7 @@ public class AltosSerial implements Runnable { } private int telemetry_len() { - switch (telemetry) { - case 1: - default: - return Altos.ao_telemetry_legacy_len; - case 2: - return Altos.ao_telemetry_split_len; - } + return Altos.telemetry_len(telemetry); } public void set_channel(int in_channel) { @@ -404,7 +398,7 @@ public class AltosSerial implements Runnable { line = ""; monitor_mode = false; frame = null; - telemetry = Altos.ao_telemetry_split; + telemetry = Altos.ao_telemetry_standard; monitors = new LinkedList> (); reply_queue = new LinkedBlockingQueue (); open(); diff --git a/altosui/AltosTelemetryRecordLegacy.java b/altosui/AltosTelemetryRecordLegacy.java index e3751ee7..756f3ec9 100644 --- a/altosui/AltosTelemetryRecordLegacy.java +++ b/altosui/AltosTelemetryRecordLegacy.java @@ -385,24 +385,25 @@ public class AltosTelemetryRecordLegacy extends AltosRecord implements AltosTele */ int[] bytes; + int adjust; private int int8(int i) { - return Altos.int8(bytes, i + 1); + return Altos.int8(bytes, i + 1 + adjust); } private int uint8(int i) { - return Altos.uint8(bytes, i + 1); + return Altos.uint8(bytes, i + 1 + adjust); } private int int16(int i) { - return Altos.int16(bytes, i + 1); + return Altos.int16(bytes, i + 1 + adjust); } private int uint16(int i) { - return Altos.uint16(bytes, i + 1); + return Altos.uint16(bytes, i + 1 + adjust); } private int uint32(int i) { - return Altos.uint32(bytes, i + 1); + return Altos.uint32(bytes, i + 1 + adjust); } private String string(int i, int l) { - return Altos.string(bytes, i + 1, l); + return Altos.string(bytes, i + 1 + adjust, l); } static final int AO_GPS_NUM_SAT_MASK = (0xf << 0); @@ -428,8 +429,13 @@ public class AltosTelemetryRecordLegacy extends AltosRecord implements AltosTele } } version = 4; - callsign = string(62, 8); + adjust = 0; serial = uint16(0); + + if (bytes.length == Altos.ao_telemetry_0_8_len + 4) + adjust = -1; + + callsign = string(62, 8); flight = uint16(2); rssi = in_rssi; status = in_status; diff --git a/altosui/AltosTelemetryRecordRaw.java b/altosui/AltosTelemetryRecordRaw.java index e6c4cfc8..4b34f017 100644 --- a/altosui/AltosTelemetryRecordRaw.java +++ b/altosui/AltosTelemetryRecordRaw.java @@ -72,7 +72,7 @@ public class AltosTelemetryRecordRaw implements AltosTelemetryRecord { /* length, data ..., rssi, status, checksum -- 4 bytes extra */ switch (bytes.length) { - case Altos.ao_telemetry_split_len + 4: + case Altos.ao_telemetry_standard_len + 4: int type = Altos.uint8(bytes, 4 + 1); switch (type) { case packet_type_TM_sensor: @@ -94,7 +94,10 @@ public class AltosTelemetryRecordRaw implements AltosTelemetryRecord { break; } break; - case Altos.ao_telemetry_legacy_len + 4: + case Altos.ao_telemetry_0_9_len + 4: + r = new AltosTelemetryRecordLegacy(bytes, rssi, status); + break; + case Altos.ao_telemetry_0_8_len + 4: r = new AltosTelemetryRecordLegacy(bytes, rssi, status); break; default: -- cgit v1.2.3 From e905042879147dd86241bf2dcc7437e5a6eb7578 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 20:43:57 -0700 Subject: altosui: Initialize channel and telemetry before use in ScanUI Otherwise we try to use telemetry format 0, which means 'no telemetry'. Signed-off-by: Keith Packard --- altosui/AltosScanUI.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 54be4f52..bc1638ed 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -311,6 +311,9 @@ public class AltosScanUI owner = in_owner; + channel = 0; + telemetry = Altos.ao_telemetry_min; + if (!open()) return; @@ -326,9 +329,6 @@ public class AltosScanUI pane.setLayout(new GridBagLayout()); - channel = 0; - telemetry = Altos.ao_telemetry_min; - scanning_label = new JLabel("Scanning:"); set_label(); -- cgit v1.2.3 From cbd14ba103ee5e3c5eec18e3a4ff13c320b98634 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 20:44:51 -0700 Subject: altosui: Set 'seen' bits in legacy telemetry packet reader Otherwise, the 'scan' code won't show detected flight computers. Signed-off-by: Keith Packard --- altosui/AltosTelemetryRecordLegacy.java | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/altosui/AltosTelemetryRecordLegacy.java b/altosui/AltosTelemetryRecordLegacy.java index 756f3ec9..f59027ab 100644 --- a/altosui/AltosTelemetryRecordLegacy.java +++ b/altosui/AltosTelemetryRecordLegacy.java @@ -414,27 +414,19 @@ public class AltosTelemetryRecordLegacy extends AltosRecord implements AltosTele static final int AO_GPS_DATE_VALID = (1 << 6); static final int AO_GPS_COURSE_VALID = (1 << 7); - static class theLock extends Object { - } - static public theLock lockObject = new theLock(); public AltosTelemetryRecordLegacy(int[] in_bytes, int in_rssi, int in_status) { bytes = in_bytes; - synchronized(lockObject) { - for (int i = 0; i < in_bytes.length - 2; i++) { - if ((i % 10) == 0) - System.out.printf("%3d:", i); - System.out.printf(" %02x", uint8(i)); - if ((i % 10) == 9 || i == in_bytes.length - 3) - System.out.printf("\n"); - } - } version = 4; adjust = 0; - serial = uint16(0); - if (bytes.length == Altos.ao_telemetry_0_8_len + 4) + if (bytes.length == Altos.ao_telemetry_0_8_len + 4) { + serial = uint8(0); adjust = -1; - + } else + serial = uint16(0); + + seen = seen_flight | seen_sensor | seen_temp_volt | seen_deploy; + callsign = string(62, 8); flight = uint16(2); rssi = in_rssi; @@ -476,6 +468,7 @@ public class AltosTelemetryRecordLegacy extends AltosRecord implements AltosTele if ((gps_flags & (AO_GPS_VALID|AO_GPS_RUNNING)) != 0) { gps = new AltosGPS(); + seen |= seen_gps_time | seen_gps_lat | seen_gps_lon; gps.nsat = (gps_flags & AO_GPS_NUM_SAT_MASK); gps.locked = (gps_flags & AO_GPS_VALID) != 0; gps.connected = true; -- cgit v1.2.3 From 225073fd822f9861a83d65386c29fda9b37bf273 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 16:37:40 -0700 Subject: altosui: Add map preloading GUI Provide a way to manually enter latitude and longitude, preview the map area while downloading a 9x9 grid of map tiles to be used when monitoring flights without network access. Signed-off-by: Keith Packard --- altosui/AltosSiteMap.java | 59 +++++--- altosui/AltosSiteMapPreload.java | 285 +++++++++++++++++++++++++++++++++++++++ altosui/AltosUI.java | 11 ++ altosui/Makefile.am | 1 + 4 files changed, 340 insertions(+), 16 deletions(-) create mode 100644 altosui/AltosSiteMapPreload.java diff --git a/altosui/AltosSiteMap.java b/altosui/AltosSiteMap.java index 7575c10e..73068138 100644 --- a/altosui/AltosSiteMap.java +++ b/altosui/AltosSiteMap.java @@ -150,10 +150,13 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { //System.out.printf("Loading/fetching map %s\n", pngfile); Thread thread = new Thread() { public void run() { - ImageIcon res; - res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl); + final ImageIcon res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl); if (res != null) { - tile.loadMap(res); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + tile.loadMap(res); + } + }); } else { System.out.printf("# Failed to fetch file %s\n", pngfile); System.out.printf(" wget -O '%s' ''\n", pngfile, pngurl); @@ -163,6 +166,24 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { thread.start(); } + File pngfile; + String pngurl; + + public int prefetchMap(int x, int y) { + LatLng map_latlng = latlng( + -centre.x + x*px_size + px_size/2, + -centre.y + y*px_size + px_size/2); + pngfile = MapFile(map_latlng.lat, map_latlng.lng); + pngurl = MapURL(map_latlng.lat, map_latlng.lng); + if (pngfile.exists()) { + return 1; + } else if (AltosSiteMapCache.fetchMap(pngfile, pngurl)) { + return 0; + } else { + return -1; + } + } + public static void prefetchMaps(double lat, double lng, int w, int h) { AltosSiteMap asm = new AltosSiteMap(true); asm.centre = asm.getBaseLocation(lat, lng); @@ -172,18 +193,18 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { int dx = -w/2, dy = -h/2; for (int y = dy; y < h+dy; y++) { for (int x = dx; x < w+dx; x++) { - LatLng map_latlng = asm.latlng( - -asm.centre.x + x*px_size + px_size/2, - -asm.centre.y + y*px_size + px_size/2); - File pngfile = asm.MapFile(map_latlng.lat, map_latlng.lng); - String pngurl = asm.MapURL(map_latlng.lat, map_latlng.lng); - if (pngfile.exists()) { - System.out.printf("Already have %s\n", pngfile); - } else if (AltosSiteMapCache.fetchMap(pngfile, pngurl)) { - System.out.printf("Fetched map %s\n", pngfile); - } else { - System.out.printf("# Failed to fetch file %s\n", pngfile); - System.out.printf(" wget -O '%s' ''\n", pngfile, pngurl); + int r = asm.prefetchMap(x, y); + switch (r) { + case 1: + System.out.printf("Already have %s\n", asm.pngfile); + break; + case 0: + System.out.printf("Fetched map %s\n", asm.pngfile); + break; + case -1: + System.out.printf("# Failed to fetch file %s\n", asm.pngfile); + System.out.printf(" wget -O '%s' ''\n", asm.pngfile, asm.pngurl); + break; } } } @@ -224,6 +245,12 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { boolean initialised = false; Point2D.Double last_pt = null; int last_state = -1; + + public void show(double lat, double lon) { + initMaps(lat, lon); + initialised = true; + scrollRocketToVisible(pt(lat, lon)); + } public void show(final AltosState state, final int crc_errors) { // if insufficient gps data, nothing to update if (!state.gps.locked && state.gps.nsat < 4) @@ -382,6 +409,6 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { } } setViewportView(comp); - setPreferredSize(new Dimension(500,200)); + setPreferredSize(new Dimension(500,500)); } } diff --git a/altosui/AltosSiteMapPreload.java b/altosui/AltosSiteMapPreload.java new file mode 100644 index 00000000..2d9468b9 --- /dev/null +++ b/altosui/AltosSiteMapPreload.java @@ -0,0 +1,285 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.image.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.MouseInputAdapter; +import javax.imageio.ImageIO; +import javax.swing.table.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.lang.Math; +import java.awt.geom.Point2D; +import java.awt.geom.Line2D; + +class AltosMapPos extends Box { + JLabel label; + JComboBox hemi; + JTextField deg; + JLabel deg_label; + JTextField min; + JLabel min_label; + + public void set_value(double new_value) { + double d, m; + int h; + + h = 0; + if (new_value < 0) { + h = 1; + new_value = -new_value; + } + d = Math.floor(new_value); + deg.setText(String.format("%3.0f", d)); + m = (new_value - d) * 60.0; + min.setText(String.format("%7.4f", m)); + hemi.setSelectedIndex(h); + } + + public double get_value() throws NumberFormatException { + int h = hemi.getSelectedIndex(); + double d = Double.parseDouble(deg.getText()); + double m = Double.parseDouble(min.getText()); + double v = d + m/60.0; + if (h == 1) + v = -v; + return v; + } + + public AltosMapPos(String label_value, + String[] hemi_names, + double default_value) { + super(BoxLayout.X_AXIS); + label = new JLabel(label_value); + hemi = new JComboBox(hemi_names); + hemi.setEditable(false); + deg = new JTextField("000"); + deg_label = new JLabel("degrees"); + min = new JTextField("00.0000"); + min_label = new JLabel("minutes"); + set_value(default_value); + add(label); + add(Box.createRigidArea(new Dimension(5, 0))); + add(hemi); + add(Box.createRigidArea(new Dimension(5, 0))); + add(deg); + add(Box.createRigidArea(new Dimension(5, 0))); + add(deg_label); + add(Box.createRigidArea(new Dimension(5, 0))); + add(min); + add(Box.createRigidArea(new Dimension(5, 0))); + add(min_label); + } +} + +public class AltosSiteMapPreload extends JDialog implements ActionListener { + AltosUI owner; + AltosSiteMap map; + + AltosMapPos lat; + AltosMapPos lon; + + JProgressBar pbar; + + final static int width = 9; + final static int height = 9; + final static int tiles = width * height; + + JToggleButton load_button; + boolean loading; + JButton close_button; + + static final String[] lat_hemi_names = { "N", "S" }; + static final String[] lon_hemi_names = { "E", "W" }; + + class updatePbar implements Runnable { + int n; + String s; + + public updatePbar(int in_n, String in_s) { + n = in_n; + s = in_s; + } + + public void run() { + pbar.setValue(n); + pbar.setString(s); + if (n == width * height) { + load_button.setSelected(false); + loading = false; + } + } + } + + class bgLoad extends Thread { + + AltosSiteMap map; + + public bgLoad(AltosSiteMap in_map) { + map = in_map; + } + + public void run() { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + map.prefetchMap(y - height/2, x - width/2); + SwingUtilities.invokeLater(new updatePbar(y * height + x + 1, + map.pngfile.toString())); + } + } + } + } + + public void actionPerformed(ActionEvent e) { + String cmd = e.getActionCommand(); + + if (cmd.equals("close")) + setVisible(false); + + if (cmd.equals("load")) { + if (!loading) { + loading = true; + final double latitude = lat.get_value(); + final double longitude = lon.get_value(); + map.show(latitude,longitude); + bgLoad thread = new bgLoad(map); + thread.start(); + } + } + } + + public AltosSiteMapPreload(AltosUI in_owner) { + owner = in_owner; + + Container pane = getContentPane(); + GridBagConstraints c = new GridBagConstraints(); + Insets i = new Insets(4,4,4,4); + + pane.setLayout(new GridBagLayout()); + + map = new AltosSiteMap(); + + c.fill = GridBagConstraints.BOTH; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 1; + + c.gridx = 0; + c.gridy = 0; + c.gridwidth = 2; + c.anchor = GridBagConstraints.CENTER; + + pane.add(map, c); + + pbar = new JProgressBar(); + pbar.setMinimum(0); + pbar.setMaximum(width * height); + pbar.setValue(0); + pbar.setString(""); + pbar.setStringPainted(true); + + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 0; + + c.gridx = 0; + c.gridy = 1; + c.gridwidth = 2; + + pane.add(pbar, c); + + lat = new AltosMapPos("Latitude:", + lat_hemi_names, + 37.167833333); + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 0; + + c.gridx = 0; + c.gridy = 2; + c.gridwidth = 1; + c.anchor = GridBagConstraints.CENTER; + + pane.add(lat, c); + + lon = new AltosMapPos("Longitude:", + lon_hemi_names, + -97.73975); + + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 0; + + c.gridx = 1; + c.gridy = 2; + c.gridwidth = 1; + c.anchor = GridBagConstraints.CENTER; + + pane.add(lon, c); + + load_button = new JToggleButton("Load Map"); + load_button.addActionListener(this); + load_button.setActionCommand("load"); + + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 0; + + c.gridx = 0; + c.gridy = 3; + c.gridwidth = 1; + c.anchor = GridBagConstraints.CENTER; + + pane.add(load_button, c); + + close_button = new JButton("Close"); + close_button.addActionListener(this); + close_button.setActionCommand("close"); + + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 0; + + c.gridx = 1; + c.gridy = 3; + c.gridwidth = 1; + c.anchor = GridBagConstraints.CENTER; + + pane.add(close_button, c); + + pack(); + setLocationRelativeTo(owner); + setVisible(true); + } +} \ No newline at end of file diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 6a24d8a9..d8c8d61c 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -180,6 +180,13 @@ public class AltosUI extends JFrame { } }); + b = addButton(1, 2, "Load Maps"); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + LoadMaps(); + } + }); + setTitle("AltOS"); pane.doLayout(); @@ -238,6 +245,10 @@ public class AltosUI extends JFrame { new AltosScanUI(AltosUI.this); } + void LoadMaps() { + new AltosSiteMapPreload(AltosUI.this); + } + /* * Replay a flight from telemetry data */ diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 0a3ed0b1..18862d98 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -88,6 +88,7 @@ altosui_JAVA = \ AltosSerialInUseException.java \ AltosSerialMonitor.java \ AltosSiteMap.java \ + AltosSiteMapPreload.java \ AltosSiteMapCache.java \ AltosSiteMapTile.java \ AltosState.java \ -- cgit v1.2.3 From 0929ee32f753255cbe1474988cb41a5a86d29a0e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 17:37:20 -0700 Subject: altosui: Try to avoid resize weirdness with map preloading grid bag + box does some strange stuff, this appears to avoid the worst of the interactions. Signed-off-by: Keith Packard --- altosui/AltosSiteMapPreload.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/altosui/AltosSiteMapPreload.java b/altosui/AltosSiteMapPreload.java index 2d9468b9..f939e9d6 100644 --- a/altosui/AltosSiteMapPreload.java +++ b/altosui/AltosSiteMapPreload.java @@ -217,7 +217,7 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener { c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.CENTER; c.insets = i; - c.weightx = 1; + c.weightx = 0; c.weighty = 0; c.gridx = 0; @@ -234,7 +234,7 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener { c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.CENTER; c.insets = i; - c.weightx = 1; + c.weightx = 0; c.weighty = 0; c.gridx = 1; -- cgit v1.2.3 From 00e6981c2e0a668864fcf391932855cd8942140c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 21:05:06 -0700 Subject: altosui: Flush telemetry lines before starting to watch for scan results This prevents pending telemetry lines from being incorrectly attributed to the wrong channel/telemetry. Signed-off-by: Keith Packard --- altosui/AltosScanUI.java | 5 +++++ altosui/AltosTelemetryReader.java | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index bc1638ed..96cab73b 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -280,6 +280,11 @@ public class AltosScanUI reader = new AltosTelemetryReader(device); reader.serial.set_channel(channel); reader.serial.set_telemetry(telemetry); + try { + Thread.sleep(100); + } catch (InterruptedException ie) { + } + reader.flush(); handler = new TelemetryHandler(); thread = new Thread(handler); thread.start(); diff --git a/altosui/AltosTelemetryReader.java b/altosui/AltosTelemetryReader.java index 18f17841..23524b2c 100644 --- a/altosui/AltosTelemetryReader.java +++ b/altosui/AltosTelemetryReader.java @@ -39,6 +39,10 @@ class AltosTelemetryReader extends AltosFlightReader { return next; } + void flush() { + telem.clear(); + } + void close(boolean interrupted) { serial.remove_monitor(telem); log.close(); -- cgit v1.2.3 From 0a4d934f6e2914bfe2d965630543f029a1576c11 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 22:34:44 -0700 Subject: altosui: Display full map preload area in view. This involved fixing the map view to support arbitrary sizes, and then exposing a synchronous tile loading API so that the progress bar could be used to show tile loading progress. Signed-off-by: Keith Packard --- altosui/AltosSiteMap.java | 99 +++++++++++++++++++++++----------------- altosui/AltosSiteMapCache.java | 6 +++ altosui/AltosSiteMapPreload.java | 91 +++++++++++++++++++++++++----------- altosui/AltosSiteMapTile.java | 8 +++- 4 files changed, 136 insertions(+), 68 deletions(-) diff --git a/altosui/AltosSiteMap.java b/altosui/AltosSiteMap.java index 73068138..188902e9 100644 --- a/altosui/AltosSiteMap.java +++ b/altosui/AltosSiteMap.java @@ -97,6 +97,8 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { int zoom; double scale_x, scale_y; + int radius; /* half width/height of tiles to load */ + private Point2D.Double pt(double lat, double lng) { return pt(new LatLng(lat, lng), scale_x, scale_y); } @@ -144,37 +146,31 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { // nothing } - private void bgLoadMap(final AltosSiteMapTile tile, - final File pngfile, final String pngurl) + private void loadMap(final AltosSiteMapTile tile, + File pngfile, String pngurl) { - //System.out.printf("Loading/fetching map %s\n", pngfile); - Thread thread = new Thread() { - public void run() { - final ImageIcon res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl); - if (res != null) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - tile.loadMap(res); - } - }); - } else { - System.out.printf("# Failed to fetch file %s\n", pngfile); - System.out.printf(" wget -O '%s' ''\n", pngfile, pngurl); - } - } - }; - thread.start(); + final ImageIcon res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl); + if (res != null) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + tile.loadMap(res); + } + }); + } else { + System.out.printf("# Failed to fetch file %s\n", pngfile); + System.out.printf(" wget -O '%s' '%s'\n", pngfile, pngurl); + } } - File pngfile; - String pngurl; + File pngfile; + String pngurl; public int prefetchMap(int x, int y) { LatLng map_latlng = latlng( -centre.x + x*px_size + px_size/2, -centre.y + y*px_size + px_size/2); - pngfile = MapFile(map_latlng.lat, map_latlng.lng); - pngurl = MapURL(map_latlng.lat, map_latlng.lng); + pngfile = MapFile(map_latlng.lat, map_latlng.lng, zoom); + pngurl = MapURL(map_latlng.lat, map_latlng.lng, zoom); if (pngfile.exists()) { return 1; } else if (AltosSiteMapCache.fetchMap(pngfile, pngurl)) { @@ -210,25 +206,41 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { } } - private void initMap(AltosSiteMapTile tile, Point offset) { + public String initMap(Point offset) { + AltosSiteMapTile tile = mapTiles.get(offset); Point2D.Double coord = tileCoordOffset(offset); LatLng map_latlng = latlng(px_size/2-coord.x, px_size/2-coord.y); - File pngfile = MapFile(map_latlng.lat, map_latlng.lng); - String pngurl = MapURL(map_latlng.lat, map_latlng.lng); - bgLoadMap(tile, pngfile, pngurl); + File pngfile = MapFile(map_latlng.lat, map_latlng.lng, zoom); + String pngurl = MapURL(map_latlng.lat, map_latlng.lng, zoom); + loadMap(tile, pngfile, pngurl); + return pngfile.toString(); } - private void initMaps(double lat, double lng) { - centre = getBaseLocation(lat, lng); - + public void setBaseLocation(double lat, double lng) { for (Point k : mapTiles.keySet()) { - initMap(mapTiles.get(k), k); + AltosSiteMapTile tile = mapTiles.get(k); + tile.clearMap(); } + + centre = getBaseLocation(lat, lng); + scrollRocketToVisible(pt(lat,lng)); } - private File MapFile(double lat, double lng) { + private void initMaps(double lat, double lng) { + setBaseLocation(lat, lng); + + Thread thread = new Thread() { + public void run() { + for (Point k : mapTiles.keySet()) + initMap(k); + } + }; + thread.start(); + } + + private static File MapFile(double lat, double lng, int zoom) { char chlat = lat < 0 ? 'S' : 'N'; char chlng = lng < 0 ? 'W' : 'E'; if (lat < 0) lat = -lat; @@ -238,7 +250,7 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { chlat, lat, chlng, lng, zoom)); } - private String MapURL(double lat, double lng) { + private static String MapURL(double lat, double lng, int zoom) { return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&sensor=false&maptype=hybrid&format=png32", lat, lng, zoom, px_size, px_size); } @@ -248,7 +260,6 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { public void show(double lat, double lon) { initMaps(lat, lon); - initialised = true; scrollRocketToVisible(pt(lat, lon)); } public void show(final AltosState state, final int crc_errors) { @@ -295,7 +306,7 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { AltosSiteMapTile tile = createTile(offset); tile.show(state, crc_errors, lref, ref); - initMap(tile, offset); + initMap(offset); finishTileLater(tile, offset); } @@ -325,13 +336,13 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { } private void ensureTilesAround(Point base_offset) { - for (int x = -1; x <= 1; x++) { - for (int y = -1; y <= 1; y++) { + for (int x = -radius; x <= radius; x++) { + for (int y = -radius; y <= radius; y++) { Point offset = new Point(base_offset.x + x, base_offset.y + y); if (mapTiles.containsKey(offset)) continue; AltosSiteMapTile tile = createTile(offset); - initMap(tile, offset); + initMap(offset); finishTileLater(tile, offset); } } @@ -396,13 +407,15 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { JComponent comp = new JComponent() { }; private GridBagLayout layout = new GridBagLayout(); - public AltosSiteMap() { + public AltosSiteMap(int in_radius) { + radius = in_radius; + GrabNDrag scroller = new GrabNDrag(comp); comp.setLayout(layout); - for (int x = -1; x <= 1; x++) { - for (int y = -1; y <= 1; y++) { + for (int x = -radius; x <= radius; x++) { + for (int y = -radius; y <= radius; y++) { Point offset = new Point(x, y); AltosSiteMapTile t = createTile(offset); addTileAt(t, offset); @@ -411,4 +424,8 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { setViewportView(comp); setPreferredSize(new Dimension(500,500)); } + + public AltosSiteMap() { + this(1); + } } diff --git a/altosui/AltosSiteMapCache.java b/altosui/AltosSiteMapCache.java index 2e62cc45..cfad52a9 100644 --- a/altosui/AltosSiteMapCache.java +++ b/altosui/AltosSiteMapCache.java @@ -37,6 +37,7 @@ public class AltosSiteMapCache extends JLabel { try { u = new URL(url); } catch (java.net.MalformedURLException e) { + System.out.printf("Malformed URL '%s'\n", url); return false; } @@ -57,9 +58,12 @@ public class AltosSiteMapCache extends JLabel { in.close(); if (offset != contentLength) { + System.out.printf("Bad length %d != %d\n", + offset, contentLength); return false; } } catch (IOException e) { + System.out.printf("IO exception reading URL\n"); return false; } @@ -69,11 +73,13 @@ public class AltosSiteMapCache extends JLabel { out.flush(); out.close(); } catch (FileNotFoundException e) { + System.out.printf("Can't create file\n"); return false; } catch (IOException e) { if (file.exists()) { file.delete(); } + System.out.printf("IO exception writing file\n"); return false; } return true; diff --git a/altosui/AltosSiteMapPreload.java b/altosui/AltosSiteMapPreload.java index f939e9d6..25133435 100644 --- a/altosui/AltosSiteMapPreload.java +++ b/altosui/AltosSiteMapPreload.java @@ -33,6 +33,7 @@ import java.awt.geom.Point2D; import java.awt.geom.Line2D; class AltosMapPos extends Box { + AltosUI owner; JLabel label; JComboBox hemi; JTextField deg; @@ -58,25 +59,51 @@ class AltosMapPos extends Box { public double get_value() throws NumberFormatException { int h = hemi.getSelectedIndex(); - double d = Double.parseDouble(deg.getText()); - double m = Double.parseDouble(min.getText()); - double v = d + m/60.0; + String d_t = deg.getText(); + String m_t = min.getText(); + double d, m, v; + try { + d = Double.parseDouble(d_t); + } catch (NumberFormatException ne) { + JOptionPane.showMessageDialog(owner, + String.format("Invalid degrees \"%s\"", + d_t), + "Invalid number", + JOptionPane.ERROR_MESSAGE); + throw ne; + } + try { + if (m_t.equals("")) + m = 0; + else + m = Double.parseDouble(m_t); + } catch (NumberFormatException ne) { + JOptionPane.showMessageDialog(owner, + String.format("Invalid minutes \"%s\"", + m_t), + "Invalid number", + JOptionPane.ERROR_MESSAGE); + throw ne; + } + v = d + m/60.0; if (h == 1) v = -v; return v; } - public AltosMapPos(String label_value, + public AltosMapPos(AltosUI in_owner, + String label_value, String[] hemi_names, double default_value) { super(BoxLayout.X_AXIS); + owner = in_owner; label = new JLabel(label_value); hemi = new JComboBox(hemi_names); hemi.setEditable(false); deg = new JTextField("000"); - deg_label = new JLabel("degrees"); + deg_label = new JLabel("°"); min = new JTextField("00.0000"); - min_label = new JLabel("minutes"); + min_label = new JLabel("'"); set_value(default_value); add(label); add(Box.createRigidArea(new Dimension(5, 0))); @@ -101,9 +128,9 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener { JProgressBar pbar; - final static int width = 9; - final static int height = 9; - final static int tiles = width * height; + final static int radius = 4; + final static int width = (radius * 2 + 1); + final static int height = (radius * 2 + 1); JToggleButton load_button; boolean loading; @@ -116,15 +143,21 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener { int n; String s; - public updatePbar(int in_n, String in_s) { - n = in_n; + public updatePbar(int x, int y, String in_s) { + n = (x + radius) + (y + radius) * width + 1; + System.out.printf("update pbar %d\n", n); s = in_s; } public void run() { pbar.setValue(n); pbar.setString(s); - if (n == width * height) { + if (n < width * height) { + pbar.setValue(n); + pbar.setString(s); + } else { + pbar.setValue(0); + pbar.setString(""); load_button.setSelected(false); loading = false; } @@ -140,11 +173,11 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener { } public void run() { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - map.prefetchMap(y - height/2, x - width/2); - SwingUtilities.invokeLater(new updatePbar(y * height + x + 1, - map.pngfile.toString())); + for (int y = -map.radius; y <= map.radius; y++) { + for (int x = -map.radius; x <= map.radius; x++) { + String pngfile; + pngfile = map.initMap(new Point(x,y)); + SwingUtilities.invokeLater(new updatePbar(x, y, pngfile)); } } } @@ -158,12 +191,16 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener { if (cmd.equals("load")) { if (!loading) { - loading = true; - final double latitude = lat.get_value(); - final double longitude = lon.get_value(); - map.show(latitude,longitude); - bgLoad thread = new bgLoad(map); - thread.start(); + try { + final double latitude = lat.get_value(); + final double longitude = lon.get_value(); + map.setBaseLocation(latitude,longitude); + loading = true; + bgLoad thread = new bgLoad(map); + thread.start(); + } catch (NumberFormatException ne) { + load_button.setSelected(false); + } } } } @@ -177,7 +214,7 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener { pane.setLayout(new GridBagLayout()); - map = new AltosSiteMap(); + map = new AltosSiteMap(4); c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; @@ -211,7 +248,8 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener { pane.add(pbar, c); - lat = new AltosMapPos("Latitude:", + lat = new AltosMapPos(owner, + "Latitude:", lat_hemi_names, 37.167833333); c.fill = GridBagConstraints.NONE; @@ -227,7 +265,8 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener { pane.add(lat, c); - lon = new AltosMapPos("Longitude:", + lon = new AltosMapPos(owner, + "Longitude:", lon_hemi_names, -97.73975); diff --git a/altosui/AltosSiteMapTile.java b/altosui/AltosSiteMapTile.java index 8301f42b..66da7c54 100644 --- a/altosui/AltosSiteMapTile.java +++ b/altosui/AltosSiteMapTile.java @@ -35,11 +35,16 @@ public class AltosSiteMapTile extends JLayeredPane { JLabel mapLabel; JLabel draw; Graphics2D g2d; + int px_size; public void loadMap(ImageIcon icn) { mapLabel.setIcon(icn); } + public void clearMap() { + fillLabel(mapLabel, Color.GRAY, px_size); + } + static Color stateColors[] = { Color.WHITE, // startup Color.WHITE, // idle @@ -90,7 +95,8 @@ public class AltosSiteMapTile extends JLayeredPane { return g; } - public AltosSiteMapTile(int px_size) { + public AltosSiteMapTile(int in_px_size) { + px_size = in_px_size; setPreferredSize(new Dimension(px_size, px_size)); mapLabel = new JLabel(); -- cgit v1.2.3 From 1681c57cbbfc5214dbc2a519e54ce9f29ffe3921 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Jul 2011 22:43:34 -0700 Subject: altosui: Remove a bunch of sitemap debugging printfs Seems to work, let's get less chatty Signed-off-by: Keith Packard --- altosui/AltosSiteMapCache.java | 6 ------ altosui/AltosSiteMapPreload.java | 1 - 2 files changed, 7 deletions(-) diff --git a/altosui/AltosSiteMapCache.java b/altosui/AltosSiteMapCache.java index cfad52a9..2e62cc45 100644 --- a/altosui/AltosSiteMapCache.java +++ b/altosui/AltosSiteMapCache.java @@ -37,7 +37,6 @@ public class AltosSiteMapCache extends JLabel { try { u = new URL(url); } catch (java.net.MalformedURLException e) { - System.out.printf("Malformed URL '%s'\n", url); return false; } @@ -58,12 +57,9 @@ public class AltosSiteMapCache extends JLabel { in.close(); if (offset != contentLength) { - System.out.printf("Bad length %d != %d\n", - offset, contentLength); return false; } } catch (IOException e) { - System.out.printf("IO exception reading URL\n"); return false; } @@ -73,13 +69,11 @@ public class AltosSiteMapCache extends JLabel { out.flush(); out.close(); } catch (FileNotFoundException e) { - System.out.printf("Can't create file\n"); return false; } catch (IOException e) { if (file.exists()) { file.delete(); } - System.out.printf("IO exception writing file\n"); return false; } return true; diff --git a/altosui/AltosSiteMapPreload.java b/altosui/AltosSiteMapPreload.java index 25133435..c97f081c 100644 --- a/altosui/AltosSiteMapPreload.java +++ b/altosui/AltosSiteMapPreload.java @@ -145,7 +145,6 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener { public updatePbar(int x, int y, String in_s) { n = (x + radius) + (y + radius) * width + 1; - System.out.printf("update pbar %d\n", n); s = in_s; } -- cgit v1.2.3 From a482d904a3f391c3a24df3660acb3f3696aa6766 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Sat, 16 Jul 2011 23:08:49 -0700 Subject: altosui: Make sure degree and minute values are visible (map preload) Set min size to preferred size so that the value remains visible instead of snapping to 0 pixels wide. Signed-off-by: Keith Packard --- altosui/AltosSiteMapPreload.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/altosui/AltosSiteMapPreload.java b/altosui/AltosSiteMapPreload.java index c97f081c..876c14ac 100644 --- a/altosui/AltosSiteMapPreload.java +++ b/altosui/AltosSiteMapPreload.java @@ -105,6 +105,8 @@ class AltosMapPos extends Box { min = new JTextField("00.0000"); min_label = new JLabel("'"); set_value(default_value); + deg.setMinimumSize(deg.getPreferredSize()); + min.setMinimumSize(min.getPreferredSize()); add(label); add(Box.createRigidArea(new Dimension(5, 0))); add(hemi); -- cgit v1.2.3