001package jmri.script.swing; 002 003import java.io.IOException; 004import java.io.PipedReader; 005import java.io.PipedWriter; 006import javax.script.ScriptContext; 007import javax.swing.JTextArea; 008import jmri.InstanceManager; 009import jmri.script.JmriScriptEngineManager; 010import jmri.util.PipeListener; 011 012/** 013 * 014 * @author Randall Wood 015 */ 016public class ScriptOutput { 017 018 /** 019 * JTextArea containing the output 020 */ 021 private JTextArea output = null; 022 023 /** 024 * Provide access to the JTextArea containing all ScriptEngine output. 025 * <p> 026 * The output JTextArea is not created until this is invoked, so that code 027 * that doesn't use this feature can run on GUI-less machines. 028 * <p> 029 * This creates a "ScriptOutput PipeListener" thread which is not normally terminated. 030 * @return component containing script output 031 */ 032 public JTextArea getOutputArea() { 033 if (output == null) { 034 // convert to stored output 035 036 try { 037 // create the output area 038 output = new JTextArea(); 039 040 // Add the I/O pipes 041 PipedWriter pw = new PipedWriter(); 042 043 ScriptContext context = JmriScriptEngineManager.getDefault().getDefaultContext(); 044 context.setErrorWriter(pw); 045 context.setWriter(pw); 046 047 // ensure the output pipe is read and stored into a 048 // Swing TextArea data model 049 PipedReader pr = new PipedReader(pw); 050 PipeListener pl = new PipeListener(pr, output); 051 pl.setName("ScriptOutput PipeListener"); 052 pl.setDaemon(true); 053 pl.start(); 054 } catch (IOException e) { 055 log.error("Exception creating script output area", e); 056 return null; 057 } 058 } 059 return output; 060 } 061 062 public static ScriptOutput getDefault() { 063 if (InstanceManager.getNullableDefault(ScriptOutput.class) == null) { 064 InstanceManager.store(new ScriptOutput(), ScriptOutput.class); 065 } 066 return InstanceManager.getDefault(ScriptOutput.class); 067 } 068 069 /** 070 * Write a script to the output area. The output is prepended with a leading 071 * ">>>" on the first line and a leading ellipsis on subsequent 072 * lines. 073 * 074 * @param script The script to write. 075 */ 076 public static void writeScript(final String script) { 077 String output = ">>> " + script; // NOI18N 078 // Strip ending newlines 079 while (output.endsWith("\n")) { // NOI18N 080 output = output.substring(0, output.length() - 1); 081 } 082 output = output.replaceAll("\n", "\n... "); // NOI18N 083 output += "\n"; // NOI18N 084 ScriptOutput.getDefault().getOutputArea().append(output); 085 } 086 087 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ScriptOutput.class); 088 089}