1
2
3
4
5
6
7
8
9
10
11 package de.jaret.util.ui.console;
12
13 import java.io.IOException;
14 import java.io.OutputStream;
15 import java.io.PrintStream;
16 import java.util.ArrayList;
17 import java.util.Iterator;
18 import java.util.List;
19
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.custom.StyledText;
22 import org.eclipse.swt.custom.VerifyKeyListener;
23 import org.eclipse.swt.events.VerifyEvent;
24 import org.eclipse.swt.layout.FillLayout;
25 import org.eclipse.swt.widgets.Composite;
26
27
28
29
30
31
32
33
34 public class ConsoleControl extends Composite implements VerifyKeyListener {
35 private List _enteredLines = new ArrayList();
36 private int _currentEnteredLineIdx = -1;
37 private List _listeners;
38 private String _prompt;
39 private int _promptEndIdx;
40 private int _promptEndOffset;
41 private StyledText _styledText;
42
43
44
45
46
47
48
49
50
51 public ConsoleControl(Composite parent, int style, String prompt, String message) {
52 super(parent, style);
53 _prompt = prompt;
54 createControls();
55 if (message != null && message.length() > 0) {
56 _styledText.append(message);
57 _styledText.setCaretOffset(_styledText.getCharCount());
58 writePrompt(true);
59 } else {
60 writePrompt(false);
61 }
62 }
63
64
65
66
67 private void createControls() {
68 setLayout(new FillLayout());
69 _styledText = new StyledText(this, SWT.WRAP | SWT.V_SCROLL | SWT.H_SCROLL);
70 _styledText.addVerifyKeyListener(this);
71 }
72
73
74
75
76
77
78 private void writePrompt(boolean newLine) {
79 if (newLine) {
80 _styledText.append(_styledText.getLineDelimiter());
81 }
82 _styledText.append(_prompt + " ");
83 _promptEndIdx = _prompt.length() + 1;
84 _promptEndOffset = _styledText.getCaretOffset() + _promptEndIdx + _styledText.getLineDelimiter().length();
85 _styledText.setCaretOffset(_promptEndOffset);
86 _styledText.showSelection();
87 }
88
89
90
91
92
93
94 private int offsetInLine() {
95 int caretOffset = _styledText.getCaretOffset();
96 int lineidx = _styledText.getLineAtOffset(caretOffset);
97 int lineoffset = _styledText.getOffsetAtLine(lineidx);
98 int posInLine = caretOffset - lineoffset;
99 return posInLine;
100 }
101
102
103
104
105
106
107 private String getEnteredLine() {
108 if (_promptEndOffset <= _styledText.getCharCount() - 1) {
109 return _styledText.getText(_promptEndOffset, _styledText.getCharCount() - 1);
110 } else {
111 return null;
112 }
113 }
114
115
116
117
118
119
120 public void setPrompt(String prompt) {
121 _prompt = prompt;
122 }
123
124
125
126
127
128
129 public String getPrompt() {
130 return _prompt;
131 }
132
133
134
135
136
137
138 public void addConsoleListener(ConsoleListener listener) {
139 if (_listeners == null) {
140 _listeners = new ArrayList();
141 }
142 _listeners.add(listener);
143 }
144
145
146
147
148
149
150 public void remConsoleListener(ConsoleListener listener) {
151 if (_listeners != null) {
152 _listeners.remove(listener);
153 }
154 }
155
156
157
158
159
160
161
162
163 protected String fireLineEntered(String line) {
164 if (_listeners != null) {
165 StringBuffer result = new StringBuffer();
166 Iterator it = _listeners.iterator();
167 while (it.hasNext()) {
168 ConsoleListener listener = (ConsoleListener) it.next();
169 String r = listener.lineEntered(this, line);
170 if (r != null) {
171 result.append(r);
172 }
173 }
174 return result.toString();
175 } else {
176 return null;
177 }
178 }
179
180
181
182
183
184
185 public void verifyKey(VerifyEvent verifyEvent) {
186 switch (verifyEvent.keyCode) {
187 case SWT.ARROW_LEFT:
188 case SWT.BS:
189 System.out.println("left " + _promptEndIdx + " " + offsetInLine());
190 if (offsetInLine() <= _promptEndIdx) {
191 System.out.println("ignore");
192 verifyEvent.doit = false;
193 }
194 break;
195 case SWT.ARROW_UP:
196 int idx = _currentEnteredLineIdx - 1;
197 if (idx >= 0) {
198 replaceEnteredLineWith((String) _enteredLines.get(idx));
199 _currentEnteredLineIdx = idx;
200 }
201 verifyEvent.doit = false;
202 break;
203 case SWT.ARROW_DOWN:
204 int idx2 = _currentEnteredLineIdx + 1;
205 if (idx2 <= _enteredLines.size() - 1) {
206 replaceEnteredLineWith((String) _enteredLines.get(idx2));
207 _currentEnteredLineIdx = idx2;
208 }
209 verifyEvent.doit = false;
210 break;
211 case SWT.CR:
212 String line = getEnteredLine();
213 _styledText.setCaretOffset(_styledText.getCharCount());
214 if (line != null) {
215 _enteredLines.add(line);
216 _currentEnteredLineIdx = _enteredLines.size();
217 String result = fireLineEntered(line);
218 if (result != null && result.length() > 0) {
219 _styledText.append(_styledText.getLineDelimiter());
220 _styledText.append(result);
221 _styledText.setCaretOffset(_styledText.getCharCount());
222 }
223 } else {
224
225 }
226 writePrompt(true);
227 verifyEvent.doit = false;
228 break;
229
230 default:
231 break;
232 }
233 }
234
235
236
237
238
239
240 public void output(String text) {
241 _styledText.append(text);
242 _styledText.setCaretOffset(_styledText.getCaretOffset() + text.length());
243 _styledText.showSelection();
244 }
245
246
247
248
249
250
251 public PrintStream getPrintStream() {
252 return new PrintStream(new ConsoleOutStream(this));
253 }
254
255
256
257
258
259
260 private void replaceEnteredLineWith(String string) {
261 _styledText.replaceTextRange(_promptEndOffset, _styledText.getCharCount() - _promptEndOffset, string);
262 _styledText.setCaretOffset(_styledText.getCharCount());
263 }
264
265
266
267
268
269
270 public class ConsoleOutStream extends OutputStream {
271 ConsoleControl _consoleControl;
272
273
274
275
276 public ConsoleOutStream(ConsoleControl control) {
277 super();
278 _consoleControl = control;
279 }
280
281
282
283
284
285
286 public void write(int b) throws IOException {
287 _consoleControl.output("" + (char) b);
288 }
289 }
290
291 }