mirror of
https://github.com/arduino/Arduino.git
synced 2025-03-15 12:29:26 +01:00
Serial.dispose() throws IOException
SerialException extends IOException SerialMonitor is now a subclass of a generic AbstractMonitor; introducing NetworkMonitor UploaderFactory becomes PerPortObjectFactory and can build AbstractMonitors favouring IOException over SerialException collecting constants in Constants made MessageSiphon stoppable
This commit is contained in:
parent
556c6ea5c1
commit
376b0f8b3f
183
app/src/processing/app/AbstractMonitor.java
Normal file
183
app/src/processing/app/AbstractMonitor.java
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
package processing.app;
|
||||||
|
|
||||||
|
import processing.app.debug.MessageConsumer;
|
||||||
|
import processing.core.PApplet;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.text.DefaultCaret;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static processing.app.I18n._;
|
||||||
|
|
||||||
|
public abstract class AbstractMonitor extends JFrame implements MessageConsumer {
|
||||||
|
|
||||||
|
protected JTextArea textArea;
|
||||||
|
protected JScrollPane scrollPane;
|
||||||
|
protected JTextField textField;
|
||||||
|
protected JButton sendButton;
|
||||||
|
protected JCheckBox autoscrollBox;
|
||||||
|
protected JComboBox lineEndings;
|
||||||
|
protected JComboBox serialRates;
|
||||||
|
protected int serialRate;
|
||||||
|
|
||||||
|
public AbstractMonitor(String title) {
|
||||||
|
super(title);
|
||||||
|
|
||||||
|
addWindowListener(new WindowAdapter() {
|
||||||
|
public void windowClosing(WindowEvent event) {
|
||||||
|
try {
|
||||||
|
close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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 event) {
|
||||||
|
try {
|
||||||
|
close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
sendButton = new JButton(_("Send"));
|
||||||
|
|
||||||
|
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",
|
||||||
|
"19200", "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.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSerialRateChange(ActionListener listener) {
|
||||||
|
serialRates.addActionListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSendCommand(ActionListener listener) {
|
||||||
|
textField.addActionListener(listener);
|
||||||
|
sendButton.addActionListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void message(final String s) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
textArea.append(s);
|
||||||
|
if (autoscrollBox.isSelected()) {
|
||||||
|
textArea.setCaretPosition(textArea.getDocument().getLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void open() throws IOException;
|
||||||
|
|
||||||
|
public abstract void close() throws IOException;
|
||||||
|
}
|
@ -936,7 +936,11 @@ public class Base {
|
|||||||
|
|
||||||
// This will store the sketch count as zero
|
// This will store the sketch count as zero
|
||||||
editors.remove(editor);
|
editors.remove(editor);
|
||||||
Editor.serialMonitor.closeSerialPort();
|
try {
|
||||||
|
Editor.serialMonitor.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
storeSketches();
|
storeSketches();
|
||||||
|
|
||||||
// Save out the current prefs state
|
// Save out the current prefs state
|
||||||
@ -974,7 +978,11 @@ public class Base {
|
|||||||
// If quit is canceled, this will be replaced anyway
|
// If quit is canceled, this will be replaced anyway
|
||||||
// by a later handleQuit() that is not canceled.
|
// by a later handleQuit() that is not canceled.
|
||||||
storeSketches();
|
storeSketches();
|
||||||
Editor.serialMonitor.closeSerialPort();
|
try {
|
||||||
|
Editor.serialMonitor.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
if (handleQuitEach()) {
|
if (handleQuitEach()) {
|
||||||
// make sure running sketches close before quitting
|
// make sure running sketches close before quitting
|
||||||
|
9
app/src/processing/app/Constants.java
Normal file
9
app/src/processing/app/Constants.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package processing.app;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Constants {
|
||||||
|
|
||||||
|
public static final Pattern IPV4_ADDRESS = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
|
||||||
|
|
||||||
|
}
|
@ -99,7 +99,7 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
static List<JMenu> boardsMenus;
|
static List<JMenu> boardsMenus;
|
||||||
static JMenu serialMenu;
|
static JMenu serialMenu;
|
||||||
|
|
||||||
static SerialMonitor serialMonitor;
|
static AbstractMonitor serialMonitor;
|
||||||
|
|
||||||
EditorHeader header;
|
EditorHeader header;
|
||||||
EditorStatus status;
|
EditorStatus status;
|
||||||
@ -204,7 +204,7 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
//sketchbook = new Sketchbook(this);
|
//sketchbook = new Sketchbook(this);
|
||||||
|
|
||||||
if (serialMonitor == null) {
|
if (serialMonitor == null) {
|
||||||
serialMonitor = new SerialMonitor(Preferences.get("serial.port"));
|
serialMonitor = new PerPortObjectFactory().newMonitor(Preferences.get("serial.port"), base);
|
||||||
serialMonitor.setIconImage(getIconImage());
|
serialMonitor.setIconImage(getIconImage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -964,9 +964,13 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
Preferences.set("serial.port.file", name.substring(5));
|
Preferences.set("serial.port.file", name.substring(5));
|
||||||
else
|
else
|
||||||
Preferences.set("serial.port.file", name);
|
Preferences.set("serial.port.file", name);
|
||||||
serialMonitor.closeSerialPort();
|
try {
|
||||||
|
serialMonitor.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
serialMonitor.setVisible(false);
|
serialMonitor.setVisible(false);
|
||||||
serialMonitor = new SerialMonitor(Preferences.get("serial.port"));
|
serialMonitor = new PerPortObjectFactory().newMonitor(Preferences.get("serial.port"), base);
|
||||||
|
|
||||||
onBoardOrPortChange();
|
onBoardOrPortChange();
|
||||||
|
|
||||||
@ -2401,7 +2405,7 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
serialMonitor.closeSerialPort();
|
serialMonitor.close();
|
||||||
serialMonitor.setVisible(false);
|
serialMonitor.setVisible(false);
|
||||||
|
|
||||||
uploading = true;
|
uploading = true;
|
||||||
@ -2437,7 +2441,7 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
serialMonitor.closeSerialPort();
|
serialMonitor.close();
|
||||||
serialMonitor.setVisible(false);
|
serialMonitor.setVisible(false);
|
||||||
|
|
||||||
uploading = true;
|
uploading = true;
|
||||||
@ -2507,9 +2511,11 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
if (uploading) return;
|
if (uploading) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
serialMonitor.openSerialPort();
|
serialMonitor.open();
|
||||||
serialMonitor.setVisible(true);
|
serialMonitor.setVisible(true);
|
||||||
} catch (SerialException e) {
|
} catch (ConnectException e) {
|
||||||
|
statusError(_("Unable to connect: is the sketch using the bridge?"));
|
||||||
|
} catch (IOException e) {
|
||||||
statusError(e);
|
statusError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
73
app/src/processing/app/NetworkMonitor.java
Normal file
73
app/src/processing/app/NetworkMonitor.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package processing.app;
|
||||||
|
|
||||||
|
import processing.app.debug.MessageSiphon;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
public class NetworkMonitor extends AbstractMonitor {
|
||||||
|
|
||||||
|
private static final int MAX_CONNECT_RETRIES = 3;
|
||||||
|
|
||||||
|
private final String ipAddress;
|
||||||
|
private final Base base;
|
||||||
|
|
||||||
|
private Socket socket;
|
||||||
|
private MessageSiphon consumer;
|
||||||
|
|
||||||
|
public NetworkMonitor(String port, Base base) {
|
||||||
|
super(port);
|
||||||
|
this.base = base;
|
||||||
|
|
||||||
|
Matcher matcher = Constants.IPV4_ADDRESS.matcher(port);
|
||||||
|
matcher.find();
|
||||||
|
this.ipAddress = matcher.group();
|
||||||
|
|
||||||
|
onSendCommand(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent event) {
|
||||||
|
try {
|
||||||
|
socket.getOutputStream().write(textField.getText().getBytes());
|
||||||
|
socket.getOutputStream().write('\n');
|
||||||
|
socket.getOutputStream().flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
textField.setText("");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void open() throws IOException {
|
||||||
|
try {
|
||||||
|
socket = new Socket();
|
||||||
|
socket.connect(new InetSocketAddress(ipAddress, 6571), 5000);
|
||||||
|
consumer = new MessageSiphon(socket.getInputStream(), this);
|
||||||
|
return;
|
||||||
|
} catch (IOException e) {
|
||||||
|
socket = null;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sleep(long millis) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(millis);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
if (socket != null) {
|
||||||
|
consumer.stop();
|
||||||
|
socket.close();
|
||||||
|
textArea.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
app/src/processing/app/PerPortObjectFactory.java
Normal file
28
app/src/processing/app/PerPortObjectFactory.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package processing.app;
|
||||||
|
|
||||||
|
import processing.app.debug.BasicUploader;
|
||||||
|
import processing.app.debug.HttpUploader;
|
||||||
|
import processing.app.debug.TargetBoard;
|
||||||
|
import processing.app.debug.Uploader;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class PerPortObjectFactory {
|
||||||
|
|
||||||
|
public Uploader newUploader(TargetBoard board, String port) {
|
||||||
|
if ("true".equals(board.getPreferences().get("upload.via_http")) && Constants.IPV4_ADDRESS.matcher(port).find()) {
|
||||||
|
return new HttpUploader(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BasicUploader();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractMonitor newMonitor(String port, Base base) {
|
||||||
|
if (Constants.IPV4_ADDRESS.matcher(port).find()) {
|
||||||
|
return new NetworkMonitor(port, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SerialMonitor(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -219,24 +219,15 @@ public class Serial implements SerialPortEventListener {
|
|||||||
//public void key(java.awt.event.KeyEvent e) { }
|
//public void key(java.awt.event.KeyEvent e) { }
|
||||||
|
|
||||||
|
|
||||||
public void dispose() {
|
public void dispose() throws IOException {
|
||||||
try {
|
|
||||||
// do io streams need to be closed first?
|
// do io streams need to be closed first?
|
||||||
if (input != null) input.close();
|
if (input != null) input.close();
|
||||||
if (output != null) output.close();
|
if (output != null) output.close();
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
input = null;
|
input = null;
|
||||||
output = null;
|
output = null;
|
||||||
|
|
||||||
try {
|
|
||||||
if (port != null) port.close(); // close the port
|
if (port != null) port.close(); // close the port
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
port = null;
|
port = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,9 @@
|
|||||||
|
|
||||||
package processing.app;
|
package processing.app;
|
||||||
|
|
||||||
public class SerialException extends Exception {
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class SerialException extends IOException {
|
||||||
public SerialException() {
|
public SerialException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
@ -18,27 +18,16 @@
|
|||||||
|
|
||||||
package processing.app;
|
package processing.app;
|
||||||
|
|
||||||
import processing.app.debug.MessageConsumer;
|
import processing.core.PApplet;
|
||||||
import processing.core.*;
|
|
||||||
import static processing.app.I18n._;
|
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.*;
|
import java.awt.event.ActionListener;
|
||||||
import javax.swing.*;
|
import java.io.IOException;
|
||||||
import javax.swing.border.*;
|
|
||||||
import javax.swing.event.*;
|
|
||||||
import javax.swing.text.*;
|
|
||||||
|
|
||||||
public class SerialMonitor extends JFrame implements MessageConsumer {
|
public class SerialMonitor extends AbstractMonitor {
|
||||||
|
|
||||||
|
private final String port;
|
||||||
private Serial serial;
|
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;
|
private int serialRate;
|
||||||
|
|
||||||
public SerialMonitor(String port) {
|
public SerialMonitor(String port) {
|
||||||
@ -46,172 +35,57 @@ public class SerialMonitor extends JFrame implements MessageConsumer {
|
|||||||
|
|
||||||
this.port = port;
|
this.port = port;
|
||||||
|
|
||||||
addWindowListener(new WindowAdapter() {
|
onSerialRateChange(new ActionListener() {
|
||||||
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",
|
|
||||||
"19200","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) {
|
public void actionPerformed(ActionEvent event) {
|
||||||
String wholeString = (String) serialRates.getSelectedItem();
|
String wholeString = (String) serialRates.getSelectedItem();
|
||||||
String rateString = wholeString.substring(0, wholeString.indexOf(' '));
|
String rateString = wholeString.substring(0, wholeString.indexOf(' '));
|
||||||
serialRate = Integer.parseInt(rateString);
|
serialRate = Integer.parseInt(rateString);
|
||||||
Preferences.set("serial.debug_rate", rateString);
|
Preferences.set("serial.debug_rate", rateString);
|
||||||
closeSerialPort();
|
|
||||||
try {
|
try {
|
||||||
|
close();
|
||||||
Thread.sleep(100); // Wait for serial port to properly close
|
Thread.sleep(100); // Wait for serial port to properly close
|
||||||
openSerialPort();
|
open();
|
||||||
} catch (SerialException e) {
|
} catch (IOException e) {
|
||||||
System.err.println(e);
|
System.err.println(e);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}});
|
|
||||||
|
|
||||||
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) {
|
onSendCommand(new ActionListener() {
|
||||||
setBounds(location[0], location[1], location[2], location[3]);
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
send(textField.getText());
|
||||||
|
textField.setText("");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
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) {
|
private void send(String s) {
|
||||||
if (serial != null) {
|
if (serial != null) {
|
||||||
switch (lineEndings.getSelectedIndex()) {
|
switch (lineEndings.getSelectedIndex()) {
|
||||||
case 1: s += "\n"; break;
|
case 1:
|
||||||
case 2: s += "\r"; break;
|
s += "\n";
|
||||||
case 3: s += "\r\n"; break;
|
break;
|
||||||
|
case 2:
|
||||||
|
s += "\r";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
s += "\r\n";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
serial.write(s);
|
serial.write(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void openSerialPort() throws SerialException {
|
public void open() throws IOException {
|
||||||
if (serial != null) return;
|
if (serial != null) return;
|
||||||
|
|
||||||
serial = new Serial(port, serialRate);
|
serial = new Serial(port, serialRate);
|
||||||
serial.addListener(this);
|
serial.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closeSerialPort() {
|
public void close() throws IOException {
|
||||||
if (serial != null) {
|
if (serial != null) {
|
||||||
int[] location = getPlacement();
|
int[] location = getPlacement();
|
||||||
String locationStr = PApplet.join(PApplet.str(location), ",");
|
String locationStr = PApplet.join(PApplet.str(location), ",");
|
||||||
@ -221,14 +95,4 @@ public class SerialMonitor extends JFrame implements MessageConsumer {
|
|||||||
serial = null;
|
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());
|
|
||||||
}
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1580,7 +1580,7 @@ public class Sketch {
|
|||||||
* Handle export to applet.
|
* Handle export to applet.
|
||||||
*/
|
*/
|
||||||
public boolean exportApplet(String appletPath, boolean usingProgrammer)
|
public boolean exportApplet(String appletPath, boolean usingProgrammer)
|
||||||
throws RunnerException, IOException, SerialException {
|
throws RunnerException, IOException {
|
||||||
|
|
||||||
prepare();
|
prepare();
|
||||||
|
|
||||||
@ -1658,12 +1658,12 @@ public class Sketch {
|
|||||||
System.out.println(_("Low memory available, stability problems may occur"));
|
System.out.println(_("Low memory available, stability problems may occur"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean upload(String buildPath, String suggestedClassName, boolean usingProgrammer) throws RunnerException, SerialException {
|
protected boolean upload(String buildPath, String suggestedClassName, boolean usingProgrammer) throws RunnerException {
|
||||||
|
|
||||||
TargetPlatform target = Base.getTargetPlatform();
|
TargetPlatform target = Base.getTargetPlatform();
|
||||||
String board = Preferences.get("board");
|
String board = Preferences.get("board");
|
||||||
|
|
||||||
Uploader uploader = new UploaderFactory().newUploader(target.getBoards().get(board), Preferences.get("serial.port"));
|
Uploader uploader = new PerPortObjectFactory().newUploader(target.getBoards().get(board), Preferences.get("serial.port"));
|
||||||
|
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
do {
|
do {
|
||||||
|
@ -45,7 +45,7 @@ public class BasicUploader extends Uploader {
|
|||||||
|
|
||||||
public boolean uploadUsingPreferences(String buildPath, String className,
|
public boolean uploadUsingPreferences(String buildPath, String className,
|
||||||
boolean usingProgrammer)
|
boolean usingProgrammer)
|
||||||
throws RunnerException, SerialException {
|
throws RunnerException {
|
||||||
// FIXME: Preferences should be reorganized
|
// FIXME: Preferences should be reorganized
|
||||||
TargetPlatform targetPlatform = Base.getTargetPlatform();
|
TargetPlatform targetPlatform = Base.getTargetPlatform();
|
||||||
PreferencesMap prefs = Preferences.getMap();
|
PreferencesMap prefs = Preferences.getMap();
|
||||||
@ -152,7 +152,11 @@ public class BasicUploader extends Uploader {
|
|||||||
Thread.sleep(250);
|
Thread.sleep(250);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
try {
|
||||||
Serial.touchPort(uploadPort, 9600);
|
Serial.touchPort(uploadPort, 9600);
|
||||||
|
} catch (SerialException e) {
|
||||||
|
throw new RunnerException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
|
@ -7,8 +7,8 @@ import org.apache.commons.httpclient.NameValuePair;
|
|||||||
import org.apache.commons.httpclient.methods.GetMethod;
|
import org.apache.commons.httpclient.methods.GetMethod;
|
||||||
import org.apache.commons.httpclient.methods.PostMethod;
|
import org.apache.commons.httpclient.methods.PostMethod;
|
||||||
import processing.app.Base;
|
import processing.app.Base;
|
||||||
|
import processing.app.Constants;
|
||||||
import processing.app.Preferences;
|
import processing.app.Preferences;
|
||||||
import processing.app.SerialException;
|
|
||||||
import processing.app.helpers.PreferencesMap;
|
import processing.app.helpers.PreferencesMap;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@ -19,7 +19,6 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
public class HttpUploader extends Uploader {
|
public class HttpUploader extends Uploader {
|
||||||
|
|
||||||
private static final Pattern IPV4_ADDRESS = Pattern.compile("(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})");
|
|
||||||
private static final String PROTOCOL = "http://";
|
private static final String PROTOCOL = "http://";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -34,11 +33,11 @@ public class HttpUploader extends Uploader {
|
|||||||
|
|
||||||
public HttpUploader(String port) {
|
public HttpUploader(String port) {
|
||||||
this.client = new HttpClient();
|
this.client = new HttpClient();
|
||||||
Matcher matcher = IPV4_ADDRESS.matcher(port);
|
Matcher matcher = Constants.IPV4_ADDRESS.matcher(port);
|
||||||
if (!matcher.find()) {
|
if (!matcher.find()) {
|
||||||
throw new IllegalArgumentException(port);
|
throw new IllegalArgumentException(port);
|
||||||
}
|
}
|
||||||
this.ipAddress = matcher.group(1);
|
this.ipAddress = matcher.group();
|
||||||
this.baseUrl = PROTOCOL + ipAddress + "/cgi-bin/luci/arduino";
|
this.baseUrl = PROTOCOL + ipAddress + "/cgi-bin/luci/arduino";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +50,7 @@ public class HttpUploader extends Uploader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer) throws RunnerException, SerialException {
|
public boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer) throws RunnerException {
|
||||||
if (usingProgrammer) {
|
if (usingProgrammer) {
|
||||||
System.err.println("Http upload using programmer not supported");
|
System.err.println("Http upload using programmer not supported");
|
||||||
return false;
|
return false;
|
||||||
|
@ -23,21 +23,26 @@
|
|||||||
|
|
||||||
package processing.app.debug;
|
package processing.app.debug;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.SocketException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Slurps up messages from compiler.
|
* Slurps up messages from compiler.
|
||||||
*/
|
*/
|
||||||
public class MessageSiphon implements Runnable {
|
public class MessageSiphon implements Runnable {
|
||||||
BufferedReader streamReader;
|
|
||||||
Thread thread;
|
|
||||||
MessageConsumer consumer;
|
|
||||||
|
|
||||||
|
private final BufferedReader streamReader;
|
||||||
|
private final MessageConsumer consumer;
|
||||||
|
|
||||||
|
private Thread thread;
|
||||||
|
private boolean canRun;
|
||||||
|
|
||||||
public MessageSiphon(InputStream stream, MessageConsumer consumer) {
|
public MessageSiphon(InputStream stream, MessageConsumer consumer) {
|
||||||
this.streamReader = new BufferedReader(new InputStreamReader(stream));
|
this.streamReader = new BufferedReader(new InputStreamReader(stream));
|
||||||
this.consumer = consumer;
|
this.consumer = consumer;
|
||||||
|
this.canRun = true;
|
||||||
|
|
||||||
thread = new Thread(this);
|
thread = new Thread(this);
|
||||||
// don't set priority too low, otherwise exceptions won't
|
// don't set priority too low, otherwise exceptions won't
|
||||||
@ -55,19 +60,17 @@ public class MessageSiphon implements Runnable {
|
|||||||
// when the program is finally done, null will come through.
|
// when the program is finally done, null will come through.
|
||||||
//
|
//
|
||||||
String currentLine;
|
String currentLine;
|
||||||
while ((currentLine = streamReader.readLine()) != null) {
|
while (canRun && (currentLine = streamReader.readLine()) != null) {
|
||||||
// \n is added again because readLine() strips it out
|
// \n is added again because readLine() strips it out
|
||||||
//EditorConsole.systemOut.println("messaging in");
|
//EditorConsole.systemOut.println("messaging in");
|
||||||
consumer.message(currentLine + "\n");
|
consumer.message(currentLine + "\n");
|
||||||
//EditorConsole.systemOut.println("messaging out");
|
//EditorConsole.systemOut.println("messaging out");
|
||||||
}
|
}
|
||||||
//EditorConsole.systemOut.println("messaging thread done");
|
//EditorConsole.systemOut.println("messaging thread done");
|
||||||
thread = null;
|
|
||||||
|
|
||||||
} catch (NullPointerException npe) {
|
} catch (NullPointerException npe) {
|
||||||
// Fairly common exception during shutdown
|
// Fairly common exception during shutdown
|
||||||
thread = null;
|
} catch (SocketException e) {
|
||||||
|
// socket has been close while we were wainting for data. nothing to see here, move along
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// On Linux and sometimes on Mac OS X, a "bad file descriptor"
|
// On Linux and sometimes on Mac OS X, a "bad file descriptor"
|
||||||
// message comes up when closing an applet that's run externally.
|
// message comes up when closing an applet that's run externally.
|
||||||
@ -81,6 +84,7 @@ public class MessageSiphon implements Runnable {
|
|||||||
} else {
|
} else {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
thread = null;
|
thread = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,7 +97,8 @@ public class MessageSiphon implements Runnable {
|
|||||||
if (t != null) t.join();
|
if (t != null) t.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Thread getThread() {
|
public void stop() {
|
||||||
return thread;
|
this.canRun = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public abstract class Uploader implements MessageConsumer {
|
|||||||
boolean verbose;
|
boolean verbose;
|
||||||
|
|
||||||
public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer)
|
public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer)
|
||||||
throws RunnerException, SerialException;
|
throws RunnerException;
|
||||||
|
|
||||||
public abstract boolean burnBootloader() throws RunnerException;
|
public abstract boolean burnBootloader() throws RunnerException;
|
||||||
|
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
package processing.app.debug;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class UploaderFactory {
|
|
||||||
|
|
||||||
private static final Pattern IPV4_ADDRESS = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
|
|
||||||
|
|
||||||
public Uploader newUploader(TargetBoard board, String port) {
|
|
||||||
if ("true".equals(board.getPreferences().get("upload.via_http")) && IPV4_ADDRESS.matcher(port).find()) {
|
|
||||||
return new HttpUploader(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BasicUploader();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -3,6 +3,7 @@ package processing.app.debug;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import processing.app.AbstractWithPreferencesTest;
|
import processing.app.AbstractWithPreferencesTest;
|
||||||
|
import processing.app.PerPortObjectFactory;
|
||||||
import processing.app.helpers.PreferencesMap;
|
import processing.app.helpers.PreferencesMap;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -23,7 +24,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldCreateAnInstanceOfHttpUploader() throws Exception {
|
public void shouldCreateAnInstanceOfHttpUploader() throws Exception {
|
||||||
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("yun");
|
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("yun");
|
||||||
Uploader uploader = new UploaderFactory().newUploader(board, "192.168.0.1 (yun)");
|
Uploader uploader = new PerPortObjectFactory().newUploader(board, "192.168.0.1 (yun)");
|
||||||
|
|
||||||
assertTrue(uploader instanceof HttpUploader);
|
assertTrue(uploader instanceof HttpUploader);
|
||||||
}
|
}
|
||||||
@ -31,7 +32,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldCreateAnInstanceOfBasicUploaderWhenHTTPIsUnsupported() throws Exception {
|
public void shouldCreateAnInstanceOfBasicUploaderWhenHTTPIsUnsupported() throws Exception {
|
||||||
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
|
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
|
||||||
Uploader uploader = new UploaderFactory().newUploader(board, "192.168.0.1 (myyun)");
|
Uploader uploader = new PerPortObjectFactory().newUploader(board, "192.168.0.1 (myyun)");
|
||||||
|
|
||||||
assertTrue(uploader instanceof BasicUploader);
|
assertTrue(uploader instanceof BasicUploader);
|
||||||
}
|
}
|
||||||
@ -39,7 +40,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldCreateAnInstanceOfBasicUploaderWhenPortIsSerial() throws Exception {
|
public void shouldCreateAnInstanceOfBasicUploaderWhenPortIsSerial() throws Exception {
|
||||||
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
|
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
|
||||||
Uploader uploader = new UploaderFactory().newUploader(board, "/dev/ttyACM0 (Arduino Leonardo)");
|
Uploader uploader = new PerPortObjectFactory().newUploader(board, "/dev/ttyACM0 (Arduino Leonardo)");
|
||||||
|
|
||||||
assertTrue(uploader instanceof BasicUploader);
|
assertTrue(uploader instanceof BasicUploader);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user