From a258042deb398d5274b76ab6b1e8c55e661e829c Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Sat, 13 Jun 2009 20:26:21 +0000 Subject: [PATCH] Adding a basic serial monitor. --- app/src/processing/app/Editor.java | 23 ++++ app/src/processing/app/EditorToolbar.java | 11 +- app/src/processing/app/Serial.java | 11 ++ app/src/processing/app/SerialMonitor.java | 138 ++++++++++++++++++++++ 4 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 app/src/processing/app/SerialMonitor.java diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 44ce92264..5ac200677 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -99,6 +99,9 @@ public class Editor extends JFrame implements RunnerListener { static JMenu serialMenu; static SerialMenuListener serialMenuListener; + static SerialMonitor serialMonitor; + + static Editor activeEditor; EditorHeader header; EditorStatus status; @@ -159,6 +162,8 @@ public class Editor extends JFrame implements RunnerListener { // When bringing a window to front, let the Base know addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { + activeEditor = Editor.this; + base.handleActivated(Editor.this); // re-add the sub-menus that are shared by all windows @@ -172,6 +177,8 @@ public class Editor extends JFrame implements RunnerListener { //PdeKeywords keywords = new PdeKeywords(); //sketchbook = new Sketchbook(this); + + if (serialMonitor == null) serialMonitor = new SerialMonitor(); buildMenuBar(); @@ -849,6 +856,7 @@ public class Editor extends JFrame implements RunnerListener { //System.out.println(item.getLabel()); Preferences.set("serial.port", name); //System.out.println("set to " + get("serial.port")); + activeEditor.handleSerial(false); } /* @@ -2204,6 +2212,21 @@ public class Editor extends JFrame implements RunnerListener { } return true; } + + + public void handleSerial(boolean showSerialMonitor) { + statusEmpty(); + + if (!showSerialMonitor && !serialMonitor.isVisible()) return; + + try { + serialMonitor.openSerialPort(Preferences.get("serial.port")); + serialMonitor.setVisible(true); + } catch (SerialException e) { + statusError(e.getMessage()); + serialMonitor.setVisible(false); + } + } protected void handleBurnBootloader(final String programmer) { diff --git a/app/src/processing/app/EditorToolbar.java b/app/src/processing/app/EditorToolbar.java index 96a82bcb2..bc8c10bf3 100644 --- a/app/src/processing/app/EditorToolbar.java +++ b/app/src/processing/app/EditorToolbar.java @@ -35,7 +35,7 @@ import javax.swing.event.*; public class EditorToolbar extends JComponent implements MouseInputListener { static final String title[] = { - "Verify", "Stop", "New", "Open", "Save", "Upload" + "Verify", "Stop", "New", "Open", "Save", "Upload", "Serial Monitor" }; static final int BUTTON_COUNT = title.length; @@ -53,6 +53,8 @@ public class EditorToolbar extends JComponent implements MouseInputListener { static final int OPEN = 3; static final int SAVE = 4; static final int EXPORT = 5; + + static final int SERIAL = 6; static final int INACTIVE = 0; static final int ROLLOVER = 1; @@ -108,6 +110,7 @@ public class EditorToolbar extends JComponent implements MouseInputListener { which[buttonCount++] = OPEN; which[buttonCount++] = SAVE; which[buttonCount++] = EXPORT; + which[buttonCount++] = SERIAL; currentRollover = -1; @@ -170,7 +173,7 @@ public class EditorToolbar extends JComponent implements MouseInputListener { int offsetX = 3; for (int i = 0; i < buttonCount; i++) { x1[i] = offsetX; - if (i == 2) x1[i] += BUTTON_GAP; + if (i == 2 || i == 6) x1[i] += BUTTON_GAP; x2[i] = x1[i] + BUTTON_WIDTH; offsetX = x2[i]; } @@ -339,6 +342,10 @@ public class EditorToolbar extends JComponent implements MouseInputListener { case EXPORT: editor.handleExport(); break; + + case SERIAL: + editor.handleSerial(true); + break; } } diff --git a/app/src/processing/app/Serial.java b/app/src/processing/app/Serial.java index 0baab4546..53f206544 100755 --- a/app/src/processing/app/Serial.java +++ b/app/src/processing/app/Serial.java @@ -25,6 +25,8 @@ package processing.app; //import processing.core.*; +import processing.app.debug.MessageConsumer; + import gnu.io.*; import java.io.*; @@ -58,6 +60,8 @@ public class Serial implements SerialPortEventListener { byte buffer[] = new byte[32768]; int bufferIndex; int bufferLast; + + MessageConsumer consumer; public Serial(boolean monitor) throws SerialException { this(Preferences.get("serial.port"), @@ -189,6 +193,11 @@ public class Serial implements SerialPortEventListener { } port = null; } + + + public void addListener(MessageConsumer consumer) { + this.consumer = consumer; + } synchronized public void serialEvent(SerialPortEvent serialEvent) { @@ -217,6 +226,8 @@ public class Serial implements SerialPortEventListener { //buffer[bufferLast++] = (byte) input.read(); if(monitor == true) System.out.print((char) input.read()); + if (this.consumer != null) + this.consumer.message("" + (char) input.read()); /* System.err.println(input.available() + " " + diff --git a/app/src/processing/app/SerialMonitor.java b/app/src/processing/app/SerialMonitor.java new file mode 100644 index 000000000..94882b85c --- /dev/null +++ b/app/src/processing/app/SerialMonitor.java @@ -0,0 +1,138 @@ +/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + 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; either version 2 of the License, or + (at your option) any later version. + + 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 processing.app; + +import processing.app.debug.MessageConsumer; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.event.*; + +public class SerialMonitor extends JFrame implements MessageConsumer { + private Serial serial; + private String port; + private JTextArea textArea; + private JTextField textField; + private JButton sendButton; + private JComboBox serialRates; + + public SerialMonitor() { + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + closeSerialPort(); + } + }); + + getContentPane().setLayout(new BorderLayout()); + + Font font = Theme.getFont("console.font"); + + textArea = new JTextArea(16, 40); + textArea.setEditable(false); + textArea.setFont(font); + + getContentPane().add(new JScrollPane(textArea), BorderLayout.CENTER); + + JPanel pane = new JPanel(new BorderLayout(4, 0)); + pane.setBorder(new EmptyBorder(4, 4, 4, 4)); + + textField = new JTextField(40); + textField.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + send(textField.getText()); + textField.setText(""); + }}); + + sendButton = new JButton("Send"); + sendButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + send(textField.getText()); + textField.setText(""); + }}); + + pane.add(textField, BorderLayout.CENTER); + pane.add(sendButton, BorderLayout.EAST); + + getContentPane().add(pane, BorderLayout.NORTH); + + pane = new JPanel(new FlowLayout(FlowLayout.TRAILING, 4, 4)); + + String[] serialRateStrings = { + "300","1200","2400","4800","9600","14400", + "19200","28800","38400","57600","115200" + }; + + serialRates = new JComboBox(); + for (int i = 0; i < serialRateStrings.length; i++) + serialRates.addItem(serialRateStrings[i] + " baud"); + + serialRates.setSelectedItem(Preferences.get("serial.debug_rate") + " baud"); + serialRates.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String wholeString = (String) serialRates.getSelectedItem(); + String rateString = wholeString.substring(0, wholeString.indexOf(' ')); + int rate = Integer.parseInt(rateString); + Preferences.set("serial.debug_rate", rateString); + closeSerialPort(); + Editor.activeEditor.handleSerial(true); + }}); + + pane.add(serialRates); + + getContentPane().add(pane, BorderLayout.SOUTH); + + pack(); + } + + private void send(String s) { + if (serial != null) + serial.write(s); + } + + public void openSerialPort(String port) throws SerialException { + if (port.equals(this.port)) + return; + + closeSerialPort(); + + serial = new Serial(port); + serial.addListener(this); + setTitle(port); + this.port = port; + } + + public void closeSerialPort() { + if (serial != null) { + setTitle("closing..."); + textArea.setText(""); + serial.dispose(); + serial = null; + port = null; + } + } + + public void message(final String s) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + textArea.append(s); + }}); + } +} \ No newline at end of file