mirror of
https://github.com/arduino/Arduino.git
synced 2025-03-15 12:29:26 +01:00
Refactored and simplified EditorConsole class.
This commit is contained in:
parent
479b974fe1
commit
93562a7800
@ -1,5 +1,3 @@
|
|||||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Part of the Processing project - http://processing.org
|
Part of the Processing project - http://processing.org
|
||||||
|
|
||||||
@ -22,15 +20,32 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
package processing.app;
|
package processing.app;
|
||||||
|
|
||||||
import static processing.app.I18n._;
|
import static processing.app.I18n._;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Color;
|
||||||
import java.awt.event.*;
|
import java.awt.Dimension;
|
||||||
import java.io.*;
|
import java.awt.Font;
|
||||||
import javax.swing.*;
|
import java.awt.FontMetrics;
|
||||||
import javax.swing.text.*;
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import java.util.*;
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTextPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.text.AttributeSet;
|
||||||
|
import javax.swing.text.BadLocationException;
|
||||||
|
import javax.swing.text.DefaultStyledDocument;
|
||||||
|
import javax.swing.text.Element;
|
||||||
|
import javax.swing.text.SimpleAttributeSet;
|
||||||
|
import javax.swing.text.StyleConstants;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,16 +55,15 @@ import java.util.*;
|
|||||||
* don't take over System.err, and debug while watching just System.out
|
* don't take over System.err, and debug while watching just System.out
|
||||||
* or just write println() or whatever directly to systemOut or systemErr.
|
* or just write println() or whatever directly to systemOut or systemErr.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
public class EditorConsole extends JScrollPane {
|
public class EditorConsole extends JScrollPane {
|
||||||
Editor editor;
|
Editor editor;
|
||||||
|
|
||||||
JTextPane consoleTextPane;
|
JTextPane consoleTextPane;
|
||||||
BufferedStyledDocument consoleDoc;
|
BufferedStyledDocument consoleDoc;
|
||||||
|
|
||||||
MutableAttributeSet stdStyle;
|
SimpleAttributeSet stdStyle;
|
||||||
MutableAttributeSet errStyle;
|
SimpleAttributeSet errStyle;
|
||||||
|
|
||||||
int maxLineCount;
|
|
||||||
|
|
||||||
static File errFile;
|
static File errFile;
|
||||||
static File outFile;
|
static File outFile;
|
||||||
@ -70,20 +84,19 @@ public class EditorConsole extends JScrollPane {
|
|||||||
|
|
||||||
static EditorConsole currentConsole;
|
static EditorConsole currentConsole;
|
||||||
|
|
||||||
|
public EditorConsole(Editor _editor) {
|
||||||
|
editor = _editor;
|
||||||
|
|
||||||
public EditorConsole(Editor editor) {
|
int maxLineCount = Preferences.getInteger("console.length");
|
||||||
this.editor = editor;
|
|
||||||
|
|
||||||
maxLineCount = Preferences.getInteger("console.length");
|
consoleDoc = new BufferedStyledDocument(4000, maxLineCount);
|
||||||
|
|
||||||
consoleDoc = new BufferedStyledDocument(10000, maxLineCount);
|
|
||||||
consoleTextPane = new JTextPane(consoleDoc);
|
consoleTextPane = new JTextPane(consoleDoc);
|
||||||
consoleTextPane.setEditable(false);
|
consoleTextPane.setEditable(false);
|
||||||
|
|
||||||
// necessary?
|
// necessary?
|
||||||
MutableAttributeSet standard = new SimpleAttributeSet();
|
SimpleAttributeSet leftAlignAttr = new SimpleAttributeSet();
|
||||||
StyleConstants.setAlignment(standard, StyleConstants.ALIGN_LEFT);
|
StyleConstants.setAlignment(leftAlignAttr, StyleConstants.ALIGN_LEFT);
|
||||||
consoleDoc.setParagraphAttributes(0, 0, standard, true);
|
consoleDoc.setParagraphAttributes(0, 0, leftAlignAttr, true);
|
||||||
|
|
||||||
// build styles for different types of console output
|
// build styles for different types of console output
|
||||||
Color bgColor = Theme.getColor("console.color");
|
Color bgColor = Theme.getColor("console.color");
|
||||||
@ -112,13 +125,13 @@ public class EditorConsole extends JScrollPane {
|
|||||||
consoleTextPane.setBackground(bgColor);
|
consoleTextPane.setBackground(bgColor);
|
||||||
|
|
||||||
// add the jtextpane to this scrollpane
|
// add the jtextpane to this scrollpane
|
||||||
this.setViewportView(consoleTextPane);
|
setViewportView(consoleTextPane);
|
||||||
|
|
||||||
// calculate height of a line of text in pixels
|
// calculate height of a line of text in pixels
|
||||||
// and size window accordingly
|
// and size window accordingly
|
||||||
FontMetrics metrics = this.getFontMetrics(font);
|
FontMetrics metrics = getFontMetrics(font);
|
||||||
int height = metrics.getAscent() + metrics.getDescent();
|
int height = metrics.getAscent() + metrics.getDescent();
|
||||||
int lines = Preferences.getInteger("console.lines"); //, 4);
|
int lines = Preferences.getInteger("console.lines");
|
||||||
int sizeFudge = 6; //10; // unclear why this is necessary, but it is
|
int sizeFudge = 6; //10; // unclear why this is necessary, but it is
|
||||||
setPreferredSize(new Dimension(1024, (height * lines) + sizeFudge));
|
setPreferredSize(new Dimension(1024, (height * lines) + sizeFudge));
|
||||||
setMinimumSize(new Dimension(1024, (height * 4) + sizeFudge));
|
setMinimumSize(new Dimension(1024, (height * 4) + sizeFudge));
|
||||||
@ -179,7 +192,7 @@ public class EditorConsole extends JScrollPane {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// only if new text has been added
|
// only if new text has been added
|
||||||
if (consoleDoc.hasAppendage) {
|
if (consoleDoc.isChanged()) {
|
||||||
// insert the text that's been added in the meantime
|
// insert the text that's been added in the meantime
|
||||||
consoleDoc.insertAll();
|
consoleDoc.insertAll();
|
||||||
// always move to the end of the text as it's added
|
// always move to the end of the text as it's added
|
||||||
@ -220,7 +233,7 @@ public class EditorConsole extends JScrollPane {
|
|||||||
stdoutFile.close();
|
stdoutFile.close();
|
||||||
stderrFile.close();
|
stderrFile.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace(systemOut);
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
outFile.delete();
|
outFile.delete();
|
||||||
@ -240,23 +253,18 @@ public class EditorConsole extends JScrollPane {
|
|||||||
synchronized public void message(String what, boolean err, boolean advance) {
|
synchronized public void message(String what, boolean err, boolean advance) {
|
||||||
if (err) {
|
if (err) {
|
||||||
systemErr.print(what);
|
systemErr.print(what);
|
||||||
//systemErr.print("CE" + what);
|
if (advance)
|
||||||
} else {
|
|
||||||
systemOut.print(what);
|
|
||||||
//systemOut.print("CO" + what);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (advance) {
|
|
||||||
appendText("\n", err);
|
|
||||||
if (err) {
|
|
||||||
systemErr.println();
|
systemErr.println();
|
||||||
} else {
|
} else {
|
||||||
|
systemOut.print(what);
|
||||||
|
if (advance)
|
||||||
systemOut.println();
|
systemOut.println();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// to console display
|
// to console display
|
||||||
appendText(what, err);
|
appendText(what, err);
|
||||||
|
if (advance)
|
||||||
|
appendText("\n", err);
|
||||||
// moved down here since something is punting
|
// moved down here since something is punting
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,83 +300,47 @@ public class EditorConsole extends JScrollPane {
|
|||||||
|
|
||||||
|
|
||||||
private static class EditorConsoleStream extends OutputStream {
|
private static class EditorConsoleStream extends OutputStream {
|
||||||
//static EditorConsole current;
|
|
||||||
final boolean err; // whether stderr or stdout
|
final boolean err; // whether stderr or stdout
|
||||||
final byte single[] = new byte[1];
|
PrintStream system;
|
||||||
|
OutputStream file;
|
||||||
|
|
||||||
public EditorConsoleStream(boolean err) {
|
public EditorConsoleStream(boolean _err) {
|
||||||
this.err = err;
|
err = _err;
|
||||||
|
if (err) {
|
||||||
|
system = systemErr;
|
||||||
|
file = stderrFile;
|
||||||
|
} else {
|
||||||
|
system = systemOut;
|
||||||
|
file = stdoutFile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() { }
|
public void close() { }
|
||||||
|
|
||||||
public void flush() { }
|
public void flush() { }
|
||||||
|
|
||||||
public void write(byte b[]) { // appears never to be used
|
public void write(int b) {
|
||||||
if (currentConsole != null) {
|
write(new byte[] { (byte) b });
|
||||||
currentConsole.write(b, 0, b.length, err);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
if (err) {
|
|
||||||
systemErr.write(b);
|
|
||||||
} else {
|
|
||||||
systemOut.write(b);
|
|
||||||
}
|
|
||||||
} catch (IOException e) { } // just ignore, where would we write?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputStream echo = err ? stderrFile : stdoutFile;
|
public void write(byte b[]) { // appears never to be used
|
||||||
if (echo != null) {
|
write(b, 0, b.length);
|
||||||
try {
|
|
||||||
echo.write(b);
|
|
||||||
echo.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
echo = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(byte b[], int offset, int length) {
|
public void write(byte b[], int offset, int length) {
|
||||||
if (currentConsole != null) {
|
if (currentConsole != null) {
|
||||||
currentConsole.write(b, offset, length, err);
|
currentConsole.write(b, offset, length, err);
|
||||||
} else {
|
} else {
|
||||||
if (err) {
|
system.write(b, offset, length);
|
||||||
systemErr.write(b, offset, length);
|
|
||||||
} else {
|
|
||||||
systemOut.write(b, offset, length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputStream echo = err ? stderrFile : stdoutFile;
|
if (file != null) {
|
||||||
if (echo != null) {
|
|
||||||
try {
|
try {
|
||||||
echo.write(b, offset, length);
|
file.write(b, offset, length);
|
||||||
echo.flush();
|
file.flush();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
echo = null;
|
file = null;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(int b) {
|
|
||||||
single[0] = (byte)b;
|
|
||||||
if (currentConsole != null) {
|
|
||||||
currentConsole.write(single, 0, 1, err);
|
|
||||||
} else {
|
|
||||||
// redirect for all the extra handling above
|
|
||||||
write(new byte[] { (byte) b }, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
OutputStream echo = err ? stderrFile : stdoutFile;
|
|
||||||
if (echo != null) {
|
|
||||||
try {
|
|
||||||
echo.write(b);
|
|
||||||
echo.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
echo = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -386,78 +358,73 @@ public class EditorConsole extends JScrollPane {
|
|||||||
* appendString() is called from multiple threads, and insertAll from the
|
* appendString() is called from multiple threads, and insertAll from the
|
||||||
* swing event thread, so they need to be synchronized
|
* swing event thread, so they need to be synchronized
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
class BufferedStyledDocument extends DefaultStyledDocument {
|
class BufferedStyledDocument extends DefaultStyledDocument {
|
||||||
ArrayList<ElementSpec> elements = new ArrayList<ElementSpec>();
|
private List<ElementSpec> elements = new ArrayList<ElementSpec>();
|
||||||
int maxLineLength, maxLineCount;
|
private int maxLineLength, maxLineCount;
|
||||||
int currentLineLength = 0;
|
private int currentLineLength = 0;
|
||||||
boolean needLineBreak = false;
|
private boolean changed = false;
|
||||||
boolean hasAppendage = false;
|
|
||||||
|
|
||||||
public BufferedStyledDocument(int maxLineLength, int maxLineCount) {
|
public BufferedStyledDocument(int _maxLineLength, int _maxLineCount) {
|
||||||
this.maxLineLength = maxLineLength;
|
maxLineLength = _maxLineLength;
|
||||||
this.maxLineCount = maxLineCount;
|
maxLineCount = _maxLineCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** buffer a string for insertion at the end of the DefaultStyledDocument */
|
/** buffer a string for insertion at the end of the DefaultStyledDocument */
|
||||||
public synchronized void appendString(String str, AttributeSet a) {
|
public synchronized void appendString(String text, AttributeSet a) {
|
||||||
// do this so that it's only updated when needed (otherwise console
|
changed = true;
|
||||||
// updates every 250 ms when an app isn't even running.. see bug 180)
|
char[] chars = text.toCharArray();
|
||||||
hasAppendage = true;
|
int start = 0;
|
||||||
|
int stop = 0;
|
||||||
// process each line of the string
|
while (stop < chars.length) {
|
||||||
while (str.length() > 0) {
|
char c = chars[stop];
|
||||||
// newlines within an element have (almost) no effect, so we need to
|
stop++;
|
||||||
// replace them with proper paragraph breaks (start and end tags)
|
currentLineLength++;
|
||||||
if (needLineBreak || currentLineLength > maxLineLength) {
|
if (c == '\n' || currentLineLength > maxLineLength) {
|
||||||
|
elements.add(new ElementSpec(a, ElementSpec.ContentType, chars, start,
|
||||||
|
stop - start));
|
||||||
elements.add(new ElementSpec(a, ElementSpec.EndTagType));
|
elements.add(new ElementSpec(a, ElementSpec.EndTagType));
|
||||||
elements.add(new ElementSpec(a, ElementSpec.StartTagType));
|
elements.add(new ElementSpec(a, ElementSpec.StartTagType));
|
||||||
currentLineLength = 0;
|
currentLineLength = 0;
|
||||||
}
|
start = stop;
|
||||||
|
|
||||||
if (str.indexOf('\n') == -1) {
|
|
||||||
elements.add(new ElementSpec(a, ElementSpec.ContentType,
|
|
||||||
str.toCharArray(), 0, str.length()));
|
|
||||||
currentLineLength += str.length();
|
|
||||||
needLineBreak = false;
|
|
||||||
str = str.substring(str.length()); // eat the string
|
|
||||||
} else {
|
|
||||||
elements.add(new ElementSpec(a, ElementSpec.ContentType,
|
|
||||||
str.toCharArray(), 0, str.indexOf('\n') + 1));
|
|
||||||
needLineBreak = true;
|
|
||||||
str = str.substring(str.indexOf('\n') + 1); // eat the line
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
elements.add(new ElementSpec(a, ElementSpec.ContentType, chars, start,
|
||||||
|
stop - start));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** insert the buffered strings */
|
/** insert the buffered strings */
|
||||||
public synchronized void insertAll() {
|
public synchronized void insertAll() {
|
||||||
ElementSpec[] elementArray = new ElementSpec[elements.size()];
|
|
||||||
elements.toArray(elementArray);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// check how many lines have been used so far
|
// Insert new elements at the bottom
|
||||||
|
ElementSpec[] elementArray = elements.toArray(new ElementSpec[0]);
|
||||||
|
insert(getLength(), elementArray);
|
||||||
|
|
||||||
|
// check how many lines have been used
|
||||||
// if too many, shave off a few lines from the beginning
|
// if too many, shave off a few lines from the beginning
|
||||||
Element element = super.getDefaultRootElement();
|
Element root = getDefaultRootElement();
|
||||||
int lineCount = element.getElementCount();
|
int lineCount = root.getElementCount();
|
||||||
int overage = lineCount - maxLineCount;
|
int overage = lineCount - maxLineCount;
|
||||||
if (overage > 0) {
|
if (overage > 0) {
|
||||||
// if 1200 lines, and 1000 lines is max,
|
// if 1200 lines, and 1000 lines is max,
|
||||||
// find the position of the end of the 200th line
|
// find the position of the end of the 200th line
|
||||||
//systemOut.println("overage is " + overage);
|
Element lineElement = root.getElement(overage);
|
||||||
Element lineElement = element.getElement(overage);
|
if (lineElement == null)
|
||||||
if (lineElement == null) return; // do nuthin
|
return; // do nuthin
|
||||||
|
|
||||||
int endOffset = lineElement.getEndOffset();
|
|
||||||
// remove to the end of the 200th line
|
// remove to the end of the 200th line
|
||||||
super.remove(0, endOffset);
|
int endOffset = lineElement.getEndOffset();
|
||||||
|
remove(0, endOffset);
|
||||||
}
|
}
|
||||||
super.insert(super.getLength(), elementArray);
|
|
||||||
|
|
||||||
} catch (BadLocationException e) {
|
} catch (BadLocationException e) {
|
||||||
// ignore the error otherwise this will cause an infinite loop
|
// ignore the error otherwise this will cause an infinite loop
|
||||||
// maybe not a good idea in the long run?
|
// maybe not a good idea in the long run?
|
||||||
}
|
}
|
||||||
elements.clear();
|
elements.clear();
|
||||||
hasAppendage = false;
|
changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isChanged() {
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user