Start adding java-based UI
authorKeith Packard <keithp@keithp.com>
Wed, 31 Mar 2010 20:49:54 +0000 (13:49 -0700)
committerKeith Packard <keithp@keithp.com>
Wed, 31 Mar 2010 20:49:54 +0000 (13:49 -0700)
ao-tools/altosui/AltosSerial.java [new file with mode: 0644]
ao-tools/altosui/AltosSerialMonitor.java [new file with mode: 0644]
ao-tools/altosui/AltosUI.java [new file with mode: 0644]
ao-tools/altosui/Makefile [new file with mode: 0644]

diff --git a/ao-tools/altosui/AltosSerial.java b/ao-tools/altosui/AltosSerial.java
new file mode 100644 (file)
index 0000000..82663ea
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright © 2010 Keith Packard <keithp@keithp.com>
+ *
+ * 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.
+ */
+
+/*
+ * Deal with TeleDongle on a serial port
+ */
+
+package altosui;
+
+import java.lang.String;
+import java.lang.System;
+import java.lang.Character;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.lang.InterruptedException;
+import java.util.LinkedList;
+import altosui.AltosSerialMonitor;
+import java.util.Iterator;
+
+/*
+ * This class reads from the serial port and places each received
+ * line in a queue. Dealing with that queue is left up to other
+ * threads.
+ */
+class AltosSerialReader implements Runnable {
+       FileInputStream serial_in;
+       LinkedBlockingQueue<String> monitor_queue;
+       LinkedBlockingQueue<String> reply_queue;
+       String line;
+
+       public void run () {
+               int c;
+
+               try {
+                       while ((c = serial_in.read()) != -1) {
+                               if (c == '\r')
+                                       continue;
+                               synchronized(this) {
+                                       if (c == '\n') {
+                                               if (line != "") {
+                                                       if (line.startsWith("VERSION"))
+                                                               monitor_queue.put(line);
+                                                       else
+                                                               reply_queue.put(line);
+                                                       line = "";
+                                               }
+                                       } else {
+                                               line = line + (char) c;
+                                       }
+                               }
+                       }
+               } catch (IOException e) {
+               } catch (InterruptedException e) {
+               }
+       }
+
+       public String get_telem() {
+               try {
+                       return monitor_queue.take();
+               } catch (InterruptedException e) {
+                       return "";
+               }
+       }
+
+       public String get_reply() {
+               try {
+                       return reply_queue.take();
+               } catch (InterruptedException e) {
+                       return "";
+               }
+       }
+
+       public void flush () {
+               synchronized(this) {
+                       if (!"VERSION".startsWith(line) && !line.startsWith("VERSION"))
+                               line = "";
+                       reply_queue.clear();
+               }
+       }
+       public AltosSerialReader (FileInputStream in) {
+               serial_in = in;
+               monitor_queue = new LinkedBlockingQueue<String> ();
+               reply_queue = new LinkedBlockingQueue<String> ();
+               line = "";
+       }
+
+}
+
+public class AltosSerial implements Runnable {
+       FileInputStream serial_in = null;
+       FileOutputStream serial_out = null;
+       AltosSerialReader reader;
+       LinkedList<AltosSerialMonitor> callbacks;
+
+       public void run() {
+               for (;;) {
+                       String s = reader.get_reply();
+                       synchronized(callbacks) {
+                               Iterator<AltosSerialMonitor> i = callbacks.iterator();
+                               while (i.hasNext()) {
+                                       i.next().data(s);
+                               }
+                       }
+               }
+       }
+
+       public void start () {
+               try {
+                       serial_out.write('?');
+                       serial_out.write('\r');
+               } catch (IOException e) {
+               }
+               (new Thread(reader)).start();
+               (new Thread(this)).start();
+       }
+
+       public void monitor(AltosSerialMonitor monitor) {
+               synchronized(callbacks) {
+                       callbacks.add(monitor);
+               }
+       }
+
+       public AltosSerial(String serial_name) {
+               try {
+                       serial_in = new FileInputStream(serial_name);
+                       serial_out = new FileOutputStream(serial_name);
+                       reader = new AltosSerialReader(serial_in);
+                       callbacks = new LinkedList<AltosSerialMonitor>();
+               } catch (FileNotFoundException e) {
+               }
+       }
+}
diff --git a/ao-tools/altosui/AltosSerialMonitor.java b/ao-tools/altosui/AltosSerialMonitor.java
new file mode 100644 (file)
index 0000000..ad0e929
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright © 2010 Keith Packard <keithp@keithp.com>
+ *
+ * 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;
+
+public interface AltosSerialMonitor {
+       void data(String data);
+}
diff --git a/ao-tools/altosui/AltosUI.java b/ao-tools/altosui/AltosUI.java
new file mode 100644 (file)
index 0000000..b731725
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright © 2010 Keith Packard <keithp@keithp.com>
+ *
+ * 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.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.KeyStroke;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.DefaultTableCellRenderer;
+import altosui.AltosSerial;
+import altosui.AltosSerialMonitor;
+
+class AltosUIMonitor implements AltosSerialMonitor {
+       public void data(String data) {
+               System.out.println(data);
+       }
+}
+
+public class AltosUI extends JFrame {
+       private int channel = -1;
+
+       private JTable flightStatus;
+       private JTable flightInfo;
+       private AltosSerial serialLine;
+
+       public AltosUI() {
+
+               String[] statusNames = { "Height (m)", "State", "RSSI (dBm)", "Speed (m/s)" };
+               Object[][] statusData = { { "0", "pad", "-50", "0" } };
+
+               flightStatus = new JTable(statusData, statusNames);
+
+               flightStatus.setShowGrid(false);
+
+               this.add(flightStatus);
+
+               setTitle("AltOS");
+
+               createMenu();
+
+               serialLine = new AltosSerial("/dev/ttyACM0");
+               serialLine.monitor(new AltosUIMonitor());
+               serialLine.start();
+               Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
+               size.width = size.width*9/10;
+               size.height = size.height*9/10;
+               this.setSize(size);
+               this.validate();
+               setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+               addWindowListener(new WindowAdapter() {
+                       @Override
+                       public void windowClosing(WindowEvent e) {
+                               System.exit(0);
+                       }
+               });
+       }
+
+       private void createMenu() {
+               JMenuBar menubar = new JMenuBar();
+               JMenu menu;
+               JMenuItem item;
+               JRadioButtonMenuItem radioitem;
+
+               // File menu
+               {
+                       menu = new JMenu("File");
+                       menu.setMnemonic(KeyEvent.VK_F);
+                       menubar.add(menu);
+
+                       item = new JMenuItem("Quit",KeyEvent.VK_Q);
+                       item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
+                                                                  ActionEvent.CTRL_MASK));
+                       item.addActionListener(new ActionListener() {
+                                       public void actionPerformed(ActionEvent e) {
+                                               System.exit(0);
+                                       }
+                               });
+                       menu.add(item);
+               }
+
+               // Device menu
+               {
+                       menu = new JMenu("Device");
+                       menu.setMnemonic(KeyEvent.VK_D);
+                       menubar.add(menu);
+
+                       item = new JMenuItem("Connect to Device",KeyEvent.VK_C);
+                       item.addActionListener(new ActionListener() {
+                                       public void actionPerformed(ActionEvent e) {
+                                       }
+                               });
+                       menu.add(item);
+
+                       item = new JMenuItem("Disconnect from Device",KeyEvent.VK_D);
+                       item.addActionListener(new ActionListener() {
+                                       public void actionPerformed(ActionEvent e) {
+                                       }
+                               });
+                       menu.add(item);
+
+                       menu.addSeparator();
+
+                       item = new JMenuItem("Save Flight Data",KeyEvent.VK_S);
+                       item.addActionListener(new ActionListener() {
+                                       public void actionPerformed(ActionEvent e) {
+                                       }
+                               });
+                       menu.add(item);
+
+                       item = new JMenuItem("Replay",KeyEvent.VK_R);
+                       item.addActionListener(new ActionListener() {
+                                       public void actionPerformed(ActionEvent e) {
+                                       }
+                               });
+                       menu.add(item);
+               }
+               // Log menu
+               {
+                       menu = new JMenu("Log");
+                       menu.setMnemonic(KeyEvent.VK_L);
+                       menubar.add(menu);
+
+                       item = new JMenuItem("New Log",KeyEvent.VK_N);
+                       item.addActionListener(new ActionListener() {
+                                       public void actionPerformed(ActionEvent e) {
+                                       }
+                               });
+                       menu.add(item);
+
+                       item = new JMenuItem("Configure Log",KeyEvent.VK_C);
+                       item.addActionListener(new ActionListener() {
+                                       public void actionPerformed(ActionEvent e) {
+                                       }
+                               });
+                       menu.add(item);
+               }
+               // Voice menu
+               {
+                       menu = new JMenu("Voice", true);
+                       menu.setMnemonic(KeyEvent.VK_V);
+                       menubar.add(menu);
+
+                       radioitem = new JRadioButtonMenuItem("Enable Voice");
+                       radioitem.addActionListener(new ActionListener() {
+                                       public void actionPerformed(ActionEvent e) {
+                                       }
+                               });
+                       menu.add(radioitem);
+               }
+
+               // Channel menu
+               {
+                       menu = new JMenu("Channel", true);
+                       menu.setMnemonic(KeyEvent.VK_C);
+                       menubar.add(menu);
+
+                       for (int c = 0; c <= 9; c++) {
+                               radioitem = new JRadioButtonMenuItem("Channel " + c + " (" +
+                                                               (434.550 + c * .1) + ")",
+                                                               c == 0);
+                               radioitem.addActionListener(new ActionListener() {
+                                               public void actionPerformed(ActionEvent e) {
+                                               }
+                                       });
+                               menu.add(radioitem);
+                       }
+               }
+
+               this.setJMenuBar(menubar);
+
+       }
+       public static void main(final String[] args) {
+               AltosUI altosui = new AltosUI();
+               altosui.setVisible(true);
+       }
+}
\ No newline at end of file
diff --git a/ao-tools/altosui/Makefile b/ao-tools/altosui/Makefile
new file mode 100644 (file)
index 0000000..cb422df
--- /dev/null
@@ -0,0 +1,13 @@
+.SUFFIXES: .java .class
+
+CLASSPATH=..
+CLASSFILES=AltosSerialMonitor.class AltosSerial.class AltosUI.class
+JAVAFLAGS=-Xlint:unchecked
+
+all: $(CLASSFILES)
+
+.java.class:
+       javac -cp $(CLASSPATH) $(JAVAFLAGS) $*.java
+
+clean:
+       rm -f *.class
\ No newline at end of file