blob: 6eebf539ed2f644a4d935bd0b7d9459b59d06ac9 [file] [log] [blame]
/* -*- 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 processing.core.*;
import static processing.app.I18n._;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class SerialMonitor extends JFrame implements MessageConsumer {
private Serial serial;
private String port;
private JTextArea textArea;
private JScrollPane scrollPane;
private JTextField textField;
private JButton sendButton;
private JCheckBox autoscrollBox;
private JComboBox lineEndings;
private JComboBox serialRates;
private int serialRate;
public SerialMonitor(String port) {
super(port);
this.port = port;
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
closeSerialPort();
}
});
// obvious, no?
KeyStroke wc = Editor.WINDOW_CLOSE_KEYSTROKE;
getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(wc, "close");
getRootPane().getActionMap().put("close", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
closeSerialPort();
setVisible(false);
}});
getContentPane().setLayout(new BorderLayout());
Font consoleFont = Theme.getFont("console.font");
Font editorFont = Preferences.getFont("editor.font");
Font font = new Font(consoleFont.getName(), consoleFont.getStyle(), editorFont.getSize());
textArea = new JTextArea(16, 40);
textArea.setEditable(false);
textArea.setFont(font);
// don't automatically update the caret. that way we can manually decide
// whether or not to do so based on the autoscroll checkbox.
((DefaultCaret)textArea.getCaret()).setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
scrollPane = new JScrollPane(textArea);
getContentPane().add(scrollPane, BorderLayout.CENTER);
JPanel pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));
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);
pane.add(Box.createRigidArea(new Dimension(4, 0)));
pane.add(sendButton);
getContentPane().add(pane, BorderLayout.NORTH);
pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));
pane.setBorder(new EmptyBorder(4, 4, 4, 4));
autoscrollBox = new JCheckBox(_("Autoscroll"), true);
lineEndings = new JComboBox(new String[] { _("No line ending"), _("Newline"), _("Carriage return"), _("Both NL & CR") });
lineEndings.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
Preferences.setInteger("serial.line_ending", lineEndings.getSelectedIndex());
}
});
if (Preferences.get("serial.line_ending") != null) {
lineEndings.setSelectedIndex(Preferences.getInteger("serial.line_ending"));
}
lineEndings.setMaximumSize(lineEndings.getMinimumSize());
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"));
serialRate = Preferences.getInteger("serial.debug_rate");
serialRates.setSelectedItem(serialRate + _(" baud"));
serialRates.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String wholeString = (String) serialRates.getSelectedItem();
String rateString = wholeString.substring(0, wholeString.indexOf(' '));
serialRate = Integer.parseInt(rateString);
Preferences.set("serial.debug_rate", rateString);
closeSerialPort();
try {
openSerialPort();
} catch (SerialException e) {
System.err.println(e);
}
}});
serialRates.setMaximumSize(serialRates.getMinimumSize());
pane.add(autoscrollBox);
pane.add(Box.createHorizontalGlue());
pane.add(lineEndings);
pane.add(Box.createRigidArea(new Dimension(8, 0)));
pane.add(serialRates);
getContentPane().add(pane, BorderLayout.SOUTH);
pack();
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
if (Preferences.get("last.screen.height") != null) {
// if screen size has changed, the window coordinates no longer
// make sense, so don't use them unless they're identical
int screenW = Preferences.getInteger("last.screen.width");
int screenH = Preferences.getInteger("last.screen.height");
if ((screen.width == screenW) && (screen.height == screenH)) {
String locationStr = Preferences.get("last.serial.location");
if (locationStr != null) {
int[] location = PApplet.parseInt(PApplet.split(locationStr, ','));
setPlacement(location);
}
}
}
}
protected void setPlacement(int[] location) {
setBounds(location[0], location[1], location[2], location[3]);
}
protected int[] getPlacement() {
int[] location = new int[4];
// Get the dimensions of the Frame
Rectangle bounds = getBounds();
location[0] = bounds.x;
location[1] = bounds.y;
location[2] = bounds.width;
location[3] = bounds.height;
return location;
}
private void send(String s) {
if (serial != null) {
switch (lineEndings.getSelectedIndex()) {
case 1: s += "\n"; break;
case 2: s += "\r"; break;
case 3: s += "\r\n"; break;
}
serial.write(s);
}
}
public void openSerialPort() throws SerialException {
if (serial != null) return;
serial = new Serial(port, serialRate);
serial.addListener(this);
}
public void closeSerialPort() {
if (serial != null) {
int[] location = getPlacement();
String locationStr = PApplet.join(PApplet.str(location), ",");
Preferences.set("last.serial.location", locationStr);
textArea.setText("");
serial.dispose();
serial = null;
}
}
public void message(final String s) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(s);
if (autoscrollBox.isSelected()) {
textArea.setCaretPosition(textArea.getDocument().getLength());
}
}});
}
}