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
36
37 private Document d;
38 private boolean autoScroll;
39
40 private TermIO() {
41 super("Winston Tools Console");
42
43
44
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 }