1
2
3
4 package jwutil.gui;
5
6 import java.awt.Dimension;
7 import java.awt.Insets;
8 import java.io.BufferedReader;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.InputStreamReader;
12 import java.io.OutputStream;
13 import java.io.PrintStream;
14 import java.io.UnsupportedEncodingException;
15 import java.io.Writer;
16 import java.lang.reflect.Field;
17 import java.lang.reflect.InvocationTargetException;
18 import java.lang.reflect.Method;
19 import javax.swing.JApplet;
20 import javax.swing.JFrame;
21 import javax.swing.JScrollPane;
22 import javax.swing.JSplitPane;
23 import javax.swing.JTextArea;
24 import javax.swing.event.DocumentEvent;
25 import javax.swing.event.DocumentListener;
26 import javax.swing.text.BadLocationException;
27 import jwutil.io.FillableReader;
28 import jwutil.io.ReaderInputStream;
29 import jwutil.reflect.Reflect;
30
31 /***
32 * AppletIO
33 *
34 * @author jwhaley
35 * @version $Id: AppletIO.java 2249 2005-04-29 02:32:27Z joewhaley $
36 */
37 public class AppletIO extends JApplet {
38
39 /***
40 * Version ID for serialization.
41 */
42 private static final long serialVersionUID = 4121128139021169972L;
43
44 public static String DEFAULT_ENCODING = "UTF-8";
45
46 /***
47 * AppletWriter takes anything written to it and puts it in the output area.
48 *
49 * @author jwhaley
50 * @version $Id: AppletIO.java 2249 2005-04-29 02:32:27Z joewhaley $
51 */
52 public class AppletWriter extends Writer {
53
54
55
56 public void write(char[] cbuf, int off, int len) throws IOException {
57 if (len == 0) {
58 return;
59 }
60 String str = new String(cbuf, off, len);
61 outputArea.append(str);
62 jumpToEndOfOutput();
63 }
64
65
66
67
68 public void flush() throws IOException {
69
70 }
71
72
73
74
75 public void close() throws IOException {
76
77 }
78 }
79
80 /***
81 * AppletOutputStream takes anything written to it and puts it in the output
82 * area.
83 *
84 * TODO: The write() method doesn't handle multibyte characters correctly.
85 * If you want correct usage of multibyte characters, use AppletWriter
86 * instead.
87 *
88 * @author jwhaley
89 * @version $Id: AppletIO.java 2249 2005-04-29 02:32:27Z joewhaley $
90 */
91 public class AppletOutputStream extends OutputStream {
92
93
94
95
96 public void write(int b) throws IOException {
97 outputArea.append(new String(new byte[]{(byte) b}));
98 jumpToEndOfOutput();
99 }
100
101
102
103
104 public void write(byte b[], int off, int len) throws IOException {
105 if (len == 0) {
106 return;
107 }
108 String str = new String(b, off, len, DEFAULT_ENCODING);
109 outputArea.append(str);
110 jumpToEndOfOutput();
111 }
112 }
113
114 /***
115 * Listens for newline inputs in the input area, and sends that line
116 * to inputWriter.
117 *
118 * @author jwhaley
119 * @version $Id: AppletIO.java 2249 2005-04-29 02:32:27Z joewhaley $
120 */
121 public class TextAreaListener implements DocumentListener {
122
123
124
125
126 public void insertUpdate(DocumentEvent e) {
127 int length = e.getLength();
128 if (length == 0) return;
129 int offset = e.getOffset();
130 try {
131 String s = inputArea.getText(offset, length);
132 int i;
133 while ((i = s.indexOf('\n')) >= 0) {
134 int lineNum = inputArea.getLineOfOffset(offset);
135 int sOff = inputArea.getLineStartOffset(lineNum);
136 int eOff = inputArea.getLineEndOffset(lineNum);
137 String line = inputArea.getText(sOff, eOff - sOff);
138 if (outputArea != null) {
139 outputArea.append(line);
140 jumpToEndOfOutput();
141 }
142 if (inputWriter != null) {
143 inputWriter.write(line);
144 }
145 offset = eOff;
146 s = s.substring(i + 1);
147 }
148 } catch (IOException x) {
149 x.printStackTrace();
150 } catch (BadLocationException x) {
151 x.printStackTrace();
152 }
153 }
154
155
156
157
158 public void removeUpdate(DocumentEvent e) {
159
160 }
161
162
163
164
165 public void changedUpdate(DocumentEvent e) {
166
167 }
168 }
169
170 /***
171 * Scroll to the end of the output area.
172 */
173 public void jumpToEndOfOutput() {
174 outputArea.setCaretPosition(outputArea.getDocument().getLength());
175 }
176
177 JTextArea outputArea;
178 JTextArea inputArea;
179 Writer inputWriter;
180 Method method;
181 Object[] methodArgs;
182
183 protected void loadAppletParameters() {
184
185 String className = getParameter("class");
186 String methodName = getParameter("method");
187 if (methodName == null) methodName = "main";
188 method = Reflect.getDeclaredMethod(className, methodName);
189 Class[] pTypes = method.getParameterTypes();
190 methodArgs = new Object[pTypes.length];
191 Object[] args;
192 if (pTypes.length == 1 && pTypes[0] == String[].class) {
193 int nParams = 0;
194 while (getParameter("arg"+nParams) != null)
195 ++nParams;
196 methodArgs[0] = args = new String[nParams];
197 } else {
198 args = methodArgs;
199 }
200 for (int i = 0; i < args.length; ++i) {
201 String arg = getParameter("arg"+i);
202 args[i] = arg;
203 }
204 }
205
206 public void init() {
207 loadAppletParameters();
208
209
210
211 try {
212 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
213 public void run() {
214 PrintStream out = createGUI();
215 launch(out, method, methodArgs);
216 }
217 });
218 } catch (Exception e) {
219 System.err.println("createGUI didn't successfully complete");
220 }
221 }
222
223 PrintStream createGUI() {
224 outputArea = new JTextArea();
225 outputArea.setMargin(new Insets(5, 5, 5, 5));
226 outputArea.setEditable(false);
227 inputArea = new JTextArea();
228 inputArea.setMargin(new Insets(5, 5, 5, 5));
229 JScrollPane top = new JScrollPane(outputArea);
230 JScrollPane bottom = new JScrollPane(inputArea,
231 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
232 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
233 JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, top, bottom);
234
235 splitPane.setResizeWeight(1.0);
236 getContentPane().add(splitPane);
237
238 Dimension minimumSize = new Dimension(400, 40);
239 top.setMinimumSize(minimumSize);
240 bottom.setMinimumSize(minimumSize);
241 bottom.setPreferredSize(minimumSize);
242
243 DocumentListener myListener = new TextAreaListener();
244 inputArea.getDocument().addDocumentListener(myListener);
245
246 try {
247 InputStream in;
248 FillableReader fin = new FillableReader();
249 inputWriter = fin.getWriter();
250 in = new ReaderInputStream(fin);
251
252
253 PrintStream out, err;
254 try {
255 err = out = new PrintStream(new AppletOutputStream(), true, DEFAULT_ENCODING);
256 } catch (NoSuchMethodError _) {
257 err = out = new PrintStream(new AppletOutputStream(), true);
258 }
259 try {
260 System.setOut(out);
261 System.setErr(err);
262
263 System.setIn(in);
264 } catch (SecurityException x) {
265
266 x.printStackTrace();
267 initStreams(method.getDeclaringClass(), in, out, err);
268 }
269 return out;
270 } catch (UnsupportedEncodingException x) {
271 outputArea.append(x.toString());
272 x.printStackTrace();
273 return null;
274 }
275 }
276
277 public static void main(String[] s) throws SecurityException,
278 NoSuchMethodException, ClassNotFoundException {
279 AppletIO applet = new AppletIO();
280
281 if (s.length < 1) {
282 applet.method = AppletIO.class.getDeclaredMethod("example", new Class[0]);
283 applet.methodArgs = new Object[0];
284 } else {
285 applet.method = Class.forName(s[0]).getDeclaredMethod("main",
286 new Class[]{String[].class});
287 String[] s2 = new String[s.length - 1];
288 System.arraycopy(s, 1, s2, 0, s2.length);
289 applet.methodArgs = new Object[]{s2};
290 }
291
292 JFrame f = new JFrame();
293 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
294 f.getContentPane().add(applet);
295 f.setSize(500, 400);
296 f.setLocation(200, 200);
297 applet.createGUI();
298 f.setVisible(true);
299
300 System.out.println("Starting " + applet.method.getDeclaringClass().getName()+
301 "."+applet.method.getName()+"()");
302 launch(System.out, applet.method, applet.methodArgs);
303 }
304
305 public static void initStreams(Class c, InputStream in, PrintStream out, PrintStream err) {
306 Field f;
307 try {
308 f = c.getDeclaredField("in");
309 f.set(null, in);
310 }
311 catch (NoSuchFieldException _) {}
312 catch (IllegalAccessException _) {}
313 try {
314 f = c.getDeclaredField("out");
315 f.set(null, out);
316 }
317 catch (NoSuchFieldException _) {}
318 catch (IllegalAccessException _) {}
319 try {
320 f = c.getDeclaredField("err");
321 f.set(null, err);
322 }
323 catch (NoSuchFieldException _) {}
324 catch (IllegalAccessException _) {}
325 }
326
327 public static void launch(final PrintStream out, final Method m, final Object[] args) {
328 new Thread() {
329 public void run() {
330 try {
331 m.invoke(null, args);
332 } catch (InvocationTargetException e) {
333 e.getTargetException().printStackTrace();
334 } catch (IllegalArgumentException e) {
335 e.printStackTrace();
336 } catch (IllegalAccessException e) {
337 e.printStackTrace();
338 } finally {
339 if (out != null) out.println("Terminated.");
340 }
341 }
342 }.start();
343 }
344
345
346 public static void example() {
347 try {
348 BufferedReader in = new BufferedReader(new InputStreamReader(
349 System.in, DEFAULT_ENCODING));
350 for (;;) {
351 String s = in.readLine();
352 System.out.println("IN: " + s);
353 }
354 } catch (IOException x) {
355 x.printStackTrace();
356 }
357 }
358 }