mirror of
https://github.com/processing/processing4.git
synced 2026-02-04 06:09:17 +01:00
filling up the bugs db and applied dave mellis' patch to the console
This commit is contained in:
@@ -28,6 +28,7 @@ import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
@@ -41,7 +42,7 @@ public class EditorConsole extends JScrollPane {
|
||||
Editor editor;
|
||||
|
||||
JTextPane consoleTextPane;
|
||||
StyledDocument consoleDoc;
|
||||
BufferedStyledDocument consoleDoc;
|
||||
|
||||
MutableAttributeSet stdStyle;
|
||||
MutableAttributeSet errStyle;
|
||||
@@ -66,9 +67,9 @@ public class EditorConsole extends JScrollPane {
|
||||
|
||||
maxLineCount = Preferences.getInteger("console.length");
|
||||
|
||||
consoleTextPane = new JTextPane();
|
||||
consoleDoc = new BufferedStyledDocument(10000, maxLineCount);
|
||||
consoleTextPane = new JTextPane(consoleDoc);
|
||||
consoleTextPane.setEditable(false);
|
||||
consoleDoc = consoleTextPane.getStyledDocument();
|
||||
|
||||
// necessary?
|
||||
MutableAttributeSet standard = new SimpleAttributeSet();
|
||||
@@ -151,6 +152,17 @@ public class EditorConsole extends JScrollPane {
|
||||
if (Base.isMacOS()) {
|
||||
setBorder(null);
|
||||
}
|
||||
|
||||
// periodically post buffered messages to the console
|
||||
// should the interval come from the preferences file?
|
||||
new javax.swing.Timer(250, new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
consoleDoc.insertAll();
|
||||
|
||||
// always move to the end of the text as it's added
|
||||
consoleTextPane.setCaretPosition(consoleDoc.getLength());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
@@ -204,63 +216,11 @@ public class EditorConsole extends JScrollPane {
|
||||
* and eventually leads to EditorConsole.appendText(), which directly
|
||||
* updates the Swing text components, causing deadlock.
|
||||
* <P>
|
||||
* A quick hack from Francis Li (who found this to be a problem)
|
||||
* wraps the contents of appendText() into a Runnable and uses
|
||||
* SwingUtilities.invokeLater() to ensure that the updates only
|
||||
* occur on the main event dispatching thread, and that appears
|
||||
* to have solved the problem.
|
||||
* <P>
|
||||
* unfortunately this is probably extremely slow and helping cause
|
||||
* some of the general print() and println() mess.. need to fix
|
||||
* up so that it's using a proper queue instead.
|
||||
* Updates are buffered to the console and displayed at regular
|
||||
* intervals on Swing's event-dispatching thread. (patch by David Mellis)
|
||||
*/
|
||||
synchronized private void appendText(String txt, boolean e) {
|
||||
final String text = txt;
|
||||
final boolean err = e;
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
// check how many lines have been used so far
|
||||
// if too many, shave off a few lines from the beginning
|
||||
Element element = consoleDoc.getDefaultRootElement();
|
||||
int lineCount = element.getElementCount();
|
||||
int overage = lineCount - maxLineCount;
|
||||
if (overage > 0) {
|
||||
// if 1200 lines, and 1000 lines is max,
|
||||
// find the position of the end of the 200th line
|
||||
//systemOut.println("overage is " + overage);
|
||||
Element lineElement = element.getElement(overage);
|
||||
if (lineElement == null) return; // do nuthin
|
||||
|
||||
int endOffset = lineElement.getEndOffset();
|
||||
// remove to the end of the 200th line
|
||||
consoleDoc.remove(0, endOffset);
|
||||
}
|
||||
|
||||
// make sure this line doesn't go over 32k chars
|
||||
lineCount = element.getElementCount(); // may have changed
|
||||
Element currentElement = element.getElement(lineCount-1);
|
||||
int currentStart = currentElement.getStartOffset();
|
||||
int currentEnd = currentElement.getEndOffset();
|
||||
//systemOut.println(currentEnd - currentStart);
|
||||
if (currentEnd - currentStart > 10000) { // force a newline
|
||||
consoleDoc.insertString(consoleDoc.getLength(), "\n",
|
||||
err ? errStyle : stdStyle);
|
||||
}
|
||||
|
||||
// add the text to the end of the console,
|
||||
consoleDoc.insertString(consoleDoc.getLength(), text,
|
||||
err ? errStyle : stdStyle);
|
||||
|
||||
// always move to the end of the text as it's added
|
||||
consoleTextPane.setCaretPosition(consoleDoc.getLength());
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
// ignore the error otherwise this will cause an infinite loop
|
||||
// maybe not a good idea in the long run?
|
||||
}
|
||||
}
|
||||
});
|
||||
consoleDoc.appendString(txt, e ? errStyle : stdStyle);
|
||||
}
|
||||
|
||||
|
||||
@@ -332,3 +292,85 @@ class EditorConsoleStream extends OutputStream {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Buffer updates to the console and output them in batches. For info, see:
|
||||
* http://java.sun.com/products/jfc/tsc/articles/text/element_buffer and
|
||||
* http://javatechniques.com/public/java/docs/gui/jtextpane-speed-part2.html
|
||||
* appendString() is called from multiple threads, and insertAll from the
|
||||
* swing event thread, so they need to be synchronized
|
||||
*/
|
||||
class BufferedStyledDocument extends DefaultStyledDocument {
|
||||
ArrayList elements = new ArrayList();
|
||||
int maxLineLength, maxLineCount;
|
||||
int currentLineLength = 0;
|
||||
|
||||
public BufferedStyledDocument(int maxLineLength, int maxLineCount) {
|
||||
this.maxLineLength = maxLineLength;
|
||||
this.maxLineCount = maxLineCount;
|
||||
}
|
||||
|
||||
public synchronized void appendString(String str, AttributeSet a) {
|
||||
// newlines within an element have (almost) no effect, so we need to
|
||||
// replace them with proper paragraph breaks (start and end tags)
|
||||
while (str.indexOf('\n') != -1) {
|
||||
elements.add(new ElementSpec(a, ElementSpec.ContentType,
|
||||
str.toCharArray(), 0, str.indexOf('\n')));
|
||||
elements.add(new ElementSpec(a, ElementSpec.EndTagType));
|
||||
elements.add(new ElementSpec(a, ElementSpec.StartTagType));
|
||||
currentLineLength = 0;
|
||||
|
||||
// add a dummy character to the new paragraph; otherwise, a newline at
|
||||
// the end of a batch will be lost (because batches get appended to the
|
||||
// paragraph containing the last character of the preceeding batch)
|
||||
elements.add(new ElementSpec(a, ElementSpec.ContentType,
|
||||
new char[] { '\0' }, 0, 1));
|
||||
|
||||
str = str.substring(str.indexOf('\n') + 1);
|
||||
}
|
||||
|
||||
if (str.length() > 0) {
|
||||
// make sure this line doesn't go over 32k chars
|
||||
if (currentLineLength > maxLineLength) {
|
||||
elements.add(new ElementSpec(a, ElementSpec.EndTagType));
|
||||
elements.add(new ElementSpec(a, ElementSpec.StartTagType));
|
||||
currentLineLength = 0;
|
||||
}
|
||||
|
||||
elements.add(new ElementSpec(a, ElementSpec.ContentType,
|
||||
str.toCharArray(), 0, str.length()));
|
||||
currentLineLength += str.length();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void insertAll() {
|
||||
ElementSpec[] elementArray = new ElementSpec[elements.size()];
|
||||
elements.toArray(elementArray);
|
||||
|
||||
try {
|
||||
// check how many lines have been used so far
|
||||
// if too many, shave off a few lines from the beginning
|
||||
Element element = super.getDefaultRootElement();
|
||||
int lineCount = element.getElementCount();
|
||||
int overage = lineCount - maxLineCount;
|
||||
if (overage > 0) {
|
||||
// if 1200 lines, and 1000 lines is max,
|
||||
// find the position of the end of the 200th line
|
||||
//systemOut.println("overage is " + overage);
|
||||
Element lineElement = element.getElement(overage);
|
||||
if (lineElement == null) return; // do nuthin
|
||||
|
||||
int endOffset = lineElement.getEndOffset();
|
||||
// remove to the end of the 200th line
|
||||
super.remove(0, endOffset);
|
||||
}
|
||||
super.insert(super.getLength(), elementArray);
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
// ignore the error otherwise this will cause an infinite loop
|
||||
// maybe not a good idea in the long run?
|
||||
}
|
||||
elements.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user