From 93562a7800f010d38b2149f24e13fa5225178689 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 26 Jan 2014 22:05:57 +0100 Subject: [PATCH] Refactored and simplified EditorConsole class. --- app/src/processing/app/EditorConsole.java | 255 ++++++++++------------ 1 file changed, 111 insertions(+), 144 deletions(-) diff --git a/app/src/processing/app/EditorConsole.java b/app/src/processing/app/EditorConsole.java index bfd20e152..c29222c93 100644 --- a/app/src/processing/app/EditorConsole.java +++ b/app/src/processing/app/EditorConsole.java @@ -1,5 +1,3 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - /* Part of the Processing project - http://processing.org @@ -22,15 +20,32 @@ */ package processing.app; + import static processing.app.I18n._; -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import javax.swing.*; -import javax.swing.text.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +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 * or just write println() or whatever directly to systemOut or systemErr. */ +@SuppressWarnings("serial") public class EditorConsole extends JScrollPane { Editor editor; JTextPane consoleTextPane; BufferedStyledDocument consoleDoc; - MutableAttributeSet stdStyle; - MutableAttributeSet errStyle; - - int maxLineCount; + SimpleAttributeSet stdStyle; + SimpleAttributeSet errStyle; static File errFile; static File outFile; @@ -70,20 +84,19 @@ public class EditorConsole extends JScrollPane { static EditorConsole currentConsole; + public EditorConsole(Editor _editor) { + editor = _editor; - public EditorConsole(Editor editor) { - this.editor = editor; + int maxLineCount = Preferences.getInteger("console.length"); - maxLineCount = Preferences.getInteger("console.length"); - - consoleDoc = new BufferedStyledDocument(10000, maxLineCount); + consoleDoc = new BufferedStyledDocument(4000, maxLineCount); consoleTextPane = new JTextPane(consoleDoc); consoleTextPane.setEditable(false); // necessary? - MutableAttributeSet standard = new SimpleAttributeSet(); - StyleConstants.setAlignment(standard, StyleConstants.ALIGN_LEFT); - consoleDoc.setParagraphAttributes(0, 0, standard, true); + SimpleAttributeSet leftAlignAttr = new SimpleAttributeSet(); + StyleConstants.setAlignment(leftAlignAttr, StyleConstants.ALIGN_LEFT); + consoleDoc.setParagraphAttributes(0, 0, leftAlignAttr, true); // build styles for different types of console output Color bgColor = Theme.getColor("console.color"); @@ -112,13 +125,13 @@ public class EditorConsole extends JScrollPane { consoleTextPane.setBackground(bgColor); // add the jtextpane to this scrollpane - this.setViewportView(consoleTextPane); + setViewportView(consoleTextPane); // calculate height of a line of text in pixels // and size window accordingly - FontMetrics metrics = this.getFontMetrics(font); + FontMetrics metrics = getFontMetrics(font); 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 setPreferredSize(new Dimension(1024, (height * lines) + sizeFudge)); setMinimumSize(new Dimension(1024, (height * 4) + sizeFudge)); @@ -127,10 +140,10 @@ public class EditorConsole extends JScrollPane { systemOut = System.out; systemErr = System.err; - // Create a temporary folder which will have a randomized name. Has to - // be randomized otherwise another instance of Processing (or one of its - // sister IDEs) might collide with the file causing permissions problems. - // The files and folders are not deleted on exit because they may be + // Create a temporary folder which will have a randomized name. Has to + // be randomized otherwise another instance of Processing (or one of its + // sister IDEs) might collide with the file causing permissions problems. + // The files and folders are not deleted on exit because they may be // needed for debugging or bug reporting. tempFolder = Base.createTempFolder("console"); tempFolder.deleteOnExit(); @@ -154,7 +167,7 @@ public class EditorConsole extends JScrollPane { } consoleOut = new PrintStream(new EditorConsoleStream(false)); consoleErr = new PrintStream(new EditorConsoleStream(true)); - + if (Preferences.getBoolean("console")) { try { System.setOut(consoleOut); @@ -179,7 +192,7 @@ public class EditorConsole extends JScrollPane { @Override public void run() { // only if new text has been added - if (consoleDoc.hasAppendage) { + if (consoleDoc.isChanged()) { // insert the text that's been added in the meantime consoleDoc.insertAll(); // always move to the end of the text as it's added @@ -220,7 +233,7 @@ public class EditorConsole extends JScrollPane { stdoutFile.close(); stderrFile.close(); } catch (IOException e) { - e.printStackTrace(systemOut); + e.printStackTrace(); } outFile.delete(); @@ -240,23 +253,18 @@ public class EditorConsole extends JScrollPane { synchronized public void message(String what, boolean err, boolean advance) { if (err) { systemErr.print(what); - //systemErr.print("CE" + what); + if (advance) + systemErr.println(); } else { systemOut.print(what); - //systemOut.print("CO" + what); - } - - if (advance) { - appendText("\n", err); - if (err) { - systemErr.println(); - } else { + if (advance) systemOut.println(); - } } - // to console display + // to console display appendText(what, err); + if (advance) + appendText("\n", err); // moved down here since something is punting } @@ -292,83 +300,47 @@ public class EditorConsole extends JScrollPane { private static class EditorConsoleStream extends OutputStream { - //static EditorConsole current; final boolean err; // whether stderr or stdout - final byte single[] = new byte[1]; - - public EditorConsoleStream(boolean err) { - this.err = err; + PrintStream system; + OutputStream file; + + public EditorConsoleStream(boolean _err) { + err = _err; + if (err) { + system = systemErr; + file = stderrFile; + } else { + system = systemOut; + file = stdoutFile; + } } public void close() { } public void flush() { } - public void write(byte b[]) { // appears never to be used - if (currentConsole != null) { - 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? - } + public void write(int b) { + write(new byte[] { (byte) b }); + } - OutputStream echo = err ? stderrFile : stdoutFile; - if (echo != null) { - try { - echo.write(b); - echo.flush(); - } catch (IOException e) { - e.printStackTrace(); - echo = null; - } - } + public void write(byte b[]) { // appears never to be used + write(b, 0, b.length); } public void write(byte b[], int offset, int length) { if (currentConsole != null) { currentConsole.write(b, offset, length, err); } else { - if (err) { - systemErr.write(b, offset, length); - } else { - systemOut.write(b, offset, length); - } + system.write(b, offset, length); } - OutputStream echo = err ? stderrFile : stdoutFile; - if (echo != null) { + if (file != null) { try { - echo.write(b, offset, length); - echo.flush(); + file.write(b, offset, length); + file.flush(); } catch (IOException e) { e.printStackTrace(); - echo = 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; + file = null; } } } @@ -386,78 +358,73 @@ public class EditorConsole extends JScrollPane { * appendString() is called from multiple threads, and insertAll from the * swing event thread, so they need to be synchronized */ +@SuppressWarnings("serial") class BufferedStyledDocument extends DefaultStyledDocument { - ArrayList elements = new ArrayList(); - int maxLineLength, maxLineCount; - int currentLineLength = 0; - boolean needLineBreak = false; - boolean hasAppendage = false; + private List elements = new ArrayList(); + private int maxLineLength, maxLineCount; + private int currentLineLength = 0; + private boolean changed = false; - public BufferedStyledDocument(int maxLineLength, int maxLineCount) { - this.maxLineLength = maxLineLength; - this.maxLineCount = maxLineCount; + public BufferedStyledDocument(int _maxLineLength, int _maxLineCount) { + maxLineLength = _maxLineLength; + maxLineCount = _maxLineCount; } /** buffer a string for insertion at the end of the DefaultStyledDocument */ - public synchronized void appendString(String str, AttributeSet a) { - // do this so that it's only updated when needed (otherwise console - // updates every 250 ms when an app isn't even running.. see bug 180) - hasAppendage = true; - - // process each line of the string - while (str.length() > 0) { - // newlines within an element have (almost) no effect, so we need to - // replace them with proper paragraph breaks (start and end tags) - if (needLineBreak || currentLineLength > maxLineLength) { + public synchronized void appendString(String text, AttributeSet a) { + changed = true; + char[] chars = text.toCharArray(); + int start = 0; + int stop = 0; + while (stop < chars.length) { + char c = chars[stop]; + stop++; + currentLineLength++; + 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.StartTagType)); currentLineLength = 0; - } - - 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 + start = stop; } } + elements.add(new ElementSpec(a, ElementSpec.ContentType, chars, start, + stop - start)); } /** insert the buffered strings */ public synchronized void insertAll() { - ElementSpec[] elementArray = new ElementSpec[elements.size()]; - elements.toArray(elementArray); - 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 - Element element = super.getDefaultRootElement(); - int lineCount = element.getElementCount(); + Element root = getDefaultRootElement(); + int lineCount = root.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 + Element lineElement = root.getElement(overage); + if (lineElement == null) + return; // do nuthin - int endOffset = lineElement.getEndOffset(); // 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) { // ignore the error otherwise this will cause an infinite loop // maybe not a good idea in the long run? } elements.clear(); - hasAppendage = false; + changed = false; + } + + public boolean isChanged() { + return changed; } }