1919package processing .app ;
2020
2121import processing .app .debug .MessageConsumer ;
22+ import processing .app .debug .TextAreaFIFO ;
2223import processing .core .*;
2324import static processing .app .I18n ._ ;
2425
2526import java .awt .*;
2627import java .awt .event .*;
2728import javax .swing .*;
2829import javax .swing .border .*;
29- import javax .swing .event .*;
3030import javax .swing .text .*;
3131
32- public class SerialMonitor extends JFrame implements MessageConsumer {
32+ public class SerialMonitor extends JFrame implements MessageConsumer , ActionListener {
3333 private Serial serial ;
3434 private String port ;
35- private JTextArea textArea ;
35+ private TextAreaFIFO textArea ;
3636 private JScrollPane scrollPane ;
3737 private JTextField textField ;
3838 private JButton sendButton ;
3939 private JCheckBox autoscrollBox ;
4040 private JComboBox lineEndings ;
4141 private JComboBox serialRates ;
4242 private int serialRate ;
43+ private javax .swing .Timer updateTimer ;
44+ private StringBuffer updateBuffer ;
4345
4446 public SerialMonitor (String port ) {
4547 super (port );
@@ -67,7 +69,9 @@ public void actionPerformed(ActionEvent e) {
6769 Font editorFont = Preferences .getFont ("editor.font" );
6870 Font font = new Font (consoleFont .getName (), consoleFont .getStyle (), editorFont .getSize ());
6971
70- textArea = new JTextArea (16 , 40 );
72+ textArea = new TextAreaFIFO (4000000 );
73+ textArea .setRows (16 );
74+ textArea .setColumns (40 );
7175 textArea .setEditable (false );
7276 textArea .setFont (font );
7377
@@ -171,6 +175,9 @@ public void actionPerformed(ActionEvent event) {
171175 }
172176 }
173177 }
178+
179+ updateBuffer = new StringBuffer (1048576 );
180+ updateTimer = new javax .swing .Timer (33 , this ); // redraw serial monitor at 30 Hz
174181 }
175182
176183 protected void setPlacement (int [] location ) {
@@ -203,9 +210,9 @@ private void send(String s) {
203210
204211 public void openSerialPort () throws SerialException {
205212 if (serial != null ) return ;
206-
207213 serial = new Serial (port , serialRate );
208214 serial .addListener (this );
215+ updateTimer .start ();
209216 }
210217
211218 public void closeSerialPort () {
@@ -219,13 +226,32 @@ public void closeSerialPort() {
219226 }
220227 }
221228
222- public void message (final String s ) {
223- SwingUtilities .invokeLater (new Runnable () {
224- public void run () {
225- textArea .append (s );
226- if (autoscrollBox .isSelected ()) {
227- textArea .setCaretPosition (textArea .getDocument ().getLength ());
228- }
229- }});
229+ public void message (String s ) {
230+ // TODO: can we pass a byte array, to avoid overhead of String
231+ addToUpdateBuffer (s );
230232 }
233+
234+ private synchronized void addToUpdateBuffer (String s ) {
235+ updateBuffer .append (s );
236+ }
237+
238+ private synchronized String consumeUpdateBuffer () {
239+ String s = updateBuffer .toString ();
240+ updateBuffer .setLength (0 );
241+ return s ;
242+ }
243+
244+ public void actionPerformed (ActionEvent e ) {
245+ final String s = consumeUpdateBuffer ();
246+ if (s .length () > 0 ) {
247+ //System.out.println("gui append " + s.length());
248+ boolean scroll = autoscrollBox .isSelected ();
249+ textArea .allowTrim (scroll );
250+ textArea .append (s );
251+ if (scroll ) {
252+ textArea .setCaretPosition (textArea .getDocument ().getLength ());
253+ }
254+ }
255+ }
256+
231257}
0 commit comments