View Javadoc
1   package gov.usgs.volcanoes.winston.tools;
2   
3   import java.awt.Dimension;
4   import java.awt.event.ActionEvent;
5   import java.awt.event.ActionListener;
6   import java.awt.event.ItemEvent;
7   import java.awt.event.ItemListener;
8   import java.io.IOException;
9   import java.io.OutputStream;
10  import java.io.PrintStream;
11  
12  import javax.swing.JButton;
13  import javax.swing.JCheckBox;
14  import javax.swing.JFrame;
15  import javax.swing.JPanel;
16  import javax.swing.JScrollPane;
17  import javax.swing.JTextArea;
18  import javax.swing.ScrollPaneConstants;
19  import javax.swing.event.DocumentEvent;
20  import javax.swing.event.DocumentListener;
21  import javax.swing.text.BadLocationException;
22  import javax.swing.text.Document;
23  
24  import com.jgoodies.forms.builder.DefaultFormBuilder;
25  import com.jgoodies.forms.layout.FormLayout;
26  
27  public class TermIO extends JFrame {
28  
29    private static final long serialVersionUID = 1L;
30  
31    private static JButton closeB = new JButton("Close");
32    private static JButton stopB = new JButton("Stop");
33    private static TermIO term = new TermIO();
34  
35    // private PrintStream stdout;
36    // private PrintStream stderr;
37    private Document d;
38    private boolean autoScroll;
39  
40    private TermIO() {
41      super("Winston Tools Console");
42  
43      // stdout = System.out;
44      // stderr = System.err;
45      autoScroll = true;
46  
47      final FormLayout layout = new FormLayout("fill:p:G", "fill:p:G, p");
48  
49      final DefaultFormBuilder builder = new DefaultFormBuilder(layout);
50      builder.setDefaultDialogBorder();
51  
52      builder.append(createContentPane());
53      builder.nextLine();
54      builder.append(createControlPanel());
55      getContentPane().add(builder.getPanel());
56      pack();
57      setSize(640, 480);
58  
59      final PrintStream o = new PrintStream(new DocumentOutputStream(d));
60      System.setOut(o);
61      System.setErr(o);
62    }
63  
64    public static TermIO getTerm() {
65      return term;
66    }
67  
68    public static void showTerm(final boolean b) {
69      term.setVisible(b);
70    }
71  
72    private JScrollPane createContentPane() {
73      final JTextArea t = new JTextArea("\n");
74      d = t.getDocument();
75      d.addDocumentListener(new ScrolledDocumentListener(t));
76  
77      final JScrollPane areaScrollPane = new JScrollPane(t);
78      areaScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
79      areaScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
80      areaScrollPane.setPreferredSize(new Dimension(320, 240));
81  
82      return areaScrollPane;
83  
84    }
85  
86    private JPanel createControlPanel() {
87      final JPanel p = new JPanel();
88      closeB.setEnabled(true);
89      closeB.addActionListener(new ActionListener() {
90        public void actionPerformed(final ActionEvent e) {
91          TermIO.this.dispose();
92        }
93      });
94      p.add(closeB);
95  
96      addStopListener(new ActionListener() {
97        public void actionPerformed(final ActionEvent e) {
98          stopB.setText("Stopping");
99          stopB.setEnabled(false);
100       }
101     });
102     stopB.setEnabled(false);
103     p.add(stopB);
104 
105     final JCheckBox autoScrollB = new JCheckBox("Auto scroll", autoScroll);
106     autoScrollB.addItemListener(new ItemListener() {
107       public void itemStateChanged(final ItemEvent e) {
108         autoScroll = e.getStateChange() == ItemEvent.SELECTED;
109       }
110     });
111     p.add(autoScrollB);
112 
113     return p;
114 
115   }
116 
117   public void addStopListener(final ActionListener a) {
118     stopB.addActionListener(a);
119   }
120 
121   public static void startRunning(final boolean b) {
122     closeB.setEnabled(false);
123     stopB.setEnabled(b);
124   }
125 
126   public static void stopRunning() {
127     closeB.setEnabled(true);
128     stopB.setEnabled(false);
129     stopB.setText("Stop");
130   }
131 
132   private class ScrolledDocumentListener implements DocumentListener {
133     JTextArea ta;
134 
135     public ScrolledDocumentListener(final JTextArea t) {
136       ta = t;
137     }
138 
139     public void changedUpdate(final DocumentEvent e) {
140       if (autoScroll)
141         ta.setCaretPosition(ta.getText().length());
142     }
143 
144     public void insertUpdate(final DocumentEvent e) {
145       if (autoScroll)
146         ta.setCaretPosition(ta.getText().length());
147     }
148 
149     public void removeUpdate(final DocumentEvent e) {
150       if (autoScroll)
151         ta.setCaretPosition(ta.getText().length());
152     }
153 
154   }
155 
156   public class DocumentOutputStream extends OutputStream {
157     private Document doc;
158     private boolean closed;
159 
160     public DocumentOutputStream(final Document d) {
161       super();
162       doc = d;
163       closed = false;
164     }
165 
166     @Override
167     public void write(final int i) throws IOException {
168       if (closed)
169         return;
170 
171       try {
172         doc.insertString(doc.getLength() - 1, String.valueOf((char) i), null);
173       } catch (final BadLocationException e) {
174       }
175     }
176 
177     @Override
178     public void write(final byte[] b, final int offset, final int length) throws IOException {
179       if (closed)
180         return;
181 
182       if (b == null)
183         throw new NullPointerException("The byte array is null");
184       if (offset < 0 || length < 0 || (offset + length) > b.length)
185         throw new IndexOutOfBoundsException(
186             "offset and length are negative or extend outside array bounds");
187 
188       final String str = new String(b, offset, length);
189       try {
190         doc.insertString(doc.getLength() - 1, str, null);
191       } catch (final BadLocationException e) {
192       }
193     }
194 
195     @Override
196     public void close() {
197       doc = null;
198       closed = true;
199     }
200 
201   }
202 }