KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > DefaultTextFieldHandler


1 /*
2  * DefaultTextFieldHandler.java
3  *
4  * Copyright (C) 1998-2003 Peter Graves
5  * $Id: DefaultTextFieldHandler.java,v 1.4 2003/07/18 15:23:41 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import java.awt.Color JavaDoc;
25 import java.awt.Container JavaDoc;
26 import java.awt.event.ActionEvent JavaDoc;
27 import java.awt.event.ActionListener JavaDoc;
28 import java.awt.event.KeyEvent JavaDoc;
29 import java.awt.event.TextEvent JavaDoc;
30 import java.awt.event.TextListener JavaDoc;
31 import java.util.List JavaDoc;
32 import javax.swing.JDialog JavaDoc;
33 import javax.swing.JMenuItem JavaDoc;
34 import javax.swing.JPopupMenu JavaDoc;
35
36 public class DefaultTextFieldHandler implements Constants, TextFieldHandler
37 {
38     protected final Editor editor;
39     protected final HistoryTextField textField;
40
41     protected List JavaDoc completions;
42     protected int index;
43
44     private Expansion expansion;
45     private String JavaDoc savedText;
46     private String JavaDoc head;
47
48     public DefaultTextFieldHandler(Editor editor, HistoryTextField textField)
49     {
50         this.editor = editor;
51         Debug.assertTrue(editor != null);
52         this.textField = textField;
53     }
54
55     public DefaultTextFieldHandler(HistoryTextField textField)
56     {
57         this(Editor.currentEditor(), textField);
58     }
59
60     public void enter()
61     {
62     }
63
64     public void escape()
65     {
66         Container JavaDoc c = textField.getParent();
67         while (true) {
68             if (c instanceof JDialog JavaDoc)
69                 return;
70             if (c == null)
71                 break;
72             c = c.getParent();
73         }
74         // Text field is not in a dialog box. We must be dealing with the
75
// location bar.
76
Debug.assertTrue(editor != null);
77         editor.ensureActive();
78         editor.setFocusToDisplay();
79         editor.updateLocation();
80     }
81
82     public boolean wantTab()
83     {
84         return false;
85     }
86
87     public void tab()
88     {
89         if (textField != null) {
90             String JavaDoc prefix = textField.getText();
91             String JavaDoc s = getCompletion(prefix);
92             if (s != null && !s.equals(prefix)) {
93                 textField.setText(s);
94                 textField.setCaretPosition(s.length());
95             }
96         }
97     }
98
99     public void shiftTab()
100     {
101         if (textField != null) {
102             String JavaDoc s = getPreviousCompletion();
103             if (s != null) {
104                 String JavaDoc text = textField.getText();
105                 if (!s.equals(text)) {
106                     textField.setText(s);
107                     textField.setCaretPosition(s.length());
108                 }
109             }
110         }
111     }
112
113     public void resetCompletions()
114     {
115         completions = null;
116     }
117
118     protected String JavaDoc getCompletion(String JavaDoc prefix)
119     {
120         if (completions == null) {
121             completions = getCompletions(prefix);
122             index = 0;
123         }
124         if (completions == null || completions.size() == 0)
125             return null;
126         if (index >= completions.size())
127             index = 0;
128         return (String JavaDoc) completions.get(index++);
129     }
130
131     private String JavaDoc getPreviousCompletion()
132     {
133         if (completions != null && completions.size() > 1) {
134             index -= 2;
135             if (index < 0)
136                 index += completions.size();
137             return (String JavaDoc) completions.get(index++);
138         }
139         return null;
140     }
141
142     public List JavaDoc getCompletions(String JavaDoc prefix)
143     {
144         return null;
145     }
146
147     private void killLine()
148     {
149         textField.setText(textField.getText().substring(0, textField.getCaretPosition()));
150     }
151
152     private void expand()
153     {
154         if (expansion == null) {
155             // New expansion.
156
savedText = textField.getText();
157             int index = savedText.lastIndexOf(' ');
158             if (index >= 0) {
159                 head = savedText.substring(0, index+1);
160                 expansion = textField.getHandler().getExpansion(savedText.substring(index+1));
161             } else {
162                 Debug.assertTrue(head == null);
163                 expansion = textField.getHandler().getExpansion(savedText);
164             }
165         }
166         final String JavaDoc candidate = expansion.getNextCandidate();
167         if (candidate != null) {
168             if (head != null)
169                 textField.setText(head.concat(candidate));
170             else
171                 textField.setText(candidate);
172         }
173     }
174
175     public void resetExpansion()
176     {
177         expansion = null;
178         savedText = null;
179         head = null;
180     }
181
182     public Expansion getExpansion(String JavaDoc prefix)
183     {
184         return new Expansion(editor.getBuffer(), prefix, prefix);
185     }
186
187     protected void reset()
188     {
189         textField.resetHistory();
190         textField.getHandler().resetCompletions();
191     }
192
193     public void keyPressed(KeyEvent JavaDoc e)
194     {
195         TextFieldHandler handler = textField.getHandler();
196         if (handler == null)
197             return;
198         if (handler != this)
199             Debug.bug();
200         final char keyChar = e.getKeyChar();
201         final int keyCode = e.getKeyCode();
202         final int modifiers = e.getModifiers();
203         switch (keyCode) {
204             case KeyEvent.VK_ENTER:
205                 resetExpansion();
206                 // Make sure user can see what he typed.
207
textField.paintImmediately(0, 0, textField.getWidth(), textField.getHeight());
208                 e.consume();
209                 handler.enter();
210                 return;
211             case KeyEvent.VK_ESCAPE:
212                 if (expansion != null) {
213                     // Cancel expansion.
214
textField.setText(savedText);
215                     resetExpansion();
216                     // Consume key event so parent will ignore it.
217
e.consume();
218                 } else
219                     handler.escape();
220                 return;
221             case KeyEvent.VK_TAB:
222                 resetExpansion();
223                 if (handler.wantTab()) {
224                     if (modifiers == 0) {
225                         e.consume();
226                         handler.tab();
227                     } else if (modifiers == SHIFT_MASK) {
228                         e.consume();
229                         handler.shiftTab();
230                     }
231                 }
232                 return;
233             case KeyEvent.VK_UP:
234             case KeyEvent.VK_KP_UP:
235                 resetExpansion();
236                 textField.previousHistory();
237                 return;
238             case KeyEvent.VK_P:
239                 resetExpansion();
240                 if (modifiers == CTRL_MASK)
241                     textField.previousHistory();
242                 else
243                     reset();
244                 return;
245             case KeyEvent.VK_DOWN:
246             case KeyEvent.VK_KP_DOWN:
247                 resetExpansion();
248                 if (modifiers == ALT_MASK)
249                     showPopup();
250                 else
251                     textField.nextHistory();
252                 return;
253             case KeyEvent.VK_N:
254                 resetExpansion();
255                 if (modifiers == CTRL_MASK)
256                     textField.nextHistory();
257                 else
258                     reset();
259                 return;
260             case KeyEvent.VK_SHIFT:
261             case KeyEvent.VK_CONTROL:
262             case KeyEvent.VK_META:
263             case KeyEvent.VK_ALT:
264                 return;
265             default:
266                 reset();
267                 break;
268         }
269         KeyMapping mapping = editor.getKeyMapping(keyChar, keyCode, modifiers);
270         if (mapping != null) {
271             Object JavaDoc command = mapping.getCommand();
272             if (command == "killLine")
273                 killLine();
274             else if (command == "expand") {
275                 expand();
276                 return; // Don't call resetExpansion()!
277
}
278         }
279         resetExpansion();
280     }
281
282     public void keyReleased(KeyEvent JavaDoc e)
283     {
284         TextListener JavaDoc textListener = textField.getTextListener();
285         if (textListener != null)
286             textListener.textValueChanged(new TextEvent JavaDoc(this, TextEvent.TEXT_VALUE_CHANGED));
287     }
288
289     public void keyTyped(KeyEvent JavaDoc e) {}
290
291     private void showPopup()
292     {
293         if (textField == null)
294             return;
295         History history = textField.getHistory();
296         if (history == null)
297             return;
298         final String JavaDoc existing = textField.getText();
299         JPopupMenu JavaDoc popup = null;
300         for (int i = history.size(); i-- > 0;) {
301             String JavaDoc s = history.get(i);
302             if (s.equals(existing))
303                 continue;
304             if (popup == null)
305                 popup = new JPopupMenu JavaDoc();
306             JMenuItem JavaDoc menuItem = new JMenuItem JavaDoc();
307             menuItem.setText(history.get(i));
308             menuItem.setActionCommand(s);
309             menuItem.addActionListener(popupActionListener);
310             popup.add(menuItem);
311         }
312         if (popup != null)
313             popup.show(textField, 0, textField.getHeight());
314     }
315
316     private ActionListener JavaDoc popupActionListener = new ActionListener JavaDoc() {
317         public void actionPerformed(ActionEvent JavaDoc e)
318         {
319             textField.setText(e.getActionCommand());
320             enter();
321         }
322     };
323 }
324
Popular Tags