mirror of
https://github.com/arduino/Arduino.git
synced 2025-03-13 10:29:35 +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
|
||||
editors.remove(editor);
|
||||
Editor.serialMonitor.closeSerialPort();
|
||||
try {
|
||||
Editor.serialMonitor.close();
|
||||
} catch (IOException e) {
|
||||
//ignore
|
||||
}
|
||||
storeSketches();
|
||||
|
||||
// Save out the current prefs state
|
||||
@ -974,7 +978,11 @@ public class Base {
|
||||
// If quit is canceled, this will be replaced anyway
|
||||
// by a later handleQuit() that is not canceled.
|
||||
storeSketches();
|
||||
Editor.serialMonitor.closeSerialPort();
|
||||
try {
|
||||
Editor.serialMonitor.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (handleQuitEach()) {
|
||||
// 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 JMenu serialMenu;
|
||||
|
||||
static SerialMonitor serialMonitor;
|
||||
static AbstractMonitor serialMonitor;
|
||||
|
||||
EditorHeader header;
|
||||
EditorStatus status;
|
||||
@ -204,7 +204,7 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
//sketchbook = new Sketchbook(this);
|
||||
|
||||
if (serialMonitor == null) {
|
||||
serialMonitor = new SerialMonitor(Preferences.get("serial.port"));
|
||||
serialMonitor = new PerPortObjectFactory().newMonitor(Preferences.get("serial.port"), base);
|
||||
serialMonitor.setIconImage(getIconImage());
|
||||
}
|
||||
|
||||
@ -964,9 +964,13 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
Preferences.set("serial.port.file", name.substring(5));
|
||||
else
|
||||
Preferences.set("serial.port.file", name);
|
||||
serialMonitor.closeSerialPort();
|
||||
try {
|
||||
serialMonitor.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
serialMonitor.setVisible(false);
|
||||
serialMonitor = new SerialMonitor(Preferences.get("serial.port"));
|
||||
serialMonitor = new PerPortObjectFactory().newMonitor(Preferences.get("serial.port"), base);
|
||||
|
||||
onBoardOrPortChange();
|
||||
|
||||
@ -2401,7 +2405,7 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
serialMonitor.closeSerialPort();
|
||||
serialMonitor.close();
|
||||
serialMonitor.setVisible(false);
|
||||
|
||||
uploading = true;
|
||||
@ -2437,7 +2441,7 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
serialMonitor.closeSerialPort();
|
||||
serialMonitor.close();
|
||||
serialMonitor.setVisible(false);
|
||||
|
||||
uploading = true;
|
||||
@ -2507,9 +2511,11 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
if (uploading) return;
|
||||
|
||||
try {
|
||||
serialMonitor.openSerialPort();
|
||||
serialMonitor.open();
|
||||
serialMonitor.setVisible(true);
|
||||
} catch (SerialException e) {
|
||||
} catch (ConnectException e) {
|
||||
statusError(_("Unable to connect: is the sketch using the bridge?"));
|
||||
} catch (IOException 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 dispose() {
|
||||
try {
|
||||
// do io streams need to be closed first?
|
||||
if (input != null) input.close();
|
||||
if (output != null) output.close();
|
||||
public void dispose() throws IOException {
|
||||
// do io streams need to be closed first?
|
||||
if (input != null) input.close();
|
||||
if (output != null) output.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
input = null;
|
||||
output = null;
|
||||
|
||||
try {
|
||||
if (port != null) port.close(); // close the port
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (port != null) port.close(); // close the port
|
||||
port = null;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,9 @@
|
||||
|
||||
package processing.app;
|
||||
|
||||
public class SerialException extends Exception {
|
||||
import java.io.IOException;
|
||||
|
||||
public class SerialException extends IOException {
|
||||
public SerialException() {
|
||||
super();
|
||||
}
|
||||
|
@ -18,200 +18,74 @@
|
||||
|
||||
package processing.app;
|
||||
|
||||
import processing.app.debug.MessageConsumer;
|
||||
import processing.core.*;
|
||||
import static processing.app.I18n._;
|
||||
import processing.core.PApplet;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.text.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.IOException;
|
||||
|
||||
public class SerialMonitor extends JFrame implements MessageConsumer {
|
||||
public class SerialMonitor extends AbstractMonitor {
|
||||
|
||||
private final String port;
|
||||
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",
|
||||
"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() {
|
||||
onSerialRateChange(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 {
|
||||
close();
|
||||
Thread.sleep(100); // Wait for serial port to properly close
|
||||
openSerialPort();
|
||||
} catch (SerialException e) {
|
||||
open();
|
||||
} catch (IOException e) {
|
||||
System.err.println(e);
|
||||
} catch (InterruptedException e) {
|
||||
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) {
|
||||
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;
|
||||
onSendCommand(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
send(textField.getText());
|
||||
textField.setText("");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
case 1:
|
||||
s += "\n";
|
||||
break;
|
||||
case 2:
|
||||
s += "\r";
|
||||
break;
|
||||
case 3:
|
||||
s += "\r\n";
|
||||
break;
|
||||
}
|
||||
serial.write(s);
|
||||
}
|
||||
}
|
||||
|
||||
public void openSerialPort() throws SerialException {
|
||||
|
||||
public void open() throws IOException {
|
||||
if (serial != null) return;
|
||||
|
||||
|
||||
serial = new Serial(port, serialRate);
|
||||
serial.addListener(this);
|
||||
}
|
||||
|
||||
public void closeSerialPort() {
|
||||
|
||||
public void close() throws IOException {
|
||||
if (serial != null) {
|
||||
int[] location = getPlacement();
|
||||
String locationStr = PApplet.join(PApplet.str(location), ",");
|
||||
@ -221,14 +95,4 @@ public class SerialMonitor extends JFrame implements MessageConsumer {
|
||||
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.
|
||||
*/
|
||||
public boolean exportApplet(String appletPath, boolean usingProgrammer)
|
||||
throws RunnerException, IOException, SerialException {
|
||||
throws RunnerException, IOException {
|
||||
|
||||
prepare();
|
||||
|
||||
@ -1658,12 +1658,12 @@ public class Sketch {
|
||||
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();
|
||||
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;
|
||||
do {
|
||||
|
@ -45,7 +45,7 @@ public class BasicUploader extends Uploader {
|
||||
|
||||
public boolean uploadUsingPreferences(String buildPath, String className,
|
||||
boolean usingProgrammer)
|
||||
throws RunnerException, SerialException {
|
||||
throws RunnerException {
|
||||
// FIXME: Preferences should be reorganized
|
||||
TargetPlatform targetPlatform = Base.getTargetPlatform();
|
||||
PreferencesMap prefs = Preferences.getMap();
|
||||
@ -152,7 +152,11 @@ public class BasicUploader extends Uploader {
|
||||
Thread.sleep(250);
|
||||
}
|
||||
} else {
|
||||
Serial.touchPort(uploadPort, 9600);
|
||||
try {
|
||||
Serial.touchPort(uploadPort, 9600);
|
||||
} catch (SerialException e) {
|
||||
throw new RunnerException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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.PostMethod;
|
||||
import processing.app.Base;
|
||||
import processing.app.Constants;
|
||||
import processing.app.Preferences;
|
||||
import processing.app.SerialException;
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
|
||||
import java.io.*;
|
||||
@ -19,7 +19,6 @@ import java.util.regex.Pattern;
|
||||
|
||||
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://";
|
||||
|
||||
/*
|
||||
@ -34,11 +33,11 @@ public class HttpUploader extends Uploader {
|
||||
|
||||
public HttpUploader(String port) {
|
||||
this.client = new HttpClient();
|
||||
Matcher matcher = IPV4_ADDRESS.matcher(port);
|
||||
Matcher matcher = Constants.IPV4_ADDRESS.matcher(port);
|
||||
if (!matcher.find()) {
|
||||
throw new IllegalArgumentException(port);
|
||||
}
|
||||
this.ipAddress = matcher.group(1);
|
||||
this.ipAddress = matcher.group();
|
||||
this.baseUrl = PROTOCOL + ipAddress + "/cgi-bin/luci/arduino";
|
||||
}
|
||||
|
||||
@ -51,7 +50,7 @@ public class HttpUploader extends Uploader {
|
||||
}
|
||||
|
||||
@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) {
|
||||
System.err.println("Http upload using programmer not supported");
|
||||
return false;
|
||||
|
@ -23,27 +23,32 @@
|
||||
|
||||
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.
|
||||
*/
|
||||
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) {
|
||||
this.streamReader = new BufferedReader(new InputStreamReader(stream));
|
||||
this.consumer = consumer;
|
||||
this.canRun = true;
|
||||
|
||||
thread = new Thread(this);
|
||||
// don't set priority too low, otherwise exceptions won't
|
||||
// bubble up in time (i.e. compile errors have a weird delay)
|
||||
//thread.setPriority(Thread.MIN_PRIORITY);
|
||||
thread.setPriority(Thread.MAX_PRIORITY-1);
|
||||
thread.setPriority(Thread.MAX_PRIORITY - 1);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
@ -55,36 +60,35 @@ public class MessageSiphon implements Runnable {
|
||||
// when the program is finally done, null will come through.
|
||||
//
|
||||
String currentLine;
|
||||
while ((currentLine = streamReader.readLine()) != null) {
|
||||
while (canRun && (currentLine = streamReader.readLine()) != null) {
|
||||
// \n is added again because readLine() strips it out
|
||||
//EditorConsole.systemOut.println("messaging in");
|
||||
consumer.message(currentLine + "\n");
|
||||
//EditorConsole.systemOut.println("messaging out");
|
||||
}
|
||||
//EditorConsole.systemOut.println("messaging thread done");
|
||||
thread = null;
|
||||
|
||||
} catch (NullPointerException npe) {
|
||||
// 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) {
|
||||
// On Linux and sometimes on Mac OS X, a "bad file descriptor"
|
||||
// message comes up when closing an applet that's run externally.
|
||||
// That message just gets supressed here..
|
||||
String mess = e.getMessage();
|
||||
if ((mess != null) &&
|
||||
(mess.indexOf("Bad file descriptor") != -1)) {
|
||||
(mess.indexOf("Bad file descriptor") != -1)) {
|
||||
//if (e.getMessage().indexOf("Bad file descriptor") == -1) {
|
||||
//System.err.println("MessageSiphon err " + e);
|
||||
//e.printStackTrace();
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
thread = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Wait until the MessageSiphon thread is complete.
|
||||
public void join() throws java.lang.InterruptedException {
|
||||
// Grab a temp copy in case another thread nulls the "thread"
|
||||
@ -93,7 +97,8 @@ public class MessageSiphon implements Runnable {
|
||||
if (t != null) t.join();
|
||||
}
|
||||
|
||||
public Thread getThread() {
|
||||
return thread;
|
||||
public void stop() {
|
||||
this.canRun = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public abstract class Uploader implements MessageConsumer {
|
||||
boolean verbose;
|
||||
|
||||
public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer)
|
||||
throws RunnerException, SerialException;
|
||||
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.Test;
|
||||
import processing.app.AbstractWithPreferencesTest;
|
||||
import processing.app.PerPortObjectFactory;
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
|
||||
import java.io.File;
|
||||
@ -23,7 +24,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
|
||||
@Test
|
||||
public void shouldCreateAnInstanceOfHttpUploader() throws Exception {
|
||||
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);
|
||||
}
|
||||
@ -31,7 +32,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
|
||||
@Test
|
||||
public void shouldCreateAnInstanceOfBasicUploaderWhenHTTPIsUnsupported() throws Exception {
|
||||
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);
|
||||
}
|
||||
@ -39,7 +40,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
|
||||
@Test
|
||||
public void shouldCreateAnInstanceOfBasicUploaderWhenPortIsSerial() throws Exception {
|
||||
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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user