KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > rero > gui > input > InputField


1 package rero.gui.input;
2
3 import rero.config.ClientDefaults;
4 import rero.config.ClientState;
5 import rero.config.ClientStateListener;
6 import text.AttributedString;
7 import text.AttributedText;
8 import text.ModifyColorMapDialog;
9 import text.TextSource;
10
11 import javax.swing.*;
12 import javax.swing.border.Border JavaDoc;
13 import javax.swing.border.CompoundBorder JavaDoc;
14 import javax.swing.text.AttributeSet JavaDoc;
15 import javax.swing.text.BadLocationException JavaDoc;
16 import javax.swing.text.Document JavaDoc;
17 import javax.swing.text.PlainDocument JavaDoc;
18 import java.awt.*;
19 import java.awt.event.*;
20 import java.util.ArrayList JavaDoc;
21 import java.util.LinkedList JavaDoc;
22 import java.util.ListIterator JavaDoc;
23
24 public class InputField extends JTextField implements KeyListener, ActionListener, MouseListener, ClientStateListener {
25   //protected InputList list = null;
26
protected Border JavaDoc defaultBorder;
27   protected LinkedList JavaDoc listeners;
28   protected UserInputEvent event;
29
30   // This is the command history for this InputField
31
// WARNING: Do not, under any circumstance, modify this structure.
32
// This will lead to a ConcurrentModificationException!
33
private ArrayList JavaDoc commandHistory;
34
35   // An iterator for the command history. This is what is actually
36
// used for manipulating the command history.
37
private ListIterator JavaDoc commandIterator;
38
39   // This is the maximum number of commands in the command history.
40
// TODO: This should be configurable.
41
private int maxCommands = 30;
42
43   // True if the key pressed in the previous keyevent was the upkey
44
// This flag is modified in a variety of places in the code.
45
private boolean previousKeyUpArrow = true;
46
47   protected InputBorder indent;
48
49   public void mouseClicked(MouseEvent ev) {
50     if (ev.getButton() == MouseEvent.BUTTON1 && ev.isShiftDown() && indent != null) {
51       AttributedText temp =
52         indent.getAttributes().getAttributesAt(ev.getX() - defaultBorder.getBorderInsets(this).left);
53
54       if (temp != null) {
55         if (temp.backIndex != -1 && ev.isControlDown()) {
56           ModifyColorMapDialog.showModifyColorMapDialog((JComponent) ev.getSource(), temp.backIndex);
57         } else {
58           ModifyColorMapDialog.showModifyColorMapDialog((JComponent) ev.getSource(), temp.foreIndex);
59         }
60         repaint();
61       }
62     }
63   }
64
65   public boolean isFocusable() {
66     return true;
67   }
68
69   public void mouseEntered(MouseEvent ev) {
70   }
71
72   public void mouseExited(MouseEvent ev) {
73   }
74
75   public void mousePressed(MouseEvent ev) {
76   }
77
78   public void mouseReleased(MouseEvent ev) {
79   }
80
81   public InputField() {
82     setUI(new javax.swing.plaf.basic.BasicTextFieldUI JavaDoc());
83
84     setOpaque(false);
85
86     defaultBorder =
87       BorderFactory.createEmptyBorder(1, TextSource.UNIVERSAL_TWEAK, 1, 1); // a 1 pixel empty border all around;
88
setBorder(defaultBorder);
89 /*
90        setBackground(null); // suggested by Sun as a fix to a background being painted problem
91                             // in the GTK+ look and feel, unfortunately it doesn't work... maybe it will when 1.5 comes out
92 */

93
94     addActionListener(this);
95     addKeyListener(this);
96
97     listeners = new LinkedList JavaDoc();
98
99     event = new UserInputEvent();
100     event.source = this;
101
102     indent = null;
103
104     addMouseListener(this);
105
106     rehashColors();
107
108     ClientState.getClientState().addClientStateListener("ui.editcolor", this);
109     ClientState.getClientState().addClientStateListener("ui.font", this);
110
111     // Instantiate the command history -oracel
112
this.commandHistory = new ArrayList JavaDoc(maxCommands + 1);
113     this.commandIterator = commandHistory.listIterator();
114
115   }
116
117   public void propertyChanged(String JavaDoc name, String JavaDoc parms) {
118     rehashColors();
119   }
120
121   public void rehashColors() {
122     Color temp = ClientState.getClientState().getColor("ui.editcolor", ClientDefaults.ui_editcolor);
123
124     setForeground(temp);
125     setCaretColor(temp.brighter());
126
127     setFont(ClientState.getClientState().getFont("ui.font", ClientDefaults.ui_font));
128
129     revalidate();
130   }
131
132   public void actionPerformed(ActionEvent ev) {
133     event.text = ev.getActionCommand();
134
135     if (event.text.length() <= 0) {
136       fireInputEvent(); // fire an empty input event, it helps sometimes
137
return;
138     }
139
140     fireInputEvent();
141   }
142
143   public void addInputListener(InputListener l) {
144     // we use addFirst for the following reasons... generally input fields will have two listeners
145
// the client itself will be listening and then there is a sort of master listener for all of the scripts.
146
// the client itself will of course register the listener first
147
// the master listener for scripts will register its listener second
148
// by firing listeners in a last in first fired manner the scripts will get a chance to halt the processing
149
// of the input event. These kinds of things can be tough to keep track of so that is why I write this
150
// comment.
151

152     listeners.addFirst(l);
153   }
154
155   public void fireInputEvent() {
156     ListIterator JavaDoc i = listeners.listIterator();
157
158     // Add text to history
159
this.addToHistory(event.text);
160
161     setText(""); // clear the textbox first, on input will receive the event information
162

163     while (i.hasNext()) {
164       InputListener temp = (InputListener) i.next();
165       temp.onInput(event);
166     }
167
168     this.resetIterator(false);
169
170     event.reset();
171   }
172
173   public String JavaDoc getIndent() {
174     if (indent != null) {
175       return indent.getText();
176     }
177
178     return "";
179   }
180
181   public void setIndent(String JavaDoc text) {
182     if (text != null) {
183       indent = new InputBorder(text);
184       setBorder(new CompoundBorder JavaDoc(defaultBorder, indent));
185     } else {
186       setBorder(defaultBorder);
187       indent = null;
188     }
189   }
190
191   public void keyTyped(KeyEvent e) {
192     //
193
// deal with problem of windows binging when hitting backspace in an empty buffer
194
//
195
if (e.getKeyChar() == KeyEvent.VK_BACK_SPACE && getText().length() == 0) {
196       e.consume();
197     }
198   }
199
200   public String JavaDoc getCurrentText() {
201     return getText();
202   }
203
204
205   public void keyPressed(KeyEvent e) {
206     //
207
// special built in control codes..
208
//
209
if (e.getModifiers() == 2) {
210       int caretpos = getCaretPosition() + 1;
211
212       switch (e.getKeyCode()) {
213         case 75: // control-k color
214
setText(getText().substring(0, getCaretPosition()) + AttributedString.color +
215             getText().substring(getCaretPosition(), getText().length()));
216           setCaretPosition(caretpos);
217           e.consume();
218           return;
219         case 85: // control-u underline
220
setText(getText().substring(0, getCaretPosition()) + AttributedString.underline +
221             getText().substring(getCaretPosition(), getText().length()));
222           setCaretPosition(caretpos);
223           e.consume();
224           return;
225         case 66: // control-b bold
226
setText(getText().substring(0, getCaretPosition()) + AttributedString.bold +
227             getText().substring(getCaretPosition(), getText().length()));
228           setCaretPosition(caretpos);
229           e.consume();
230           return;
231         case 79: // control-o cancel
232
setText(getText().substring(0, getCaretPosition()) + AttributedString.cancel +
233             getText().substring(getCaretPosition(), getText().length()));
234           setCaretPosition(caretpos);
235           e.consume();
236           return;
237         case 82: // control-r reverse
238
setText(getText().substring(0, getCaretPosition()) + AttributedString.reverse +
239             getText().substring(getCaretPosition(), getText().length()));
240           setCaretPosition(caretpos);
241           e.consume();
242           return;
243         default:
244       }
245     }
246
247     if (e.getKeyCode() == KeyEvent.VK_ENTER && e.getModifiers() != 0) {
248       this.resetIterator();
249       event.text = getText();
250       fireInputEvent();
251       e.consume();
252       return;
253     }
254
255     //
256
// deal with arrow up
257
//
258
if (e.getKeyCode() == KeyEvent.VK_UP) {
259
260       // See if there is an available command in list
261
if (commandIterator.hasPrevious()) {
262
263         // Store it
264
String JavaDoc previous = String.valueOf(commandIterator.previous());
265
266         // See if we should skip one forward
267
if (!previousKeyUpArrow && commandIterator.hasPrevious()) {
268           setText(String.valueOf(commandIterator.previous()));
269         }
270
271         // Set text from history
272
else {
273           setText(previous);
274         }
275
276       } else {
277         e.consume();
278       }
279
280       // Set flag
281
this.previousKeyUpArrow = true;
282     }
283
284     // deal with arrow down
285
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
286
287       // This will hold the next item in the list
288
String JavaDoc next;
289
290       // Check
291
if (commandIterator.hasNext()) {
292
293         // Special case check, user pressed up and down from empty
294
// command line
295
if (commandIterator.hasNext() &&
296           commandIterator.nextIndex() + 1 == commandHistory.size() &&
297           this.previousKeyUpArrow) {
298           // Clear the command textfield and reset iterator
299
resetIterator(false);
300           this.previousKeyUpArrow = true;
301           setText("");
302         }
303
304         // Not a special case
305
else {
306           // Fetch next item in command history (downwards)
307
next = String.valueOf(commandIterator.next());
308
309           // Semi-special case, user pressed up then down so
310
// we need to skip an item
311
if (previousKeyUpArrow && commandIterator.hasNext()) {
312             setText(String.valueOf(commandIterator.next()));
313           }
314
315           // Just set the text
316
else {
317             setText(next);
318           }
319
320           // Set flag (user pressed arrow down)
321
this.previousKeyUpArrow = false;
322         }
323       }
324
325       // No more items in history, clear the textfield and set flag
326
else {
327         setText("");
328         next = null;
329         this.previousKeyUpArrow = true;
330
331       }
332
333       // I'm not really sure what this is
334
e.consume();
335     }
336
337     // deal with ^K and other built in shortcuts
338
}
339
340   // Resets to the beginning of the command iterator
341
private void resetIterator() {
342     this.resetIterator(true);
343   }
344
345   // Reset the iterator to beginning (true) or end (false)
346
private void resetIterator(boolean resetToBeginning) {
347     if (resetToBeginning) {
348
349       // Reset to beginning
350
while (this.commandIterator.hasPrevious()) {
351         this.commandIterator.previous();
352       }
353
354     } else {
355
356       // Reset to end
357
while (this.commandIterator.hasNext()) {
358         this.commandIterator.next();
359       }
360
361     }
362   }
363
364
365   private void addToHistory(String JavaDoc text) {
366
367     // Add the text to the command history and remove redundant items
368
this.commandExistsInHistory(text, true); // Remove if it already exists
369
this.resetIterator(false); // Reset to end
370
this.commandIterator.add(text); // Append to end of list
371

372     // Check if the max size of the history has been reached
373
if (this.commandHistory.size() == (maxCommands + 1)
374       && (maxCommands > 0)) {
375
376       this.resetIterator(); // Reset to beginning
377
this.commandIterator.remove(); // Remove first item in list
378
this.resetIterator(false); // Reset to end
379
}
380   }
381
382
383   // Returns true if the command is found in the history. If the
384
// parameter <i>delete</i> is true, the command is deleted if found.
385
// This method offers O(n) performance.
386
private boolean commandExistsInHistory(String JavaDoc cmd, boolean delete) {
387
388     // Reset iterator to beginning
389
this.resetIterator();
390
391     // Iterate through the history from beginning to end
392
while (this.commandIterator.hasNext()) {
393       if (this.commandIterator.next().equals(cmd)) {
394
395         // Command was found
396
if (delete) {
397
398           // Remove it
399
this.commandIterator.remove();
400         }
401
402         // Return
403
return true;
404       }
405     }
406
407     // Not found
408
return false;
409   }
410
411   public void keyReleased(KeyEvent e) {
412   }
413
414   public void paint(Graphics g) {
415     TextSource.initGraphics(g);
416     super.paint(g);
417   }
418
419   protected Document JavaDoc createDefaultModel() {
420     return new InputDocument();
421   }
422
423   class InputDocument extends PlainDocument JavaDoc {
424     public void insertString(int offs, String JavaDoc str, AttributeSet JavaDoc a) throws BadLocationException JavaDoc {
425       if (str.indexOf('\n') == -1) {
426 // super.insertString(offs, str, a);
427
super.insertString(offs, str, a);
428         return;
429       }
430
431       while (str.indexOf('\n') > -1) {
432         event.text = str.substring(0, str.indexOf('\n'));
433         // @Serge: multiple lines may appear in the input field due to paste.
434
// First line from the pasted text should be inserted into the
435
// current position and then the whole line should be processed,
436
// otherwise current field text will be lost!
437
if (getCurrentText().length() > 0) {
438           super.insertString(offs, event.text, a);
439           event.text = getCurrentText();
440         }
441
442         fireInputEvent();
443
444         if (str.indexOf('\n') == str.length()) {
445           return;
446         } else {
447           str = str.substring(str.indexOf('\n') + 1, str.length());
448         }
449       }
450
451       if (str.length() > 0) {
452         event.text = str;
453         fireInputEvent();
454       }
455     }
456   }
457 }
458
Popular Tags