sclass Chat { JTextArea chatArea = wrappedTextArea(); new JTextField chatField; Runnable onEnter_pre, onEnter_post; bool showTimestamps = true; O timeFormatter; File logFile; // I/O Android3 android; bool monitored, hijacked; *() { onEnter(chatField, runnable { pcallFunction(onEnter_pre); append(formatLine(chatField.getText()) + "\n"); chatField.selectAll(); pcallFunction(onEnter_post); }); } void requestFocus { chatField.requestFocus(); } JComponent swing() { appendToFile(logFile, "\n"); final JComponent c = withTitle("Chat", centerAndSouth(chatArea, chatField)); ret bindToComponent(c, r { android = makeAndroid3("Swing Chat", makeResponder(new O { S answer(S s) { ret Chat.this.answer(s, c); } })); print("Vport: " + android.vport); }, r { print("Disposing chat android"); android.dispose(); }); } // override me if you freaking like S formatLine(S line) { ret "Usr: " + line; } void append(S s) { if (showTimestamps) s = formatTime() + " " + s; chatArea.append(s); if (logFile != null) appendToFile(logFile, s); } S formatTime() { if (timeFormatter != null) ret (S) callFunction(timeFormatter); ret "[" + formatInt(month(), 2) + "/" + formatInt(days(), 2) + " " + formatInt(hours(), 2) + ":" + formatInt(minutes(), 2) + ":" + formatInt(seconds(), 2) + "]"; } S input() { ret chatField.getText().trim(); } void setInput(S s) { chatField.setText(s); chatField.selectAll(); } S answer(S s, JComponent c) { new Matches m; if "set input: *" { setInput(m.unq(0)); set hijacked; ret "ok"; } if "get input" { set monitored; ret format("ok: *", input()); } if "set text: *" { chatArea.setText(m.unq(0)); set hijacked; ret "ok"; } if "append: *" { append(m.unq(0)); set hijacked; ret "ok"; } if "get text" { set monitored; ret format("ok: *", chatArea.getText()); } if "set input cursor: * to *" { chatField.select(m.psi(0), m.psi(1)); set hijacked; ret "ok"; } if "window title" { set monitored; ret getFrameTitle(c); } if "set window title: *" { setFrameTitle(c, m.unq(0)); set hijacked; ret "ok"; } if "is window focused" { set monitored; ret yn(getFrame(c).isFocused()); } null; } }