001: /*
002: * @(#)PnutsConsoleUI.java 1.1 05/05/16
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.tools;
010:
011: import java.util.*;
012: import java.net.URL;
013: import java.awt.Image;
014: import java.awt.Font;
015: import java.awt.Toolkit;
016: import java.awt.event.KeyEvent;
017: import java.awt.event.KeyListener;
018: import java.awt.event.WindowAdapter;
019: import java.awt.event.WindowEvent;
020: import javax.swing.*;
021: import javax.swing.event.DocumentEvent;
022: import javax.swing.event.DocumentListener;
023: import javax.swing.text.BadLocationException;
024: import javax.swing.text.Document;
025: import pnuts.lang.Context;
026:
027: /**
028: * Swing based UI
029: */
030: public class PnutsConsoleUI extends JTextComponentConsoleUI {
031:
032: final static String ICON_RESOURCE = "pnuts16.png";
033:
034: Vector history = new Vector();
035: int historyIndex = -1;
036: JFrame frame;
037: JComponent component;
038: String title;
039:
040: public PnutsConsoleUI() {
041: this (null);
042: }
043:
044: public PnutsConsoleUI(Console console) {
045: setModel(console);
046: EventHandler handler = new EventHandler();
047: JTextArea textarea = (JTextArea) textComponent;
048: textarea.addKeyListener(handler);
049: textarea.getDocument().addDocumentListener(handler);
050: }
051:
052: public PnutsConsole createConsole(Context context, String inputlog) {
053: return createConsole(null, context, null, inputlog, true, null,
054: Thread.NORM_PRIORITY);
055: }
056:
057: protected PnutsConsole createConsole() {
058: return new PnutsConsole();
059: }
060:
061: public PnutsConsole createConsole(String[] modules,
062: Context context, ClassLoader cl, String inputlog,
063: boolean greeting, Runnable terminationCallback, int priority) {
064: Context cc;
065: if (context != null) {
066: cc = context;
067: } else {
068: cc = new CancelableContext();
069: }
070: if (cl != null) {
071: cc.setClassLoader(cl);
072: }
073: if (modules != null) {
074: for (int i = 0; i < modules.length; i++) {
075: cc.usePackage(modules[i]);
076: }
077: }
078: PnutsConsole console = createConsole();
079: setModel(console);
080: console.setContext(cc);
081: console.setInputLog(inputlog);
082: console.setGreeting(greeting);
083: console.setClassLoader(cl);
084: console.setPriority(priority);
085: console.setTerminationCallback(terminationCallback);
086: console.setConsoleUI(this );
087: return console;
088: }
089:
090: public void entered(String command) {
091: if (command != null && command.length() > 0) {
092: history.add(command);
093: }
094: historyIndex = history.size();
095: }
096:
097: public JTextArea getTextArea() {
098: return (JTextArea) textComponent;
099: }
100:
101: public JComponent getComponent() {
102: if (this .component == null) {
103: this .component = new JScrollPane(textComponent);
104: }
105: return this .component;
106: }
107:
108: public void setTitle(String title) {
109: this .title = title;
110: }
111:
112: public String getTitle() {
113: return this .title;
114: }
115:
116: public JFrame getFrame() {
117: if (frame == null) {
118: frame = new JFrame(title);
119: frame.setContentPane(getComponent());
120: frame.setSize(textComponent.getPreferredSize());
121: URL imageURL = PnutsConsole.class
122: .getResource(ICON_RESOURCE);
123: if (imageURL != null) {
124: Image iconImage = Toolkit.getDefaultToolkit().getImage(
125: imageURL);
126: if (iconImage != null) {
127: frame.setIconImage(iconImage);
128: }
129: }
130: frame.addWindowListener(new WindowAdapter() {
131: public void windowClosing(WindowEvent e) {
132: ((PnutsConsole) model).dispose();
133: }
134: });
135: }
136: ;
137: return frame;
138: }
139:
140: void largerFont() {
141: Font font = textComponent.getFont();
142: int size = font.getSize() + 1;
143: textComponent.setFont(font.deriveFont((float) size));
144: }
145:
146: void smallerFont() {
147: Font font = textComponent.getFont();
148: int size = font.getSize() - 1;
149: if (size < 1) {
150: size = 1;
151: }
152: textComponent.setFont(font.deriveFont((float) size));
153: }
154:
155: public void close() {
156: if (frame != null) {
157: frame.dispose();
158: }
159: }
160:
161: class EventHandler implements KeyListener, DocumentListener {
162:
163: public void keyPressed(KeyEvent e) {
164: int code = e.getKeyCode();
165: char ch = e.getKeyChar();
166: boolean control = e.isControlDown();
167:
168: int pos = textComponent.getCaretPosition();
169: if (code == KeyEvent.VK_BACK_SPACE
170: || code == KeyEvent.VK_LEFT) {
171: if (mark == pos) {
172: e.consume();
173: }
174: } else if (control && code == KeyEvent.VK_A) {
175: textComponent.setCaretPosition(mark);
176: e.consume();
177: } else if (control && code == KeyEvent.VK_E) {
178: textComponent.setCaretPosition(textComponent
179: .getDocument().getLength());
180: e.consume();
181: } else if (control && code == KeyEvent.VK_B) {
182: if (mark < pos) {
183: textComponent.setCaretPosition(pos - 1);
184: }
185: e.consume();
186: } else if (control && code == KeyEvent.VK_D) {
187: Document doc = textComponent.getDocument();
188: if (pos < doc.getLength()) {
189: try {
190: doc.remove(pos, 1);
191: } catch (BadLocationException ble) {
192: ble.printStackTrace();
193: }
194: }
195: e.consume();
196: } else if (control && code == KeyEvent.VK_F) {
197: if (textComponent.getDocument().getLength() > pos) {
198: textComponent.setCaretPosition(pos + 1);
199: }
200: e.consume();
201: } else if (control && code == KeyEvent.VK_K) {
202: Document doc = textComponent.getDocument();
203: try {
204: doc.remove(pos, doc.getLength() - pos);
205: } catch (BadLocationException ble) {
206: ble.printStackTrace();
207: }
208: e.consume();
209: } else if (control && code == KeyEvent.VK_U) {
210: Document doc = textComponent.getDocument();
211: try {
212: doc.remove(mark, doc.getLength() - mark);
213: } catch (BadLocationException ble) {
214: ble.printStackTrace();
215: }
216: e.consume();
217: } else if (control && ch == '+') {
218: largerFont();
219: e.consume();
220: } else if (control
221: && (ch == '-' || code == KeyEvent.VK_MINUS)) {
222: smallerFont();
223: e.consume();
224: } else if (code == KeyEvent.VK_HOME
225: || (control && code == KeyEvent.VK_A)) {
226: if (pos == mark) {
227: e.consume();
228: } else if (pos > mark) {
229: if (!control) {
230: if (e.isShiftDown()) {
231: textComponent.moveCaretPosition(mark);
232: } else {
233: textComponent.setCaretPosition(mark);
234: }
235: e.consume();
236: }
237: }
238: } else if (code == KeyEvent.VK_ENTER) {
239: enter();
240: e.consume();
241: } else if (code == KeyEvent.VK_UP
242: || (control && code == KeyEvent.VK_P)) {
243: historyIndex--;
244: if (historyIndex >= 0) {
245: if (historyIndex >= history.size()) {
246: historyIndex = history.size() - 1;
247: }
248: if (historyIndex >= 0) {
249: String str = (String) history
250: .elementAt(historyIndex);
251: int len = textComponent.getDocument()
252: .getLength();
253: ((JTextArea) textComponent).replaceRange(str,
254: mark, len);
255: int caretPos = mark + str.length();
256: textComponent.select(caretPos, caretPos);
257: } else {
258: historyIndex++;
259: }
260: } else {
261: historyIndex++;
262: }
263: e.consume();
264: } else if (code == KeyEvent.VK_DOWN
265: || (control && code == KeyEvent.VK_N)) {
266: int caretPos = mark;
267: if (history.size() > 0) {
268: historyIndex++;
269: if (historyIndex < 0) {
270: historyIndex = 0;
271: }
272: int len = textComponent.getDocument().getLength();
273: if (historyIndex < history.size()) {
274: String str = (String) history
275: .elementAt(historyIndex);
276: ((JTextArea) textComponent).replaceRange(str,
277: mark, len);
278: caretPos = mark + str.length();
279: } else {
280: historyIndex = history.size();
281: ((JTextArea) textComponent).replaceRange("",
282: mark, len);
283: }
284: }
285: textComponent.select(caretPos, caretPos);
286: e.consume();
287:
288: }
289: }
290:
291: public void keyTyped(KeyEvent e) {
292: int keyChar = e.getKeyChar();
293: if (keyChar == KeyEvent.VK_BACK_SPACE) {
294: if (mark == textComponent.getCaretPosition()) {
295: e.consume();
296: }
297: } else if (textComponent.getCaretPosition() < mark) {
298: textComponent.setCaretPosition(mark);
299: }
300: }
301:
302: public void keyReleased(KeyEvent e) {
303: }
304:
305: public void insertUpdate(DocumentEvent e) {
306: synchronized (PnutsConsoleUI.this ) {
307: int len = e.getLength();
308: int off = e.getOffset();
309: if (mark > off) {
310: mark += len;
311: }
312: }
313: }
314:
315: public void removeUpdate(DocumentEvent e) {
316: synchronized (PnutsConsoleUI.this ) {
317: int len = e.getLength();
318: int off = e.getOffset();
319: if (mark > off) {
320: if (mark >= off + len) {
321: mark -= len;
322: } else {
323: mark = off;
324: }
325: }
326: }
327: }
328:
329: public void changedUpdate(DocumentEvent e) {
330: }
331: }
332: }
|