From bf8e1b6eecb2bae12ffdbd730bd6ec12ccdaf23a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 25 Dec 2012 14:23:29 -0800 Subject: Start building MicroPeak GUI tool Download, save and analyze MicroPeak flight data Signed-off-by: Keith Packard --- micropeak/MicroGraph.java | 105 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 micropeak/MicroGraph.java (limited to 'micropeak/MicroGraph.java') diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java new file mode 100644 index 00000000..aac14b9a --- /dev/null +++ b/micropeak/MicroGraph.java @@ -0,0 +1,105 @@ +/* + * Copyright © 2012 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 org.altusmetrum.micropeak; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.AltosLib.*; + +import org.jfree.ui.*; +import org.jfree.chart.*; +import org.jfree.chart.plot.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.renderer.*; +import org.jfree.chart.renderer.xy.*; +import org.jfree.chart.labels.*; +import org.jfree.data.xy.*; +import org.jfree.data.*; + +public class MicroGraph { + + XYPlot plot; + JFreeChart chart; + ChartPanel panel; + NumberAxis xAxis; + XYSeries heightSeries; + XYSeries speedSeries; + XYSeries accelSeries; + + MicroData data; + + public JPanel panel() { + return panel; + } + + private void addSeries(XYSeries series, int index, String label, String units) { + XYSeriesCollection dataset = new XYSeriesCollection(series); + NumberAxis axis = new NumberAxis(String.format("%s (%s)", label, units)); + XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false); + + renderer.setPlot(plot); + renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", units), + new java.text.DecimalFormat("0.00"), + new java.text.DecimalFormat("0.00"))); + plot.setRangeAxis(index, axis); + plot.setDataset(index, dataset); + plot.setRenderer(index, renderer); + plot.mapDatasetToRangeAxis(index, index); + } + + public MicroGraph(MicroData data) { + + this.data = data; + + heightSeries = new XYSeries("Height"); + speedSeries = new XYSeries("Speed"); + accelSeries = new XYSeries("Acceleration"); + + for (int i = 0; i < data.pressures.length; i++) { + double x = data.time(i); + heightSeries.add(x, data.height(i)); + speedSeries.add(x, data.speed(i)); + accelSeries.add(x, data.acceleration(i)); + } + + xAxis = new NumberAxis("Time (s)"); + + xAxis.setAutoRangeIncludesZero(true); + + plot = new XYPlot(); + plot.setDomainAxis(xAxis); + plot.setOrientation(PlotOrientation.VERTICAL); + plot.setDomainPannable(true); + plot.setRangePannable(true); + + addSeries(heightSeries, 0, "Height", "m"); + addSeries(speedSeries, 1, "Speed", "m/s"); + addSeries(accelSeries, 2, "Acceleration", "m/s²"); + + chart = new JFreeChart("Flight", JFreeChart.DEFAULT_TITLE_FONT, + plot, true); + + ChartUtilities.applyCurrentTheme(chart); + panel = new ChartPanel(chart); + panel.setMouseWheelEnabled(true); + panel.setPreferredSize(new java.awt.Dimension(800, 500)); + } +} \ No newline at end of file -- cgit v1.2.3 From 9da9adc2718928de2af65a68cddbcc636cc3e9e8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 25 Dec 2012 14:45:49 -0800 Subject: Add file chooser for MicroPeak Needs reasonable directory tracking Signed-off-by: Keith Packard --- micropeak/Makefile.am | 1 + micropeak/MicroFileChooser.java | 65 +++++++++++++++++++++++++++++++++++++++++ micropeak/MicroGraph.java | 19 +++++++----- micropeak/MicroPeak.java | 57 +++++++++++++++++++++--------------- 4 files changed, 111 insertions(+), 31 deletions(-) create mode 100644 micropeak/MicroFileChooser.java (limited to 'micropeak/MicroGraph.java') diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index a3ecac72..32be9070 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -12,6 +12,7 @@ micropeak_JAVA= \ MicroData.java \ MicroGraph.java \ MicroSerial.java \ + MicroFileChooser.java \ MicroUSB.java JFREECHART_CLASS= \ diff --git a/micropeak/MicroFileChooser.java b/micropeak/MicroFileChooser.java new file mode 100644 index 00000000..0fd63a27 --- /dev/null +++ b/micropeak/MicroFileChooser.java @@ -0,0 +1,65 @@ +/* + * Copyright © 2012 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 org.altusmetrum.micropeak; + +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.*; +import org.altusmetrum.AltosLib.*; + +public class MicroFileChooser extends JFileChooser { + JFrame frame; + String filename; + File file; + + public String filename() { + return filename; + } + + public File file() { + return file; + } + + public InputStream runDialog() { + int ret; + + ret = showOpenDialog(frame); + if (ret == APPROVE_OPTION) { + file = getSelectedFile(); + if (file == null) + return null; + filename = file.getName(); + try { + return new FileInputStream(file); + } catch (FileNotFoundException fe) { + JOptionPane.showMessageDialog(frame, + fe.getMessage(), + "Cannot open file", + JOptionPane.ERROR_MESSAGE); + } + } + return null; + } + + public MicroFileChooser(JFrame in_frame) { + frame = in_frame; + setDialogTitle("Select MicroPeak Data File"); + setFileFilter(new FileNameExtensionFilter("MicroPeak data file", + "mpd")); + } +} diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index aac14b9a..9192cad9 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -65,6 +65,18 @@ public class MicroGraph { plot.mapDatasetToRangeAxis(index, index); } + public void setData (MicroData data) { + heightSeries.clear(); + speedSeries.clear(); + accelSeries.clear(); + for (int i = 0; i < data.pressures.length; i++) { + double x = data.time(i); + heightSeries.add(x, data.height(i)); + speedSeries.add(x, data.speed(i)); + accelSeries.add(x, data.acceleration(i)); + } + } + public MicroGraph(MicroData data) { this.data = data; @@ -73,13 +85,6 @@ public class MicroGraph { speedSeries = new XYSeries("Speed"); accelSeries = new XYSeries("Acceleration"); - for (int i = 0; i < data.pressures.length; i++) { - double x = data.time(i); - heightSeries.add(x, data.height(i)); - speedSeries.add(x, data.speed(i)); - accelSeries.add(x, data.acceleration(i)); - } - xAxis = new NumberAxis("Time (s)"); xAxis.setAutoRangeIncludesZero(true); diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index 82d926fb..cd09c475 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -32,24 +32,31 @@ public class MicroPeak extends JFrame implements ActionListener, ItemListener { MicroData data; Container pane; + private void RunFile(InputStream input) { + try { + data = new MicroData(input); + graph.setData(data); + } catch (IOException ioe) { + } + try { + input.close(); + } catch (IOException ioe) { + } + } + private void OpenFile(File filename) { try { - FileInputStream input = new FileInputStream(filename); - try { - data = new MicroData(input); - graph = new MicroGraph(data); - pane.add(graph.panel); - } catch (IOException ioe) { - } - try { - input.close(); - } catch (IOException ioe) { - } + RunFile (new FileInputStream(filename)); } catch (FileNotFoundException fne) { } } private void SelectFile() { + MicroFileChooser chooser = new MicroFileChooser(this); + InputStream input = chooser.runDialog(); + + if (input != null) + RunFile(input); } private void DownloadData() { @@ -73,17 +80,12 @@ public class MicroPeak extends JFrame implements ActionListener, ItemListener { public void itemStateChanged(ItemEvent e) { } - public MicroPeak(File filename) { + public MicroPeak() { this.filename = filename; pane = getContentPane(); -// JLabel label = new JLabel ("Hello, World"); -// pane.add(label); - - setSize(800, 500); - setTitle("MicroPeak"); JMenuBar menuBar = new JMenuBar(); @@ -116,20 +118,27 @@ public class MicroPeak extends JFrame implements ActionListener, ItemListener { } }); - if (filename != null) - this.OpenFile(filename); + graph = new MicroGraph(data); + pane.add(graph.panel); + pane.doLayout(); + pane.validate(); + doLayout(); + validate(); + Insets i = getInsets(); + Dimension ps = pane.getPreferredSize(); + ps.width += i.left + i.right; + ps.height += i.top + i.bottom; + setPreferredSize(ps); + setSize(ps); setVisible(true); } - public MicroPeak() { - this(null); - } - public static void main(final String[] args) { boolean opened = false; for (int i = 0; i < args.length; i++) { - new MicroPeak(new File(args[i])); + MicroPeak m = new MicroPeak(); + m.OpenFile(new File(args[i])); opened = true; } if (!opened) -- cgit v1.2.3 From 56a1210a7b04a3623d19ec282f26fecc79c126dd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 31 Dec 2012 11:42:57 -0800 Subject: micropeak: Use altosuilib This removes a pile of code stolen from altosui Signed-off-by: Keith Packard --- micropeak/.gitignore | 6 + micropeak/Makefile.am | 22 ++-- micropeak/MicroFileChooser.java | 2 + micropeak/MicroFontListener.java | 22 ---- micropeak/MicroFrame.java | 45 +------ micropeak/MicroGraph.java | 82 +++++++++--- micropeak/MicroPeak.java | 21 +++- micropeak/MicroPreferences.java | 221 --------------------------------- micropeak/MicroPreferencesBackend.java | 101 --------------- micropeak/MicroSerial.java | 4 +- micropeak/MicroUIListener.java | 22 ---- 11 files changed, 109 insertions(+), 439 deletions(-) create mode 100644 micropeak/.gitignore delete mode 100644 micropeak/MicroFontListener.java delete mode 100644 micropeak/MicroPreferences.java delete mode 100644 micropeak/MicroPreferencesBackend.java delete mode 100644 micropeak/MicroUIListener.java (limited to 'micropeak/MicroGraph.java') diff --git a/micropeak/.gitignore b/micropeak/.gitignore new file mode 100644 index 00000000..fc99b31c --- /dev/null +++ b/micropeak/.gitignore @@ -0,0 +1,6 @@ +*.jar +Manifest.txt +classes +*.stamp +micropeak +micropeak-test diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index 2cfd2ad3..fde981a6 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -1,7 +1,7 @@ JAVAROOT=classes AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation -CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH=".:classes:../altoslib/*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" +CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH=".:classes:../altoslib/*:../altosuilib/*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" bin_SCRIPTS=micropeak @@ -14,10 +14,6 @@ micropeak_JAVA= \ MicroGraph.java \ MicroSerial.java \ MicroFileChooser.java \ - MicroPreferences.java \ - MicroPreferencesBackend.java \ - MicroFontListener.java \ - MicroUIListener.java \ MicroUSB.java JFREECHART_CLASS= \ @@ -38,6 +34,9 @@ LIBALTOS= \ ALTOSLIB_CLASS=\ AltosLib.jar +ALTOSUILIB_CLASS=\ + AltosUILib.jar + # Icons ICONDIR=$(top_srcdir)/icon @@ -62,6 +61,7 @@ all-local: micropeak-test $(JAR) clean-local: -rm -rf classes $(JAR) $(FATJAR) \ $(ALTOSLIB_CLASS) \ + $(ALTOSUILIB_CLASS) \ $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt \ micropeak micropeak-test macosx linux windows @@ -75,13 +75,13 @@ micropeak-test: Makefile echo 'exec java -cp "./*:../libaltos/*:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" -jar micropeak.jar "$$@"' >> $@ chmod +x $@ -$(JAR): classmicropeak.stamp Manifest.txt $(JAVA_ICONS) $(ALTOSLIB_CLASS) +$(JAR): classmicropeak.stamp Manifest.txt $(JAVA_ICONS) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) jar cfm $@ Manifest.txt \ $(ICONJAR) \ -C classes org \ -C ../libaltos libaltosJNI -$(FATJAR): classmicropeak.stamp Manifest-fat.txt $(ALTOSLIB_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(JAVA_ICONS) +$(FATJAR): classmicropeak.stamp Manifest-fat.txt $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(JAVA_ICONS) jar cfm $@ Manifest-fat.txt \ $(ICONJAR) \ -C classes org \ @@ -122,6 +122,10 @@ $(ALTOSLIB_CLASS): -rm -f "$@" $(LN_S) ../altoslib/"$@" . +$(ALTOSUILIB_CLASS): + -rm -f "$@" + $(LN_S) ../altosuilib/"$@" . + $(JFREECHART_CLASS): -rm -f "$@" $(LN_S) "$(JFREECHART)"/"$@" . @@ -132,9 +136,9 @@ $(JCOMMON_CLASS): Manifest.txt: Makefile echo 'Main-Class: org.altusmetrum.micropeak.MicroPeak' > $@ - echo "Class-Path: AltosLib.jar $(JCOMMON)/jcommon.jar $(JFREECHART)/jfreechart.jar" >> $@ + echo "Class-Path: AltosLib.jar AltosUILib.jar $(JCOMMON)/jcommon.jar $(JFREECHART)/jfreechart.jar" >> $@ Manifest-fat.txt: echo 'Main-Class: org.altusmetrum.micropeak.MicroPeak' > $@ - echo "Class-Path: AltosLib.jar jcommon.jar jfreechart.jar" >> $@ + echo "Class-Path: AltosLib.jar AltosUILib.jar jcommon.jar jfreechart.jar" >> $@ diff --git a/micropeak/MicroFileChooser.java b/micropeak/MicroFileChooser.java index 0fd63a27..d2540987 100644 --- a/micropeak/MicroFileChooser.java +++ b/micropeak/MicroFileChooser.java @@ -21,6 +21,7 @@ import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.io.*; import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; public class MicroFileChooser extends JFileChooser { JFrame frame; @@ -61,5 +62,6 @@ public class MicroFileChooser extends JFileChooser { setDialogTitle("Select MicroPeak Data File"); setFileFilter(new FileNameExtensionFilter("MicroPeak data file", "mpd")); + setCurrentDirectory(AltosUIPreferences.logdir()); } } diff --git a/micropeak/MicroFontListener.java b/micropeak/MicroFontListener.java deleted file mode 100644 index a902584c..00000000 --- a/micropeak/MicroFontListener.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 org.altusmetrum.micropeak; - -public interface MicroFontListener { - void font_size_changed(int font_size); -} diff --git a/micropeak/MicroFrame.java b/micropeak/MicroFrame.java index a9b9a37a..03e3af0c 100644 --- a/micropeak/MicroFrame.java +++ b/micropeak/MicroFrame.java @@ -21,21 +21,10 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; +import org.altusmetrum.altosuilib.*; -class MicroFrameListener extends WindowAdapter { - public void windowClosing (WindowEvent e) { - MicroPreferences.unregister_ui_listener((MicroFrame) e.getWindow()); - } -} - -public class MicroFrame extends JFrame implements MicroUIListener { - - public void ui_changed(String look_and_feel) { - SwingUtilities.updateComponentTreeUI(this); - this.pack(); - } - - static final String[] icon_names = { +public class MicroFrame extends AltosUIFrame { + static String[] micro_icon_names = { "/micropeak-16.png", "/micropeak-32.png", "/micropeak-48.png", @@ -44,31 +33,5 @@ public class MicroFrame extends JFrame implements MicroUIListener { "/micropeak-256.png" }; - public void set_icon() { - ArrayList icons = new ArrayList(); - - for (int i = 0; i < icon_names.length; i++) { - java.net.URL imgURL = MicroPeak.class.getResource(icon_names[i]); - if (imgURL != null) - icons.add(new ImageIcon(imgURL).getImage()); - } - - setIconImages(icons); - } - - public MicroFrame() { - super(); - MicroPreferences.set_component(this); - MicroPreferences.register_ui_listener(this); - addWindowListener(new MicroFrameListener()); - set_icon(); - } - - public MicroFrame(String name) { - super(name); - MicroPreferences.set_component(this); - MicroPreferences.register_ui_listener(this); - addWindowListener(new MicroFrameListener()); - set_icon(); - } + static { set_icon_names(micro_icon_names); } } diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index 9192cad9..38f54fe0 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -34,15 +34,47 @@ import org.jfree.chart.labels.*; import org.jfree.data.xy.*; import org.jfree.data.*; -public class MicroGraph { +class MicroSeries extends XYSeries { + NumberAxis axis; + String label; + String units; + Color color; + + String label() { + return String.format("%s (%s)", label, units); + } + + void set_units(String units) { + this.units = units; + + axis.setLabel(label()); + } + + public MicroSeries (String label, String units, Color color) { + super(label); + this.label = label; + this.units = units; + this.color = color; + + axis = new NumberAxis(label()); + axis.setLabelPaint(color); + axis.setTickLabelPaint(color); + } +} + +public class MicroGraph implements AltosUnitsListener { XYPlot plot; JFreeChart chart; ChartPanel panel; NumberAxis xAxis; - XYSeries heightSeries; - XYSeries speedSeries; - XYSeries accelSeries; + MicroSeries heightSeries; + MicroSeries speedSeries; + MicroSeries accelSeries; + + static final private Color red = new Color(194,31,31); + static final private Color green = new Color(31,194,31); + static final private Color blue = new Color(31,31,194); MicroData data; @@ -50,40 +82,50 @@ public class MicroGraph { return panel; } - private void addSeries(XYSeries series, int index, String label, String units) { + private MicroSeries addSeries(int index, String label, String units, Color color) { + MicroSeries series = new MicroSeries(label, units, color); XYSeriesCollection dataset = new XYSeriesCollection(series); - NumberAxis axis = new NumberAxis(String.format("%s (%s)", label, units)); XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false); + renderer.setSeriesPaint(0, color); renderer.setPlot(plot); renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", units), new java.text.DecimalFormat("0.00"), new java.text.DecimalFormat("0.00"))); - plot.setRangeAxis(index, axis); + plot.setRangeAxis(index, series.axis); plot.setDataset(index, dataset); plot.setRenderer(index, renderer); plot.mapDatasetToRangeAxis(index, index); + return series; } - public void setData (MicroData data) { + public void resetData() { heightSeries.clear(); speedSeries.clear(); accelSeries.clear(); for (int i = 0; i < data.pressures.length; i++) { double x = data.time(i); - heightSeries.add(x, data.height(i)); - speedSeries.add(x, data.speed(i)); - accelSeries.add(x, data.acceleration(i)); + heightSeries.add(x, AltosConvert.height.value(data.height(i))); + speedSeries.add(x, AltosConvert.speed.value(data.speed(i))); + accelSeries.add(x, AltosConvert.accel.value(data.acceleration(i))); } } - public MicroGraph(MicroData data) { - + public void setData (MicroData data) { this.data = data; + resetData(); + } - heightSeries = new XYSeries("Height"); - speedSeries = new XYSeries("Speed"); - accelSeries = new XYSeries("Acceleration"); + public void units_changed(boolean imperial_units) { + if (data != null) { + heightSeries.set_units(AltosConvert.height.show_units()); + speedSeries.set_units(AltosConvert.speed.show_units()); + accelSeries.set_units(AltosConvert.accel.show_units()); + resetData(); + } + } + + public MicroGraph() { xAxis = new NumberAxis("Time (s)"); @@ -95,9 +137,9 @@ public class MicroGraph { plot.setDomainPannable(true); plot.setRangePannable(true); - addSeries(heightSeries, 0, "Height", "m"); - addSeries(speedSeries, 1, "Speed", "m/s"); - addSeries(accelSeries, 2, "Acceleration", "m/s²"); + heightSeries = addSeries(0, "Height", AltosConvert.height.show_units(), red); + speedSeries = addSeries(1, "Speed", AltosConvert.speed.show_units(), green); + accelSeries = addSeries(2, "Acceleration", AltosConvert.accel.show_units(), blue); chart = new JFreeChart("Flight", JFreeChart.DEFAULT_TITLE_FONT, plot, true); @@ -106,5 +148,7 @@ public class MicroGraph { panel = new ChartPanel(chart); panel.setMouseWheelEnabled(true); panel.setPreferredSize(new java.awt.Dimension(800, 500)); + + AltosPreferences.register_units_listener(this); } } \ No newline at end of file diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index c9074348..463238c8 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -24,6 +24,7 @@ import java.io.*; import java.util.concurrent.*; import java.util.*; import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; public class MicroPeak extends MicroFrame implements ActionListener, ItemListener { @@ -59,6 +60,10 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene RunFile(input); } + private void Preferences() { + new AltosConfigureUI(this); + } + private void DownloadData() { java.util.List devices = MicroUSB.list(); for (MicroUSB device : devices) @@ -66,7 +71,6 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene } public void actionPerformed(ActionEvent ev) { - System.out.printf("action %s %s\n", ev.getActionCommand(), ev.paramString()); if ("Exit".equals(ev.getActionCommand())) System.exit(0); else if ("Open".equals(ev.getActionCommand())) @@ -75,6 +79,8 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene new MicroPeak(); else if ("Download".equals(ev.getActionCommand())) DownloadData(); + else if ("Preferences".equals(ev.getActionCommand())) + Preferences(); } public void itemStateChanged(ItemEvent e) { @@ -82,7 +88,7 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene public MicroPeak() { - this.filename = filename; + AltosUIPreferences.set_component(this); pane = getContentPane(); @@ -106,6 +112,10 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene fileMenu.add(downloadAction); downloadAction.addActionListener(this); + JMenuItem preferencesAction = new JMenuItem("Preferences"); + fileMenu.add(preferencesAction); + preferencesAction.addActionListener(this); + JMenuItem exitAction = new JMenuItem("Exit"); fileMenu.add(exitAction); exitAction.addActionListener(this); @@ -118,7 +128,7 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene } }); - graph = new MicroGraph(data); + graph = new MicroGraph(); pane.add(graph.panel); pane.doLayout(); pane.validate(); @@ -136,6 +146,11 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene public static void main(final String[] args) { boolean opened = false; + try { + UIManager.setLookAndFeel(AltosUIPreferences.look_and_feel()); + } catch (Exception e) { + } + for (int i = 0; i < args.length; i++) { MicroPeak m = new MicroPeak(); m.OpenFile(new File(args[i])); diff --git a/micropeak/MicroPreferences.java b/micropeak/MicroPreferences.java deleted file mode 100644 index 70c2557c..00000000 --- a/micropeak/MicroPreferences.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * 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 org.altusmetrum.micropeak; - -import java.io.*; -import java.util.*; -import java.awt.Component; -import javax.swing.*; -import java.awt.*; -import org.altusmetrum.AltosLib.*; - -public class MicroPreferences extends AltosPreferences { - - static final int tab_elt_pad = 5; - - static Font label_font; - static Font value_font; - static Font status_font; - static Font table_label_font; - static Font table_value_font; - - final static int font_size_small = 1; - final static int font_size_medium = 2; - final static int font_size_large = 3; - - static void set_fonts(int size) { - int brief_size; - int table_size; - int status_size; - - switch (size) { - case font_size_small: - brief_size = 16; - status_size = 18; - table_size = 11; - break; - default: - case font_size_medium: - brief_size = 22; - status_size = 24; - table_size = 14; - break; - case font_size_large: - brief_size = 26; - status_size = 30; - table_size = 17; - break; - } - label_font = new Font("Dialog", Font.PLAIN, brief_size); - value_font = new Font("Monospaced", Font.PLAIN, brief_size); - status_font = new Font("SansSerif", Font.BOLD, status_size); - table_label_font = new Font("SansSerif", Font.PLAIN, table_size); - table_value_font = new Font("Monospaced", Font.PLAIN, table_size); - } - - /* font size preferences name */ - final static String fontSizePreference = "FONT-SIZE"; - - /* Look&Feel preference name */ - final static String lookAndFeelPreference = "LOOK-AND-FEEL"; - - /* UI Component to pop dialogs up */ - static Component component; - - static LinkedList font_listeners; - - static int font_size = font_size_medium; - - static LinkedList ui_listeners; - - static String look_and_feel = null; - - /* Serial debug */ - static boolean serial_debug; - - public static void init() { - AltosPreferences.init(new MicroPreferencesBackend()); - - font_listeners = new LinkedList(); - - font_size = backend.getInt(fontSizePreference, font_size_medium); - set_fonts(font_size); - look_and_feel = backend.getString(lookAndFeelPreference, UIManager.getSystemLookAndFeelClassName()); - - ui_listeners = new LinkedList(); - serial_debug = backend.getBoolean(serialDebugPreference, false); - } - - static { init(); } - - static void set_component(Component in_component) { - component = in_component; - } - - private static boolean check_dir(File dir) { - if (!dir.exists()) { - if (!dir.mkdirs()) { - JOptionPane.showMessageDialog(component, - dir.getName(), - "Cannot create directory", - JOptionPane.ERROR_MESSAGE); - return false; - } - } else if (!dir.isDirectory()) { - JOptionPane.showMessageDialog(component, - dir.getName(), - "Is not a directory", - JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - - /* Configure the log directory. This is where all telemetry and eeprom files - * will be written to, and where replay will look for telemetry files - */ - public static void ConfigureLog() { - JFileChooser logdir_chooser = new JFileChooser(logdir.getParentFile()); - - logdir_chooser.setDialogTitle("Configure Data Logging Directory"); - logdir_chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - - if (logdir_chooser.showDialog(component, "Select Directory") == JFileChooser.APPROVE_OPTION) { - File dir = logdir_chooser.getSelectedFile(); - if (check_dir(dir)) - set_logdir(dir); - } - } - public static int font_size() { - synchronized (backend) { - return font_size; - } - } - - static void set_fonts() { - } - - public static void set_font_size(int new_font_size) { - synchronized (backend) { - font_size = new_font_size; - backend.putInt(fontSizePreference, font_size); - flush_preferences(); - set_fonts(font_size); - for (MicroFontListener l : font_listeners) - l.font_size_changed(font_size); - } - } - - public static void register_font_listener(MicroFontListener l) { - synchronized (backend) { - font_listeners.add(l); - } - } - - public static void unregister_font_listener(MicroFontListener l) { - synchronized (backend) { - font_listeners.remove(l); - } - } - - public static void set_look_and_feel(String new_look_and_feel) { - try { - UIManager.setLookAndFeel(new_look_and_feel); - } catch (Exception e) { - } - synchronized(backend) { - look_and_feel = new_look_and_feel; - backend.putString(lookAndFeelPreference, look_and_feel); - flush_preferences(); - for (MicroUIListener l : ui_listeners) - l.ui_changed(look_and_feel); - } - } - - public static String look_and_feel() { - synchronized (backend) { - return look_and_feel; - } - } - - public static void register_ui_listener(MicroUIListener l) { - synchronized(backend) { - ui_listeners.add(l); - } - } - - public static void unregister_ui_listener(MicroUIListener l) { - synchronized (backend) { - ui_listeners.remove(l); - } - } - public static void set_serial_debug(boolean new_serial_debug) { - synchronized (backend) { - serial_debug = new_serial_debug; - backend.putBoolean(serialDebugPreference, serial_debug); - flush_preferences(); - } - } - - public static boolean serial_debug() { - synchronized (backend) { - return serial_debug; - } - } - -} diff --git a/micropeak/MicroPreferencesBackend.java b/micropeak/MicroPreferencesBackend.java deleted file mode 100644 index 7d92f6be..00000000 --- a/micropeak/MicroPreferencesBackend.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright © 2012 Mike Beattie - * - * 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 org.altusmetrum.micropeak; - -import java.io.File; -import java.util.prefs.*; -import org.altusmetrum.AltosLib.*; -import javax.swing.filechooser.FileSystemView; - -public class MicroPreferencesBackend implements AltosPreferencesBackend { - - private Preferences _preferences = null; - - public MicroPreferencesBackend() { - _preferences = Preferences.userRoot().node("/org/altusmetrum/altosui"); - } - - public MicroPreferencesBackend(Preferences in_preferences) { - _preferences = in_preferences; - } - - public String getString(String key, String def) { - return _preferences.get(key, def); - } - public void putString(String key, String value) { - _preferences.put(key, value); - } - - public int getInt(String key, int def) { - return _preferences.getInt(key, def); - } - public void putInt(String key, int value) { - _preferences.putInt(key, value); - } - - public double getDouble(String key, double def) { - return _preferences.getDouble(key, def); - } - public void putDouble(String key, double value) { - _preferences.putDouble(key, value); - } - - public boolean getBoolean(String key, boolean def) { - return _preferences.getBoolean(key, def); - } - public void putBoolean(String key, boolean value) { - _preferences.putBoolean(key, value); - } - - public boolean nodeExists(String key) { - try { - return _preferences.nodeExists(key); - } catch (BackingStoreException be) { - return false; - } - } - - public AltosPreferencesBackend node(String key) { - return new MicroPreferencesBackend(_preferences.node(key)); - } - - public String[] keys() { - try { - return _preferences.keys(); - } catch (BackingStoreException be) { - return null; - } - } - - public void remove(String key) { - _preferences.remove(key); - } - - public void flush() { - try { - _preferences.flush(); - } catch (BackingStoreException ee) { - System.err.printf("Cannot save preferences\n"); - } - } - - public File homeDirectory() { - /* Use the file system view default directory */ - return FileSystemView.getFileSystemView().getDefaultDirectory(); - } -} diff --git a/micropeak/MicroSerial.java b/micropeak/MicroSerial.java index 8546276e..a1a77a1d 100644 --- a/micropeak/MicroSerial.java +++ b/micropeak/MicroSerial.java @@ -16,16 +16,18 @@ */ package org.altusmetrum.micropeak; + import java.util.*; import java.io.*; import libaltosJNI.*; +import org.altusmetrum.altosuilib.*; public class MicroSerial extends InputStream { SWIGTYPE_p_altos_file file; public int read() { int c = libaltos.altos_getchar(file, 0); - if (MicroPreferences.serial_debug) + if (AltosUIPreferences.serial_debug) System.out.printf("%c", c); return c; } diff --git a/micropeak/MicroUIListener.java b/micropeak/MicroUIListener.java deleted file mode 100644 index 9aed8dae..00000000 --- a/micropeak/MicroUIListener.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 org.altusmetrum.micropeak; - -public interface MicroUIListener { - public void ui_changed(String look_and_feel); -} -- cgit v1.2.3 From d83587c3c66b730cc54ca153714eee520ee40b2c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 1 Jan 2013 15:30:11 -0800 Subject: micropeak is code complete now. Added save and download functionality. Removed 'new' from file menu. Signed-off-by: Keith Packard --- altoslib/AltosLib.java | 1 + altosuilib/AltosDevice.java | 30 +++++++ altosuilib/AltosDeviceDialog.java | 163 ++++++++++++++++++++++++++++++++++++++ altosuilib/AltosUSBDevice.java | 112 ++++++++++++++++++++++++++ altosuilib/Makefile.am | 3 + libaltos/libaltos.c | 4 + micropeak/Makefile.am | 3 + micropeak/MicroData.java | 15 +++- micropeak/MicroDeviceDialog.java | 50 ++++++++++++ micropeak/MicroDownload.java | 139 ++++++++++++++++++++++++++++++++ micropeak/MicroGraph.java | 5 ++ micropeak/MicroPeak.java | 81 +++++++++++++++---- micropeak/MicroSave.java | 102 ++++++++++++++++++++++++ micropeak/MicroSerial.java | 12 ++- micropeak/MicroUSB.java | 19 +++-- 15 files changed, 708 insertions(+), 31 deletions(-) create mode 100644 altosuilib/AltosDevice.java create mode 100644 altosuilib/AltosDeviceDialog.java create mode 100644 altosuilib/AltosUSBDevice.java create mode 100644 micropeak/MicroDeviceDialog.java create mode 100644 micropeak/MicroDownload.java create mode 100644 micropeak/MicroSave.java (limited to 'micropeak/MicroGraph.java') diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 07516aeb..67138450 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -97,6 +97,7 @@ public class AltosLib { public final static int product_any = 0x10000; public final static int product_basestation = 0x10000 + 1; public final static int product_altimeter = 0x10000 + 2; + public final static int product_micropeak_serial = 0x10000 + 3; /* Bluetooth "identifier" (bluetooth sucks) */ public final static String bt_product_telebt = "TeleBT"; diff --git a/altosuilib/AltosDevice.java b/altosuilib/AltosDevice.java new file mode 100644 index 00000000..69b025ba --- /dev/null +++ b/altosuilib/AltosDevice.java @@ -0,0 +1,30 @@ +/* + * 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 org.altusmetrum.altosuilib; + +import libaltosJNI.*; + +public interface AltosDevice { + public abstract String toString(); + public abstract String toShortString(); + public abstract int getSerial(); + public abstract String getPath(); + public abstract boolean matchProduct(int product); + public abstract String getErrorString(); + public SWIGTYPE_p_altos_file open(); +} diff --git a/altosuilib/AltosDeviceDialog.java b/altosuilib/AltosDeviceDialog.java new file mode 100644 index 00000000..82620b8b --- /dev/null +++ b/altosuilib/AltosDeviceDialog.java @@ -0,0 +1,163 @@ +/* + * Copyright © 2010 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 org.altusmetrum.altosuilib; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +public abstract class AltosDeviceDialog extends AltosUIDialog implements ActionListener { + + private AltosDevice value; + private JList list; + private JButton cancel_button; + private JButton select_button; + private JButton manage_bluetooth_button; + private Frame frame; + private int product; + + public AltosDevice getValue() { + return value; + } + + public abstract AltosDevice[] devices(); + + private void update_devices() { + AltosDevice[] devices = devices(); + list.setListData(devices); + select_button.setEnabled(devices.length > 0); + } + + public AltosDeviceDialog (Frame in_frame, Component location, int in_product) { + super(in_frame, "Device Selection", true); + + product = in_product; + frame = in_frame; + value = null; + + AltosDevice[] devices = devices(); + + cancel_button = new JButton("Cancel"); + cancel_button.setActionCommand("cancel"); + cancel_button.addActionListener(this); + +// manage_bluetooth_button = new JButton("Manage Bluetooth"); +// manage_bluetooth_button.setActionCommand("manage"); +// manage_bluetooth_button.addActionListener(this); + + select_button = new JButton("Select"); + select_button.setActionCommand("select"); + select_button.addActionListener(this); + if (devices.length == 0) + select_button.setEnabled(false); + getRootPane().setDefaultButton(select_button); + + list = new JList(devices) { + //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)); + + //Lay out the buttons from left to right. + JPanel buttonPane = new JPanel(); + buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS)); + buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); + buttonPane.add(Box.createHorizontalGlue()); + buttonPane.add(cancel_button); + buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); +// buttonPane.add(manage_bluetooth_button); +// buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); + buttonPane.add(select_button); + + //Put everything together, using the content pane's BorderLayout. + Container contentPane = getContentPane(); + contentPane.add(listPane, BorderLayout.CENTER); + contentPane.add(buttonPane, BorderLayout.PAGE_END); + + //Initialize values. + if (devices != null && devices.length != 0) + list.setSelectedValue(devices[0], true); + pack(); + setLocationRelativeTo(location); + } + + //Handle clicks on the Set and Cancel buttons. + public void actionPerformed(ActionEvent e) { + if ("select".equals(e.getActionCommand())) + value = (AltosDevice)(list.getSelectedValue()); +// if ("manage".equals(e.getActionCommand())) { +// AltosBTManage.show(frame, AltosBTKnown.bt_known()); +// update_devices(); +// return; +// } + setVisible(false); + } + +} diff --git a/altosuilib/AltosUSBDevice.java b/altosuilib/AltosUSBDevice.java new file mode 100644 index 00000000..2f4e0dc6 --- /dev/null +++ b/altosuilib/AltosUSBDevice.java @@ -0,0 +1,112 @@ +/* + * Copyright © 2010 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 org.altusmetrum.altosuilib; + +import java.util.*; +import libaltosJNI.*; + +public class AltosUSBDevice extends altos_device implements AltosDevice { + + public String toString() { + String name = getName(); + if (name == null) + name = "Altus Metrum"; + return String.format("%-20.20s %4d %s", + name, getSerial(), getPath()); + } + + public String toShortString() { + String name = getName(); + if (name == null) + name = "Altus Metrum"; + return String.format("%s %d %s", + name, getSerial(), getPath()); + + } + + public String getErrorString() { + altos_error error = new altos_error(); + + libaltos.altos_get_last_error(error); + return String.format("%s (%d)", error.getString(), error.getCode()); + } + + public SWIGTYPE_p_altos_file open() { + return libaltos.altos_open(this); + } + + private boolean isAltusMetrum() { + if (getVendor() != AltosUILib.vendor_altusmetrum) + return false; + if (getProduct() < AltosUILib.product_altusmetrum_min) + return false; + if (getProduct() > AltosUILib.product_altusmetrum_max) + return false; + return true; + } + + public boolean matchProduct(int want_product) { + + if (!isAltusMetrum()) + return false; + + if (want_product == AltosUILib.product_any) + return true; + + if (want_product == AltosUILib.product_basestation) + return matchProduct(AltosUILib.product_teledongle) || + matchProduct(AltosUILib.product_teleterra) || + matchProduct(AltosUILib.product_telebt) || + matchProduct(AltosUILib.product_megadongle); + + if (want_product == AltosUILib.product_altimeter) + return matchProduct(AltosUILib.product_telemetrum) || + matchProduct(AltosUILib.product_megametrum); + + int have_product = getProduct(); + + if (have_product == AltosUILib.product_altusmetrum) /* old devices match any request */ + return true; + + if (want_product == have_product) + return true; + + return false; + } + + static java.util.List list(int product) { + if (!AltosUILib.load_library()) + return null; + + SWIGTYPE_p_altos_list list = libaltos.altos_list_start(); + + ArrayList device_list = new ArrayList(); + if (list != null) { + for (;;) { + AltosUSBDevice device = new AltosUSBDevice(); + if (libaltos.altos_list_next(list, device) == 0) + break; + if (device.matchProduct(product)) + device_list.add(device); + } + libaltos.altos_list_finish(list); + } + + return device_list; + } +} \ No newline at end of file diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am index 26aee7c4..e2ff8cb5 100644 --- a/altosuilib/Makefile.am +++ b/altosuilib/Makefile.am @@ -11,6 +11,9 @@ AltosUILibdir = $(datadir)/java AltosUILib_JAVA = \ AltosConfigureUI.java \ + AltosDevice.java \ + AltosDeviceDialog.java \ + AltosUSBDevice.java \ AltosFontListener.java \ AltosUIDialog.java \ AltosUIFrame.java \ diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index d7b266cf..6e884c80 100644 --- a/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -116,6 +116,7 @@ altos_open(struct altos_device *device) return NULL; } + printf ("open\n"); // altos_set_last_error(12, "yeah yeah, failed again"); // free(file); // return NULL; @@ -148,6 +149,8 @@ altos_open(struct altos_device *device) return NULL; } cfmakeraw(&term); + cfsetospeed(&term, B9600); + cfsetispeed(&term, B9600); #ifdef USE_POLL term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; @@ -609,6 +612,7 @@ altos_list_next(struct altos_list *list, struct altos_device *device) { struct altos_usbdev *dev; if (list->current >= list->ndev) { + printf ("end\n"); return 0; } dev = list->dev[list->current]; diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index e0de690c..a54b78a5 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -10,12 +10,15 @@ micropeakdir=$(datadir)/java micropeak_JAVA= \ MicroPeak.java \ MicroData.java \ + MicroDownload.java \ MicroFrame.java \ MicroGraph.java \ + MicroSave.java \ MicroSerial.java \ MicroStats.java \ MicroStatsTable.java \ MicroFileChooser.java \ + MicroDeviceDialog.java \ MicroUSB.java JFREECHART_CLASS= \ diff --git a/micropeak/MicroData.java b/micropeak/MicroData.java index ec9b83d8..8ccd5fd8 100644 --- a/micropeak/MicroData.java +++ b/micropeak/MicroData.java @@ -110,6 +110,7 @@ public class MicroData { private double time_step; private double ground_altitude; private ArrayList bytes; + String name; class FileEndedException extends Exception { @@ -310,12 +311,18 @@ public class MicroData { public void save (OutputStream f) throws IOException { for (int c : bytes) f.write(c); + f.write('\n'); } - public MicroData (InputStream f) throws IOException { + public void set_name(String name) { + this.name = name; + } + + public MicroData (InputStream f, String name) throws IOException, InterruptedException { + this.name = name; bytes = new ArrayList(); if (!find_header(f)) - throw new IOException(); + throw new IOException("No MicroPeak data header found"); try { file_crc = 0xffff; ground_pressure = get_32(f); @@ -354,9 +361,9 @@ public class MicroData { time_step = 0.192; } catch (FileEndedException fe) { - throw new IOException(); + throw new IOException("File Ended Unexpectedly"); } catch (NonHexcharException ne) { - throw new IOException(); + throw new IOException("Non hexadecimal character found"); } } diff --git a/micropeak/MicroDeviceDialog.java b/micropeak/MicroDeviceDialog.java new file mode 100644 index 00000000..7b8a630c --- /dev/null +++ b/micropeak/MicroDeviceDialog.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2012 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 org.altusmetrum.micropeak; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import org.altusmetrum.altosuilib.*; + +public class MicroDeviceDialog extends AltosDeviceDialog { + + public AltosDevice[] devices() { + java.util.List list = MicroUSB.list(); + int num_devices = list.size(); + AltosDevice[] devices = new AltosDevice[num_devices]; + + for (int i = 0; i < num_devices; i++) + devices[i] = list.get(i); + return devices; + } + + public MicroDeviceDialog (Frame in_frame, Component location) { + super(in_frame, location, 0); + } + + public static AltosDevice show (Component frameComp) { + Frame frame = JOptionPane.getFrameForComponent(frameComp); + MicroDeviceDialog dialog; + + dialog = new MicroDeviceDialog (frame, frameComp); + dialog.setVisible(true); + return dialog.getValue(); + } +} diff --git a/micropeak/MicroDownload.java b/micropeak/MicroDownload.java new file mode 100644 index 00000000..2e328b4a --- /dev/null +++ b/micropeak/MicroDownload.java @@ -0,0 +1,139 @@ +/* + * Copyright © 2012 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 org.altusmetrum.micropeak; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener { + MicroPeak owner; + Container pane; + AltosDevice device; + JButton cancel; + MicroData data; + MicroSerial serial; + + private void done_internal() { + setVisible(false); + if (data != null) { + owner = owner.SetData(data); + MicroSave save = new MicroSave(owner, data); + if (save.runDialog()) + owner.SetName(data.name); + } + dispose(); + } + + public void done() { + Runnable r = new Runnable() { + public void run() { + try { + done_internal(); + } catch (Exception ex) { + } + } + }; + SwingUtilities.invokeLater(r); + } + + public void run() { + try { + data = new MicroData(serial, device.toShortString()); + serial.close(); + } catch (FileNotFoundException fe) { + } catch (IOException ioe) { + } catch (InterruptedException ie) { + } + done(); + } + + Thread serial_thread; + + public void start() { + try { + serial = new MicroSerial(device); + } catch (FileNotFoundException fe) { + return; + } + serial_thread = new Thread(this); + serial_thread.start(); + } + + public void actionPerformed(ActionEvent ae) { + System.out.printf ("command %s\n", ae.getActionCommand()); + if (serial_thread != null) { + System.out.printf ("Interrupting serial_thread\n"); + serial.close(); + serial_thread.interrupt(); + } + } + + public MicroDownload(MicroPeak owner, AltosDevice device) { + super (owner, "Download MicroPeak Data", false); + + GridBagConstraints c; + Insets il = new Insets(4,4,4,4); + Insets ir = new Insets(4,4,4,4); + + this.owner = owner; + this.device = device; + + pane = getContentPane(); + pane.setLayout(new GridBagLayout()); + + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = 0; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + JLabel device_label = new JLabel("Device:"); + pane.add(device_label, c); + + c = new GridBagConstraints(); + c.gridx = 1; c.gridy = 0; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + JLabel device_value = new JLabel(device.toString()); + pane.add(device_value, c); + + cancel = new JButton("Cancel"); + c = new GridBagConstraints(); + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.gridx = 0; c.gridy = 1; + c.gridwidth = GridBagConstraints.REMAINDER; + Insets ic = new Insets(4,4,4,4); + c.insets = ic; + pane.add(cancel, c); + + cancel.addActionListener(this); + + pack(); + setLocationRelativeTo(owner); + setVisible(true); + this.start(); + } +} diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index 38f54fe0..b9b084f8 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -111,8 +111,13 @@ public class MicroGraph implements AltosUnitsListener { } } + public void setName (String name) { + chart.setTitle(name); + } + public void setData (MicroData data) { this.data = data; + chart.setTitle(data.name); resetData(); } diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index c69f7167..5e375057 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -34,13 +34,36 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene MicroData data; Container container; JTabbedPane pane; + static int number_of_windows; - private void RunFile(InputStream input) { + MicroPeak SetData(MicroData data) { + MicroPeak mp = this; + if (this.data != null) { + mp = new MicroPeak(); + return mp.SetData(data); + } + this.data = data; + graph.setData(data); + stats.setData(data); + setTitle(data.name); + return this; + } + + void SetName(String name) { + graph.setName(name); + setTitle(name); + } + + private void RunFile(InputStream input, String name) { try { - data = new MicroData(input); - graph.setData(data); - stats.setData(data); + MicroData data = new MicroData(input, name); + SetData(data); } catch (IOException ioe) { + JOptionPane.showMessageDialog(this, + ioe.getMessage(), + "File Read Error", + JOptionPane.ERROR_MESSAGE); + } catch (InterruptedException ie) { } try { input.close(); @@ -50,8 +73,12 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene private void OpenFile(File filename) { try { - RunFile (new FileInputStream(filename)); + RunFile (new FileInputStream(filename), filename.getName()); } catch (FileNotFoundException fne) { + JOptionPane.showMessageDialog(this, + fne.getMessage(), + "Cannot open file", + JOptionPane.ERROR_MESSAGE); } } @@ -60,30 +87,44 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene InputStream input = chooser.runDialog(); if (input != null) - RunFile(input); + RunFile(input, chooser.filename); } private void Preferences() { new AltosConfigureUI(this); } - + private void DownloadData() { - java.util.List devices = MicroUSB.list(); - for (MicroUSB device : devices) - System.out.printf("device %s\n", device.toString()); + AltosDevice device = MicroDeviceDialog.show(this); + + if (device != null) + new MicroDownload(this, device); } + private void Save() { + if (data == null) { + JOptionPane.showMessageDialog(this, + "No data available", + "No data", + JOptionPane.INFORMATION_MESSAGE); + return; + } + MicroSave save = new MicroSave (this, data); + if (save.runDialog()) + SetName(data.name); + } + public void actionPerformed(ActionEvent ev) { if ("Exit".equals(ev.getActionCommand())) System.exit(0); else if ("Open".equals(ev.getActionCommand())) SelectFile(); - else if ("New".equals(ev.getActionCommand())) - new MicroPeak(); else if ("Download".equals(ev.getActionCommand())) DownloadData(); else if ("Preferences".equals(ev.getActionCommand())) Preferences(); + else if ("Save a Copy".equals(ev.getActionCommand())) + Save(); } public void itemStateChanged(ItemEvent e) { @@ -91,6 +132,8 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene public MicroPeak() { + ++number_of_windows; + AltosUIPreferences.set_component(this); container = getContentPane(); @@ -104,10 +147,6 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene JMenu fileMenu = new JMenu("File"); menuBar.add(fileMenu); - JMenuItem newAction = new JMenuItem("New"); - fileMenu.add(newAction); - newAction.addActionListener(this); - JMenuItem openAction = new JMenuItem("Open"); fileMenu.add(openAction); openAction.addActionListener(this); @@ -116,6 +155,10 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene fileMenu.add(downloadAction); downloadAction.addActionListener(this); + JMenuItem saveAction = new JMenuItem("Save a Copy"); + fileMenu.add(saveAction); + saveAction.addActionListener(this); + JMenuItem preferencesAction = new JMenuItem("Preferences"); fileMenu.add(preferencesAction); preferencesAction.addActionListener(this); @@ -128,7 +171,11 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - System.exit(0); + setVisible(false); + dispose(); + --number_of_windows; + if (number_of_windows == 0) + System.exit(0); } }); diff --git a/micropeak/MicroSave.java b/micropeak/MicroSave.java new file mode 100644 index 00000000..cb4b4221 --- /dev/null +++ b/micropeak/MicroSave.java @@ -0,0 +1,102 @@ +/* + * Copyright © 2012 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 org.altusmetrum.micropeak; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroSave extends JFileChooser { + + JFrame frame; + MicroData data; + + public boolean runDialog() { + int ret; + + for (;;) { + ret = showSaveDialog(frame); + if (ret != APPROVE_OPTION) + return false; + File file; + String filename; + file = getSelectedFile(); + if (file == null) + continue; + if (!file.getName().contains(".")) { + String fullname = file.getPath(); + file = new File(fullname.concat(".mpd")); + } + filename = file.getName(); + if (file.exists()) { + if (file.isDirectory()) { + JOptionPane.showMessageDialog(frame, + String.format("\"%s\" is a directory", + filename), + "Directory", + JOptionPane.ERROR_MESSAGE); + continue; + } + int r = JOptionPane.showConfirmDialog(frame, + String.format("\"%s\" already exists. Overwrite?", + filename), + "Overwrite file?", + JOptionPane.YES_NO_OPTION); + if (r != JOptionPane.YES_OPTION) + continue; + + if (!file.canWrite()) { + JOptionPane.showMessageDialog(frame, + String.format("\"%s\" is not writable", + filename), + "File not writable", + JOptionPane.ERROR_MESSAGE); + continue; + } + } + try { + FileOutputStream fos = new FileOutputStream(file); + data.save(fos); + fos.close(); + data.set_name(filename); + return true; + } catch (FileNotFoundException fe) { + JOptionPane.showMessageDialog(frame, + fe.getMessage(), + "Cannot create file", + JOptionPane.ERROR_MESSAGE); + } catch (IOException ioe) { + } + } + } + + public MicroSave(JFrame frame, MicroData data) { + this.frame = frame; + this.data = data; + setDialogTitle("Save MicroPeak Data File"); + setFileFilter(new FileNameExtensionFilter("MicroPeak data file", + "mpd")); + setCurrentDirectory(AltosUIPreferences.logdir()); + } +} diff --git a/micropeak/MicroSerial.java b/micropeak/MicroSerial.java index a1a77a1d..15ef8582 100644 --- a/micropeak/MicroSerial.java +++ b/micropeak/MicroSerial.java @@ -27,6 +27,10 @@ public class MicroSerial extends InputStream { public int read() { int c = libaltos.altos_getchar(file, 0); + if (Thread.interrupted()) + return -1; + if (c == -1) + return -1; if (AltosUIPreferences.serial_debug) System.out.printf("%c", c); return c; @@ -39,12 +43,12 @@ public class MicroSerial extends InputStream { } } - public MicroSerial(MicroUSB usb) throws FileNotFoundException { - file = usb.open(); + public MicroSerial(AltosDevice device) throws FileNotFoundException { + file = device.open(); if (file == null) { - final String message = usb.getErrorString(); + final String message = device.getErrorString(); throw new FileNotFoundException(String.format("%s (%s)", - usb.toShortString(), + device.toShortString(), message)); } } diff --git a/micropeak/MicroUSB.java b/micropeak/MicroUSB.java index d48610fe..244f7bc0 100644 --- a/micropeak/MicroUSB.java +++ b/micropeak/MicroUSB.java @@ -16,10 +16,12 @@ */ package org.altusmetrum.micropeak; + import java.util.*; import libaltosJNI.*; +import org.altusmetrum.altosuilib.*; -public class MicroUSB extends altos_device { +public class MicroUSB extends altos_device implements AltosDevice { static boolean initialized = false; static boolean loaded_library = false; @@ -48,16 +50,16 @@ public class MicroUSB extends altos_device { String name = getName(); if (name == null) name = "Altus Metrum"; - return String.format("%-20.20s %4d %s", - name, getSerial(), getPath()); + return String.format("%-20.20s %s", + name, getPath()); } public String toShortString() { String name = getName(); if (name == null) name = "Altus Metrum"; - return String.format("%s %d %s", - name, getSerial(), getPath()); + return String.format("%s %s", + name, getPath()); } @@ -75,11 +77,15 @@ public class MicroUSB extends altos_device { private boolean isMicro() { if (getVendor() != 0x0403) return false; - if (getProduct() != 0x6001) + if (getProduct() != 0x6015) return false; return true; } + public boolean matchProduct(int product) { + return isMicro(); + } + static java.util.List list() { if (!load_library()) return null; @@ -92,6 +98,7 @@ public class MicroUSB extends altos_device { MicroUSB device = new MicroUSB(); if (libaltos.altos_list_next(list, device) == 0) break; + System.out.printf("Device %s\n", device.toString()); if (device.isMicro()) device_list.add(device); } -- cgit v1.2.3 From 982b272920fcb444fd399941cabe613d8ac7104b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 1 Jan 2013 16:57:31 -0800 Subject: micropeak: Fix chart colors Need to apply custom colors after setting the theme Signed-off-by: Keith Packard --- micropeak/MicroGraph.java | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'micropeak/MicroGraph.java') diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index b9b084f8..c5580634 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -72,9 +72,12 @@ public class MicroGraph implements AltosUnitsListener { MicroSeries speedSeries; MicroSeries accelSeries; - static final private Color red = new Color(194,31,31); - static final private Color green = new Color(31,194,31); - static final private Color blue = new Color(31,31,194); + static final private Color height_color = new Color(194,31,31); + static final private Color speed_color = new Color(31,194,31); + static final private Color accel_color = new Color(31,31,194); + static final private Color gridline_color = new Color(0, 0, 0); + static final private Color border_color = new Color(255, 255, 255); + static final private Color background_color = new Color(255, 255, 255); MicroData data; @@ -142,14 +145,22 @@ public class MicroGraph implements AltosUnitsListener { plot.setDomainPannable(true); plot.setRangePannable(true); - heightSeries = addSeries(0, "Height", AltosConvert.height.show_units(), red); - speedSeries = addSeries(1, "Speed", AltosConvert.speed.show_units(), green); - accelSeries = addSeries(2, "Acceleration", AltosConvert.accel.show_units(), blue); - chart = new JFreeChart("Flight", JFreeChart.DEFAULT_TITLE_FONT, plot, true); ChartUtilities.applyCurrentTheme(chart); + + heightSeries = addSeries(0, "Height", AltosConvert.height.show_units(), height_color); + speedSeries = addSeries(1, "Speed", AltosConvert.speed.show_units(), speed_color); + accelSeries = addSeries(2, "Acceleration", AltosConvert.accel.show_units(), accel_color); + + plot.setDomainGridlinePaint(gridline_color); + plot.setRangeGridlinePaint(gridline_color); + plot.setBackgroundPaint(background_color); + plot.setBackgroundAlpha((float) 1); + + chart.setBackgroundPaint(background_color); + chart.setBorderPaint(border_color); panel = new ChartPanel(chart); panel.setMouseWheelEnabled(true); panel.setPreferredSize(new java.awt.Dimension(800, 500)); -- cgit v1.2.3 From 93d640de65a1ecedfef89c96521c21632f96f372 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jan 2013 11:22:11 -0800 Subject: micropoint: Add MicroDataPoint This holds height/speed/accel data all in one place Signed-off-by: Keith Packard --- micropeak/Makefile.am | 1 + micropeak/MicroData.java | 77 +++++++------------------------------------ micropeak/MicroDataPoint.java | 39 ++++++++++++++++++++++ micropeak/MicroGraph.java | 9 +++-- micropeak/MicroStats.java | 68 +++++++++++++------------------------- 5 files changed, 78 insertions(+), 116 deletions(-) create mode 100644 micropeak/MicroDataPoint.java (limited to 'micropeak/MicroGraph.java') diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index 2dd9c69c..26431bd5 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -10,6 +10,7 @@ micropeakdir=$(datadir)/java micropeak_JAVA= \ MicroPeak.java \ MicroData.java \ + MicroDataPoint.java \ MicroDownload.java \ MicroFrame.java \ MicroGraph.java \ diff --git a/micropeak/MicroData.java b/micropeak/MicroData.java index 8ccd5fd8..2afd3cd7 100644 --- a/micropeak/MicroData.java +++ b/micropeak/MicroData.java @@ -22,7 +22,7 @@ import java.io.*; import java.util.*; import org.altusmetrum.AltosLib.*; -abstract class MicroIterator implements Iterator { +class MicroIterator implements Iterator { int i; MicroData data; @@ -30,6 +30,10 @@ abstract class MicroIterator implements Iterator { return i < data.pressures.length; } + public MicroDataPoint next() { + return new MicroDataPoint(data, i++); + } + public MicroIterator (MicroData data) { this.data = data; i = 0; @@ -39,66 +43,15 @@ abstract class MicroIterator implements Iterator { } } -class MicroHeightIterator extends MicroIterator { - public Double next() { - return data.height(i++); - } - - public MicroHeightIterator(MicroData data) { - super(data); - } -} - -class MicroHeightIterable implements Iterable { - MicroData data; - - public Iterator iterator() { - return new MicroHeightIterator(data); - } - - public MicroHeightIterable(MicroData data) { - this.data = data; - } -} - -class MicroSpeedIterator extends MicroIterator { - public Double next() { - return data.speed(i++); - } - public MicroSpeedIterator(MicroData data) { - super(data); - } -} - -class MicroSpeedIterable implements Iterable { - MicroData data; - - public Iterator iterator() { - return new MicroSpeedIterator(data); - } - - public MicroSpeedIterable(MicroData data) { - this.data = data; - } -} +class MicroIterable implements Iterable { -class MicroAccelIterator extends MicroIterator { - public Double next() { - return data.acceleration(i++); - } - public MicroAccelIterator(MicroData data) { - super(data); - } -} - -class MicroAccelIterable implements Iterable { MicroData data; - public Iterator iterator() { - return new MicroAccelIterator(data); + public Iterator iterator() { + return new MicroIterator(data); } - public MicroAccelIterable(MicroData data) { + public MicroIterable(MicroData data) { this.data = data; } } @@ -225,16 +178,8 @@ public class MicroData { return AltosConvert.pressure_to_altitude(pressures[i]); } - public Iterable heights() { - return new MicroHeightIterable(this); - } - - public Iterable speeds() { - return new MicroSpeedIterable(this); - } - - public Iterable accels() { - return new MicroAccelIterable(this); + public Iterable points() { + return new MicroIterable(this); } int fact(int n) { diff --git a/micropeak/MicroDataPoint.java b/micropeak/MicroDataPoint.java new file mode 100644 index 00000000..3fd1e641 --- /dev/null +++ b/micropeak/MicroDataPoint.java @@ -0,0 +1,39 @@ +/* + * Copyright © 2012 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 org.altusmetrum.micropeak; + +public class MicroDataPoint { + public double time; + public double height; + public double speed; + public double accel; + + public MicroDataPoint (double height, double speed, double accel, double time) { + this.height = height; + this.speed = speed; + this.accel = accel; + this.time = time; + } + + public MicroDataPoint(MicroData data, int i) { + this(data.height(i), + data.speed(i), + data.acceleration(i), + data.time(i)); + } +} \ No newline at end of file diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index c5580634..8330a67b 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -106,11 +106,10 @@ public class MicroGraph implements AltosUnitsListener { heightSeries.clear(); speedSeries.clear(); accelSeries.clear(); - for (int i = 0; i < data.pressures.length; i++) { - double x = data.time(i); - heightSeries.add(x, AltosConvert.height.value(data.height(i))); - speedSeries.add(x, AltosConvert.speed.value(data.speed(i))); - accelSeries.add(x, AltosConvert.accel.value(data.acceleration(i))); + for (MicroDataPoint point : data.points()) { + heightSeries.add(point.time, AltosConvert.height.value(point.height)); + speedSeries.add(point.time, AltosConvert.speed.value(point.speed)); + accelSeries.add(point.time, AltosConvert.accel.value(point.accel)); } } diff --git a/micropeak/MicroStats.java b/micropeak/MicroStats.java index 6ae8a2b2..056fac7d 100644 --- a/micropeak/MicroStats.java +++ b/micropeak/MicroStats.java @@ -39,25 +39,21 @@ public class MicroStats { void find_landing() { landed_height = 0; - int t = 0; - for (double height : data.heights()) { - landed_height = height; - t++; + for (MicroDataPoint point : data.points()) { + landed_height = point.height; + landed_time = point.time; } - landed_time = data.time(t); - t = 0; boolean above = false; - for (double height : data.heights()) { - if (height > landed_height + 10) { + for (MicroDataPoint point : data.points()) { + if (point.height > landed_height + 10) { above = true; } else { - if (above && height < landed_height + 2) { + if (above && point.height < landed_height + 2) { above = false; - landed_time = data.time(t); + landed_time = point.time; } } - t++; } } @@ -65,13 +61,11 @@ public class MicroStats { apogee_height = 0; apogee_time = 0; - int t = 0; - for (double height : data.heights()) { - if (height > apogee_height) { - apogee_height = height; - apogee_time = data.time(t); + for (MicroDataPoint point : data.points()) { + if (point.height > apogee_height) { + apogee_height = point.height; + apogee_time = point.time; } - t++; } } @@ -79,47 +73,31 @@ public class MicroStats { coast_height = 0; coast_time = 0; - int t = 0; - for (double accel : data.accels()) { - if (accel < -9.8) + for (MicroDataPoint point : data.points()) { + if (point.accel < -9.8) break; - t++; - } - coast_time = data.time(t); - - int coast_t = t; - t = 0; - for (double height : data.heights()) { - if (t >= coast_t) { - coast_height = height; - break; - } - t++; + coast_time = point.time; + coast_height = point.height; } } void find_max_speed() { max_speed = 0; - int t = 0; - for (double speed : data.speeds()) { - if (data.time(t) > apogee_time) + for (MicroDataPoint point : data.points()) { + if (point.time > apogee_time) break; - if (speed > max_speed) - max_speed = speed; - t++; + if (point.speed > max_speed) + max_speed = point.speed; } } void find_max_accel() { max_accel = 0; - - int t = 0; - for (double accel : data.accels()) { - if (data.time(t) > apogee_time) + for (MicroDataPoint point : data.points()) { + if (point.time > apogee_time) break; - if (accel > max_accel) - max_accel = accel; - t++; + if (point.accel > max_accel) + max_accel = point.accel; } } -- cgit v1.2.3 From 9e4c5b0a6ed3594cff6ab71398c172daa7c67177 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jan 2013 16:19:33 -0800 Subject: micropeak: Use JTextArea instead of TextArea Looks nicer and doesn't appear to have the same weird clipping problem Signed-off-by: Keith Packard --- micropeak/MicroGraph.java | 23 ++++++++++++----------- micropeak/MicroPeak.java | 3 ++- micropeak/MicroRaw.java | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) (limited to 'micropeak/MicroGraph.java') diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index 8330a67b..d2e86f9f 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -106,10 +106,12 @@ public class MicroGraph implements AltosUnitsListener { heightSeries.clear(); speedSeries.clear(); accelSeries.clear(); - for (MicroDataPoint point : data.points()) { - heightSeries.add(point.time, AltosConvert.height.value(point.height)); - speedSeries.add(point.time, AltosConvert.speed.value(point.speed)); - accelSeries.add(point.time, AltosConvert.accel.value(point.accel)); + if (data != null) { + for (MicroDataPoint point : data.points()) { + heightSeries.add(point.time, AltosConvert.height.value(point.height)); + speedSeries.add(point.time, AltosConvert.speed.value(point.speed)); + accelSeries.add(point.time, AltosConvert.accel.value(point.accel)); + } } } @@ -119,17 +121,16 @@ public class MicroGraph implements AltosUnitsListener { public void setData (MicroData data) { this.data = data; - chart.setTitle(data.name); + if (data != null) + setName(data.name); resetData(); } public void units_changed(boolean imperial_units) { - if (data != null) { - heightSeries.set_units(AltosConvert.height.show_units()); - speedSeries.set_units(AltosConvert.speed.show_units()); - accelSeries.set_units(AltosConvert.accel.show_units()); - resetData(); - } + heightSeries.set_units(AltosConvert.height.show_units()); + speedSeries.set_units(AltosConvert.speed.show_units()); + accelSeries.set_units(AltosConvert.accel.show_units()); + resetData(); } public MicroGraph() { diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index 290511e7..d4252fa9 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -214,7 +214,8 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene raw = new MicroRaw(); pane.add(graph.panel, "Graph"); pane.add(stats, "Statistics"); - pane.add(raw, "Raw Data"); + JScrollPane scroll = new JScrollPane(raw); + pane.add(scroll, "Raw Data"); pane.doLayout(); pane.validate(); container.add(pane); diff --git a/micropeak/MicroRaw.java b/micropeak/MicroRaw.java index 6b006f32..f5bea76f 100644 --- a/micropeak/MicroRaw.java +++ b/micropeak/MicroRaw.java @@ -22,7 +22,7 @@ import javax.swing.*; import org.altusmetrum.AltosLib.*; import org.altusmetrum.altosuilib.*; -public class MicroRaw extends TextArea { +public class MicroRaw extends JTextArea { public void setData(MicroData data) { setRows(data.pressures.length); -- cgit v1.2.3 From 722dc277dee915dcd09d3d65c0ee19173b114ef7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jan 2013 16:30:44 -0800 Subject: micropeak: Change graph tooltip units on the fly Make sure the tooltips show the right units when they change Signed-off-by: Keith Packard --- micropeak/MicroGraph.java | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'micropeak/MicroGraph.java') diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index d2e86f9f..84320be3 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -39,15 +39,19 @@ class MicroSeries extends XYSeries { String label; String units; Color color; + XYItemRenderer renderer; - String label() { - return String.format("%s (%s)", label, units); - } - void set_units(String units) { this.units = units; - axis.setLabel(label()); + axis.setLabel(String.format("%s (%s)", label, units)); + + StandardXYToolTipGenerator ttg; + + ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", units), + new java.text.DecimalFormat("0.00"), + new java.text.DecimalFormat("0.00")); + renderer.setBaseToolTipGenerator(ttg); } public MicroSeries (String label, String units, Color color) { @@ -56,9 +60,13 @@ class MicroSeries extends XYSeries { this.units = units; this.color = color; - axis = new NumberAxis(label()); + axis = new NumberAxis(); axis.setLabelPaint(color); axis.setTickLabelPaint(color); + + renderer = new XYLineAndShapeRenderer(true, false); + renderer.setSeriesPaint(0, color); + set_units(units); } } @@ -88,16 +96,11 @@ public class MicroGraph implements AltosUnitsListener { private MicroSeries addSeries(int index, String label, String units, Color color) { MicroSeries series = new MicroSeries(label, units, color); XYSeriesCollection dataset = new XYSeriesCollection(series); - XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false); - renderer.setSeriesPaint(0, color); - renderer.setPlot(plot); - renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", units), - new java.text.DecimalFormat("0.00"), - new java.text.DecimalFormat("0.00"))); + series.renderer.setPlot(plot); plot.setRangeAxis(index, series.axis); plot.setDataset(index, dataset); - plot.setRenderer(index, renderer); + plot.setRenderer(index, series.renderer); plot.mapDatasetToRangeAxis(index, index); return series; } -- cgit v1.2.3 From 98e74150040e444ed6480ef3d107caa54c205ef9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jan 2013 21:38:15 -0800 Subject: micropeak: Demonstrate how to hide various parts of the graph This just shows how to disable a series and axis; it's not used here. Signed-off-by: Keith Packard --- micropeak/MicroGraph.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'micropeak/MicroGraph.java') diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index 84320be3..5aa127bb 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -54,6 +54,11 @@ class MicroSeries extends XYSeries { renderer.setBaseToolTipGenerator(ttg); } + void set_enable(boolean enable) { + renderer.setSeriesVisible(0, enable); + axis.setVisible(enable); + } + public MicroSeries (String label, String units, Color color) { super(label); this.label = label; @@ -116,6 +121,7 @@ public class MicroGraph implements AltosUnitsListener { accelSeries.add(point.time, AltosConvert.accel.value(point.accel)); } } +// accelSeries.set_enable(false); } public void setName (String name) { -- cgit v1.2.3