diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 5b2f0fe99..5df968ed4 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -139,6 +139,8 @@ public class Base { } Platform.init(); + // call after Platform.init() because we need the settings folder + Console.startup(); // Set the debug flag based on a file being present in the settings folder File debugFile = getSettingsFile("debug.txt"); @@ -1474,6 +1476,9 @@ public class Base { // Save out the current prefs state Preferences.save(); + // Finished with this guy + Console.shutdown(); + if (!Platform.isMacOS()) { // If this was fired from the menu or an AppleEvent (the Finder), // then Mac OS X will send the terminate signal itself. diff --git a/app/src/processing/app/Console.java b/app/src/processing/app/Console.java index b5f5b9496..178fce716 100644 --- a/app/src/processing/app/Console.java +++ b/app/src/processing/app/Console.java @@ -3,7 +3,8 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2004-10 Ben Fry and Casey Reas + Copyright (c) 2012-16 The Processing Foundation + Copyright (c) 2004-12 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology This program is free software; you can redistribute it and/or modify @@ -21,25 +22,11 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -package processing.app.ui; +package processing.app; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.event.*; import java.io.*; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Date; -import java.util.List; - -import javax.swing.*; -import javax.swing.border.MatteBorder; -import javax.swing.text.*; - -import processing.app.*; -import processing.core.PApplet; /** @@ -55,76 +42,87 @@ import processing.core.PApplet; * It seems that Eclipse's console-grabbing and that of Processing don't * get along with one another. Use 'ant run' to work on encoding-related issues. */ -public class EditorConsole extends JScrollPane { - Editor editor; - - Timer flushTimer; - - JTextPane consoleTextPane; - BufferedStyledDocument consoleDoc; - - MutableAttributeSet stdStyle; - MutableAttributeSet errStyle; - - int maxLineCount; - - PrintStream sketchOut; - PrintStream sketchErr; +public class Console { +// PrintStream sketchOut; +// PrintStream sketchErr; // Single static instance shared because there's only one real System.out. // Within the input handlers, the currentConsole variable will be used to // echo things to the correct location. + /** The original System.out */ static PrintStream systemOut; + /** The original System.err */ static PrintStream systemErr; + /** Our replacement System.out */ static PrintStream consoleOut; + /** Our replacement System.err */ static PrintStream consoleErr; + /** All stdout also written to a file */ static OutputStream stdoutFile; + /** All stderr also written to a file */ static OutputStream stderrFile; - static EditorConsole currentConsole; + /** stdout listener for the currently active Editor */ + static OutputStream editorOut; + /** stderr listener for the currently active Editor */ + static OutputStream editorErr; - // For 0185, moved the first init to this static { } block, so that we never - // have a situation that causes systemOut/Err to not be set properly. - static { + + static public void startup() { systemOut = System.out; systemErr = System.err; // placing everything inside a try block because this can be a dangerous // time for the lights to blink out and crash for and obscure reason. try { - // Create output files that 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. - SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd"); - String randy = PApplet.nf((int) (1000 * Math.random()), 4); - String stamp = formatter.format(new Date()) + "_" + randy; + SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd_HHmmss"); + // Moving away from a random string in 0256 (and adding hms) because + // the random digits looked like times anyway, causing confusion. + //String randy = String.format("%04d", (int) (1000 * Math.random())); + //final String stamp = formatter.format(new Date()) + "_" + randy; + final String stamp = formatter.format(new Date()); File consoleDir = Base.getSettingsFile("console"); - consoleDir.mkdirs(); + if (consoleDir.exists()) { + // clear old debug files + File[] stdFiles = consoleDir.listFiles(new FileFilter() { + final String todayPrefix = stamp.substring(0, 4); + + public boolean accept(File file) { + if (!file.isDirectory()) { + String name = file.getName(); + if (name.endsWith(".err") || name.endsWith(".out")) { + // don't delete any of today's debug messages + return !name.startsWith(todayPrefix); + } + } + return false; + } + }); + // Remove any files that aren't from today + for (File file : stdFiles) { + file.delete(); + } + } else { + consoleDir.mkdirs(); + } + File outFile = new File(consoleDir, stamp + ".out"); stdoutFile = new FileOutputStream(outFile); File errFile = new File(consoleDir, stamp + ".err"); stderrFile = new FileOutputStream(errFile); - consoleOut = new PrintStream(new EditorConsoleStream(false, null)); - consoleErr = new PrintStream(new EditorConsoleStream(true, null)); +// consoleOut = new PrintStream(new EditorConsoleStream(false, null)); +// consoleErr = new PrintStream(new EditorConsoleStream(true, null)); + consoleOut = new PrintStream(new ConsoleStream(false)); + consoleErr = new PrintStream(new ConsoleStream(true)); System.setOut(consoleOut); System.setErr(consoleErr); -// } catch (Exception e) { -// stdoutFile = null; -// stderrFile = null; -// -// e.printStackTrace(); -// Base.showWarning("Console Error", -// "A problem occurred while trying to open the\n" + -// "files used to store the console output.", e); } catch (Exception e) { stdoutFile = null; stderrFile = null; @@ -135,159 +133,31 @@ public class EditorConsole extends JScrollPane { System.setOut(systemOut); System.setErr(systemErr); - e.printStackTrace(systemErr); + e.printStackTrace(); } } - public EditorConsole(Editor editor) { - this.editor = editor; - - maxLineCount = Preferences.getInteger("console.length"); - - consoleDoc = new BufferedStyledDocument(10000, maxLineCount); - consoleTextPane = new JTextPane(consoleDoc); - consoleTextPane.setEditable(false); - - updateMode(); - - // add the jtextpane to this scrollpane - this.setViewportView(consoleTextPane); - - sketchOut = new PrintStream(new EditorConsoleStream(false, this)); - sketchErr = new PrintStream(new EditorConsoleStream(true, this)); - - startTimer(); + static public void setEditor(OutputStream out, OutputStream err) { + editorOut = out; + editorErr = err; } - protected void flush() { - // only if new text has been added - if (consoleDoc.hasAppendage) { - // insert the text that's been added in the meantime - consoleDoc.insertAll(); - // always move to the end of the text as it's added - consoleTextPane.setCaretPosition(consoleDoc.getLength()); - } - } +// public Console() { +// sketchOut = new PrintStream(new EditorConsoleStream(false, this)); +// sketchErr = new PrintStream(new EditorConsoleStream(true, this)); +// } - /** - * Start the timer that handles flushing the console text. Has to be started - * and stopped/cleared because the Timer thread will keep a reference to its - * Editor around even after the Editor has been closed, leaking memory. - */ - protected void startTimer() { - if (flushTimer == null) { - // periodically post buffered messages to the console - // should the interval come from the preferences file? - flushTimer = new Timer(250, new ActionListener() { - public void actionPerformed(ActionEvent evt) { - flush(); - } - }); - flushTimer.start(); - } - } +// public PrintStream getOut() { +// return sketchOut; +// } - protected void stopTimer() { - if (flushTimer != null) { - flush(); // clear anything that's there - flushTimer.stop(); - flushTimer = null; - } - } - - - public PrintStream getOut() { - return sketchOut; - } - - - public PrintStream getErr() { - return sketchErr; - } - - - /** - * Update the font family and sizes based on the Preferences window. - */ - protected void updateAppearance() { - String fontFamily = Preferences.get("editor.font.family"); - int fontSize = Preferences.getInteger("console.font.size"); - StyleConstants.setFontFamily(stdStyle, fontFamily); - StyleConstants.setFontSize(stdStyle, fontSize); - StyleConstants.setFontFamily(errStyle, fontFamily); - StyleConstants.setFontSize(errStyle, fontSize); - clear(); // otherwise we'll have mixed fonts - } - - - /** - * Change coloring, fonts, etc in response to a mode change. - */ - protected void updateMode() { - Mode mode = editor.getMode(); - - // necessary? - MutableAttributeSet standard = new SimpleAttributeSet(); - StyleConstants.setAlignment(standard, StyleConstants.ALIGN_LEFT); - consoleDoc.setParagraphAttributes(0, 0, standard, true); - - Font font = Preferences.getFont("console.font"); - - // build styles for different types of console output - Color bgColor = mode.getColor("console.color"); - Color fgColorOut = mode.getColor("console.output.color"); - Color fgColorErr = mode.getColor("console.error.color"); - - // Make things line up with the Editor above. If this is ever removed, - // setBorder(null) should be called instead. The defaults are nasty. - setBorder(new MatteBorder(0, Editor.LEFT_GUTTER, 0, 0, bgColor)); - - stdStyle = new SimpleAttributeSet(); - StyleConstants.setForeground(stdStyle, fgColorOut); - StyleConstants.setBackground(stdStyle, bgColor); - StyleConstants.setFontSize(stdStyle, font.getSize()); - StyleConstants.setFontFamily(stdStyle, font.getFamily()); - StyleConstants.setBold(stdStyle, font.isBold()); - StyleConstants.setItalic(stdStyle, font.isItalic()); - - errStyle = new SimpleAttributeSet(); - StyleConstants.setForeground(errStyle, fgColorErr); - StyleConstants.setBackground(errStyle, bgColor); - StyleConstants.setFontSize(errStyle, font.getSize()); - StyleConstants.setFontFamily(errStyle, font.getFamily()); - StyleConstants.setBold(errStyle, font.isBold()); - StyleConstants.setItalic(errStyle, font.isItalic()); - - if (UIManager.getLookAndFeel().getID().equals("Nimbus")) { - getViewport().setBackground(bgColor); - consoleTextPane.setOpaque(false); - consoleTextPane.setBackground(new Color(0, 0, 0, 0)); - } else { - consoleTextPane.setBackground(bgColor); - } - - // calculate height of a line of text in pixels - // and size window accordingly - FontMetrics metrics = this.getFontMetrics(font); - int height = metrics.getAscent() + metrics.getDescent(); - int lines = Preferences.getInteger("console.lines"); //, 4); - 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)); - } - - - static public void setEditor(Editor editor) { - if (currentConsole != null) { - currentConsole.stopTimer(); // allow to be garbage collected - } - currentConsole = editor.console; - currentConsole.startTimer(); - } +// public PrintStream getErr() { +// return sketchErr; +// } /** @@ -298,66 +168,29 @@ public class EditorConsole extends JScrollPane { * folder itself is deleted, which can't be guaranteed when using * the deleteOnExit() method. */ - public static void handleQuit() { + static public void shutdown() { // replace original streams to remove references to console's streams System.setOut(systemOut); System.setErr(systemErr); + cleanup(consoleOut); + cleanup(consoleErr); + + // also have to close the original FileOutputStream + // otherwise it won't be shut down completely + cleanup(stdoutFile); + cleanup(stderrFile); + } + + + static private void cleanup(OutputStream output) { try { - // close the PrintStream - if (consoleOut != null) consoleOut.close(); - if (consoleErr != null) consoleErr.close(); - - // also have to close the original FileOutputStream - // otherwise it won't be shut down completely - if (stdoutFile != null) stdoutFile.close(); - if (stderrFile != null) stderrFile.close(); - + if (output != null) { + output.flush(); + output.close(); + } } catch (IOException e) { - e.printStackTrace(systemErr); - } - } - - - synchronized public void message(String what, boolean err) { - if (err) { - systemErr.print(what); - } else { - systemOut.print(what); - } - - if (err && (what.contains("invalid context 0x0") || (what.contains("invalid drawable")))) { - // Respectfully declining... This is a quirk of more recent releases of - // Java on Mac OS X, but is widely reported as the source of any other - // bug or problem that a user runs into. It may well be a Processing - // bug, but until we know, we're suppressing the messages. - } else if (err && what.contains("Make pbuffer:")) { - // Remove initalization warning from LWJGL. - } else if (err && what.contains("XInitThreads() called for concurrent")) { - // "Info: XInitThreads() called for concurrent Thread support" message on Linux - } else if (!err && what.contains("Listening for transport dt_socket at address")) { - // Message from the JVM about the socket launch for debug - // Listening for transport dt_socket at address: 8727 - } else { - // Append a piece of text to the console. Swing components are NOT - // thread-safe, and since the MessageSiphon instantiates new threads, - // and in those callbacks, they often print output to stdout and stderr, - // which are wrapped by EditorConsoleStream and eventually leads to - // EditorConsole.appendText(), which directly updates the Swing text - // components, causing deadlock. Updates are buffered to the console and - // displayed at regular intervals on Swing's event-dispatching thread. - // (patch by David Mellis) - consoleDoc.appendString(what, err ? errStyle : stdStyle); - } - } - - - public void clear() { - try { - consoleDoc.remove(0, consoleDoc.getLength()); - } catch (BadLocationException e) { - // ignore the error otherwise this will cause an infinite loop - // maybe not a good idea in the long run? + e.printStackTrace(); } } @@ -365,14 +198,12 @@ public class EditorConsole extends JScrollPane { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - private static class EditorConsoleStream extends OutputStream { - final boolean err; // whether stderr or stdout - final byte single[] = new byte[1]; - EditorConsole console; + static class ConsoleStream extends OutputStream { + boolean err; // whether stderr or stdout + byte single[] = new byte[1]; - public EditorConsoleStream(boolean err, EditorConsole console) { + public ConsoleStream(boolean err) { this.err = err; - this.console = console; } public void close() { } @@ -384,20 +215,34 @@ public class EditorConsole extends JScrollPane { } public void write(byte b[], int offset, int length) { - if (console != null) { - console.message(new String(b, offset, length), err); - } else if (currentConsole != null) { - currentConsole.message(new String(b, offset, length), err); + // First write to the original stdout/stderr + if (err) { + systemErr.write(b, offset, length); } else { - // If no console is present, still need to write this to the actual - // System.out or System.err. Otherwise we can't !#$!% debug anything. - if (err) { - systemErr.write(b, offset, length); - } else { - systemOut.write(b, offset, length); - } + systemOut.write(b, offset, length); } + // Write to the files that are storing this information + writeFile(b, offset, length); + + // Write to the console of the current Editor, if any + try { + if (err) { + if (editorErr != null) { + editorErr.write(b, offset, length); + } + } else { + if (editorOut != null) { + editorOut.write(b, offset, length); + } + } + } catch (IOException e) { + // Avoid this function being called in a recursive, infinite loop + e.printStackTrace(systemErr); + } + } + + public void writeFile(byte b[], int offset, int length) { final OutputStream echo = err ? stderrFile : stdoutFile; if (echo != null) { try { @@ -414,91 +259,4 @@ public class EditorConsole extends JScrollPane { write(single, 0, 1); } } -} - - -// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - -/** - * 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 { - List elements = new ArrayList(); - int maxLineLength, maxLineCount; - int currentLineLength = 0; - boolean needLineBreak = false; - boolean hasAppendage = false; - - public BufferedStyledDocument(int maxLineLength, int maxLineCount) { - this.maxLineLength = maxLineLength; - this.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) { - 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 - } - } - } - - /** 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 - // 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(); - hasAppendage = false; - } -} +} \ No newline at end of file diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index b4baaa71a..fee7ae181 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -182,25 +182,21 @@ public abstract class Editor extends JFrame implements RunnerListener { // When bringing a window to front, let the Base know addWindowListener(new WindowAdapter() { -// int importIndex; public void windowActivated(WindowEvent e) { base.handleActivated(Editor.this); fileMenu.insert(Recent.getMenu(), 2); Toolkit.setMenuMnemsInside(fileMenu); - //sketchMenu.insert(mode.getImportMenu(), 5); mode.insertImportMenu(sketchMenu); - //sketchMenu.insert(mode.getImportMenu(), importIndex); Toolkit.setMenuMnemsInside(sketchMenu); mode.insertToolbarRecentMenu(); } public void windowDeactivated(WindowEvent e) { + // TODO call handleActivated(null)? or do we run the risk of the + // deactivate call for old window being called after the activate? fileMenu.remove(Recent.getMenu()); -// JMenu importMenu = mode.getImportMenu(); -// importIndex = sketchMenu.getComponentZOrder(mode.getImportMenu()); -// sketchMenu.remove(mode.getImportMenu()); mode.removeImportMenu(sketchMenu); mode.removeToolbarRecentMenu(); } diff --git a/app/src/processing/app/ui/EditorConsole.java b/app/src/processing/app/ui/EditorConsole.java index b5f5b9496..269975891 100644 --- a/app/src/processing/app/ui/EditorConsole.java +++ b/app/src/processing/app/ui/EditorConsole.java @@ -3,7 +3,8 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2004-10 Ben Fry and Casey Reas + Copyright (c) 2012-16 The Processing Foundation + Copyright (c) 2004-12 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology This program is free software; you can redistribute it and/or modify @@ -27,19 +28,20 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; -import java.awt.event.*; -import java.io.*; -import java.text.SimpleDateFormat; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.ArrayList; -import java.util.Date; import java.util.List; import javax.swing.*; import javax.swing.border.MatteBorder; import javax.swing.text.*; -import processing.app.*; -import processing.core.PApplet; +import processing.app.Console; +import processing.app.Mode; +import processing.app.Preferences; /** @@ -71,6 +73,7 @@ public class EditorConsole extends JScrollPane { PrintStream sketchOut; PrintStream sketchErr; + /* // Single static instance shared because there's only one real System.out. // Within the input handlers, the currentConsole variable will be used to // echo things to the correct location. @@ -83,9 +86,11 @@ public class EditorConsole extends JScrollPane { static OutputStream stdoutFile; static OutputStream stderrFile; + */ - static EditorConsole currentConsole; + static EditorConsole current; + /* // For 0185, moved the first init to this static { } block, so that we never // have a situation that causes systemOut/Err to not be set properly. static { @@ -138,6 +143,7 @@ public class EditorConsole extends JScrollPane { e.printStackTrace(systemErr); } } + */ public EditorConsole(Editor editor) { @@ -154,8 +160,10 @@ public class EditorConsole extends JScrollPane { // add the jtextpane to this scrollpane this.setViewportView(consoleTextPane); - sketchOut = new PrintStream(new EditorConsoleStream(false, this)); - sketchErr = new PrintStream(new EditorConsoleStream(true, this)); +// sketchOut = new PrintStream(new EditorConsoleStream(false, this)); +// sketchErr = new PrintStream(new EditorConsoleStream(true, this)); + sketchOut = new PrintStream(new EditorConsoleStream(false)); + sketchErr = new PrintStream(new EditorConsoleStream(true)); startTimer(); } @@ -282,49 +290,58 @@ public class EditorConsole extends JScrollPane { static public void setEditor(Editor editor) { - if (currentConsole != null) { - currentConsole.stopTimer(); // allow to be garbage collected + if (current != null) { + current.stopTimer(); // allow to be garbage collected } - currentConsole = editor.console; - currentConsole.startTimer(); + editor.console.setCurrent(); } - /** - * Close the streams so that the temporary files can be deleted. - *

- * File.deleteOnExit() cannot be used because the stdout and stderr - * files are inside a folder, and have to be deleted before the - * folder itself is deleted, which can't be guaranteed when using - * the deleteOnExit() method. - */ - public static void handleQuit() { - // replace original streams to remove references to console's streams - System.setOut(systemOut); - System.setErr(systemErr); - - try { - // close the PrintStream - if (consoleOut != null) consoleOut.close(); - if (consoleErr != null) consoleErr.close(); - - // also have to close the original FileOutputStream - // otherwise it won't be shut down completely - if (stdoutFile != null) stdoutFile.close(); - if (stderrFile != null) stderrFile.close(); - - } catch (IOException e) { - e.printStackTrace(systemErr); - } + void setCurrent() { + current = this; //editor.console; + startTimer(); + Console.setEditor(sketchOut, sketchErr); } +// /** +// * Close the streams so that the temporary files can be deleted. +// *

+// * File.deleteOnExit() cannot be used because the stdout and stderr +// * files are inside a folder, and have to be deleted before the +// * folder itself is deleted, which can't be guaranteed when using +// * the deleteOnExit() method. +// */ +// public static void handleQuit() { +// // replace original streams to remove references to console's streams +// System.setOut(systemOut); +// System.setErr(systemErr); +// +// try { +// // close the PrintStream +// if (consoleOut != null) consoleOut.close(); +// if (consoleErr != null) consoleErr.close(); +// +// // also have to close the original FileOutputStream +// // otherwise it won't be shut down completely +// if (stdoutFile != null) stdoutFile.close(); +// if (stderrFile != null) stderrFile.close(); +// +// } catch (IOException e) { +// e.printStackTrace(systemErr); +// } +// } + + synchronized public void message(String what, boolean err) { + // now handled in Console + /* if (err) { - systemErr.print(what); + Console.systemErr.print(what); } else { - systemOut.print(what); + Console.systemOut.print(what); } + */ if (err && (what.contains("invalid context 0x0") || (what.contains("invalid drawable")))) { // Respectfully declining... This is a quirk of more recent releases of @@ -362,12 +379,13 @@ public class EditorConsole extends JScrollPane { } + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - private static class EditorConsoleStream extends OutputStream { - final boolean err; // whether stderr or stdout - final byte single[] = new byte[1]; + /* + static class EditorConsoleStream extends OutputStream { + boolean err; EditorConsole console; public EditorConsoleStream(boolean err, EditorConsole console) { @@ -375,14 +393,6 @@ public class EditorConsole extends JScrollPane { this.console = console; } - public void close() { } - - public void flush() { } - - 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 (console != null) { console.message(new String(b, offset, length), err); @@ -397,21 +407,26 @@ public class EditorConsole extends JScrollPane { systemOut.write(b, offset, length); } } + writeEcho(b, offset, length); + } + } + */ - final OutputStream echo = err ? stderrFile : stdoutFile; - if (echo != null) { - try { - echo.write(b, offset, length); - echo.flush(); - } catch (IOException e) { - e.printStackTrace(); - } - } + + class EditorConsoleStream extends OutputStream { + boolean err; + + public EditorConsoleStream(boolean err) { + this.err = err; } + public void write(byte b[], int offset, int length) { + message(new String(b, offset, length), err); + } + + // doesn't appear to be called (but must be implemented) public void write(int b) { - single[0] = (byte) b; - write(single, 0, 1); + write(new byte[] { (byte) b }, 0, 1); } } } diff --git a/core/todo.txt b/core/todo.txt index c98e94cf0..081647303 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -21,6 +21,8 @@ cleaning o probably should also check to make sure PApplet running JVM 8 X or compile against 1.8 and force it? +_ no prompt shows with selectInput() on 10.11 and 10.12 +_ https://github.com/processing/processing/issues/4758 _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678