Skip to content

Commit 8e830b6

Browse files
Federico Fissorefacchinm
Federico Fissore
authored andcommitted
New console: replaces previous EditorConsoleStream with one that's faster and doesn't discard end chars. See arduino#2798
1 parent fadc6f2 commit 8e830b6

File tree

8 files changed

+188
-272
lines changed

8 files changed

+188
-272
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/**
2+
* Original version of this file courtesy of Rob Camick
3+
* <p>
4+
* https://tips4java.wordpress.com/2008/11/08/message-console/
5+
* <p>
6+
* About page at https://tips4java.wordpress.com/about/ says something
7+
* like MIT
8+
*/
9+
10+
package cc.arduino;
11+
12+
import javax.swing.*;
13+
import javax.swing.text.BadLocationException;
14+
import javax.swing.text.DefaultCaret;
15+
import javax.swing.text.Document;
16+
import javax.swing.text.SimpleAttributeSet;
17+
import java.io.ByteArrayOutputStream;
18+
import java.io.PrintStream;
19+
20+
/*
21+
* Create a simple console to display text messages.
22+
*
23+
* Messages can be directed here from different sources. Each source can
24+
* have its messages displayed in a different color.
25+
*/
26+
public class MessageConsole {
27+
28+
private final JTextPane textComponent;
29+
private final JScrollPane scrollPane;
30+
private final Document document;
31+
32+
public MessageConsole(JTextPane textComponent, JScrollPane scrollPane) {
33+
this.textComponent = textComponent;
34+
this.scrollPane = scrollPane;
35+
this.document = textComponent.getDocument();
36+
this.textComponent.setEditable(false);
37+
DefaultCaret caret = (DefaultCaret) this.textComponent.getCaret();
38+
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
39+
}
40+
41+
/*
42+
* Redirect the output from the standard output to the console using the specified
43+
* color and PrintStream. The message will be added to the Document before it is
44+
* also written to the PrintStream.
45+
*/
46+
public void redirectOut(SimpleAttributeSet style, PrintStream printStream) {
47+
ConsoleOutputStream cos = new ConsoleOutputStream(style, scrollPane, printStream);
48+
System.setOut(new PrintStream(cos, true));
49+
}
50+
51+
/*
52+
* Redirect the output from the standard error to the console using the specified
53+
* color and PrintStream. The message will be added to the Document before it is
54+
* also written to the PrintStream.
55+
*/
56+
public void redirectErr(SimpleAttributeSet style, PrintStream printStream) {
57+
ConsoleOutputStream cos = new ConsoleOutputStream(style, scrollPane, printStream);
58+
System.setErr(new PrintStream(cos, true));
59+
}
60+
61+
public synchronized void clear() {
62+
try {
63+
document.remove(0, document.getLength());
64+
} catch (BadLocationException e) {
65+
// ignore the error otherwise this will cause an infinite loop
66+
// maybe not a good idea in the long run?
67+
}
68+
}
69+
70+
public synchronized String getText() {
71+
return textComponent.getText().trim();
72+
}
73+
74+
/*
75+
* Class to intercept output from a PrintStream and add it to a Document.
76+
* The output can optionally be redirected to a different PrintStream.
77+
* The text displayed in the Document can be color coded to indicate
78+
* the output source.
79+
*/
80+
class ConsoleOutputStream extends ByteArrayOutputStream {
81+
82+
private final SimpleAttributeSet attributes;
83+
private final PrintStream printStream;
84+
private final StringBuilder buffer;
85+
private final Timer timer;
86+
87+
public ConsoleOutputStream(SimpleAttributeSet attributes, JScrollPane scrollPane, PrintStream printStream) {
88+
this.attributes = attributes;
89+
this.printStream = printStream;
90+
this.buffer = new StringBuilder();
91+
92+
this.timer = new Timer(100, (e) -> {
93+
scrollPane.getHorizontalScrollBar().setValue(0);
94+
scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
95+
});
96+
timer.setRepeats(false);
97+
}
98+
99+
public synchronized void flush() {
100+
String message = toString();
101+
102+
if (message.length() == 0) {
103+
return;
104+
}
105+
106+
handleAppend(message);
107+
108+
reset();
109+
}
110+
111+
private void handleAppend(String message) {
112+
resetBufferIfDocumentEmpty();
113+
114+
buffer.append(message);
115+
116+
clearBuffer();
117+
}
118+
119+
private void resetBufferIfDocumentEmpty() {
120+
if (document.getLength() == 0) {
121+
buffer.setLength(0);
122+
}
123+
}
124+
125+
private void clearBuffer() {
126+
String line = buffer.toString();
127+
buffer.setLength(0);
128+
129+
printStream.print(line);
130+
131+
SwingUtilities.invokeLater(() -> {
132+
try {
133+
int offset = document.getLength();
134+
document.insertString(offset, line, attributes);
135+
} catch (BadLocationException ble) {
136+
//ignore
137+
}
138+
});
139+
140+
if (!timer.isRunning()) {
141+
timer.restart();
142+
}
143+
}
144+
}
145+
}

app/src/processing/app/Base.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -639,9 +639,6 @@ protected void handleActivated(Editor whichEditor) {
639639
// noop
640640
}
641641
}
642-
643-
// set the current window to be the console that's getting output
644-
EditorConsoleStream.setCurrent(activeEditor.console);
645642
}
646643

647644

app/src/processing/app/Editor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ public void windowDeactivated(WindowEvent e) {
263263
status = new EditorStatus(this);
264264
consolePanel.add(status, BorderLayout.NORTH);
265265

266-
console = new EditorConsole(this);
266+
console = new EditorConsole();
267267
console.setName("console");
268268
// windows puts an ugly border on this guy
269269
console.setBorder(null);

0 commit comments

Comments
 (0)