1 21 22 package org.armedbear.j; 23 24 import java.awt.Color ; 25 import java.awt.Container ; 26 import java.awt.event.ActionEvent ; 27 import java.awt.event.ActionListener ; 28 import java.awt.event.KeyEvent ; 29 import java.awt.event.TextEvent ; 30 import java.awt.event.TextListener ; 31 import java.util.List ; 32 import javax.swing.JDialog ; 33 import javax.swing.JMenuItem ; 34 import javax.swing.JPopupMenu ; 35 36 public class DefaultTextFieldHandler implements Constants, TextFieldHandler 37 { 38 protected final Editor editor; 39 protected final HistoryTextField textField; 40 41 protected List completions; 42 protected int index; 43 44 private Expansion expansion; 45 private String savedText; 46 private String 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 c = textField.getParent(); 67 while (true) { 68 if (c instanceof JDialog ) 69 return; 70 if (c == null) 71 break; 72 c = c.getParent(); 73 } 74 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 prefix = textField.getText(); 91 String 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 s = getPreviousCompletion(); 103 if (s != null) { 104 String 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 getCompletion(String 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 ) completions.get(index++); 129 } 130 131 private String getPreviousCompletion() 132 { 133 if (completions != null && completions.size() > 1) { 134 index -= 2; 135 if (index < 0) 136 index += completions.size(); 137 return (String ) completions.get(index++); 138 } 139 return null; 140 } 141 142 public List getCompletions(String 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 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 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 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 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 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 textField.setText(savedText); 215 resetExpansion(); 216 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 command = mapping.getCommand(); 272 if (command == "killLine") 273 killLine(); 274 else if (command == "expand") { 275 expand(); 276 return; } 278 } 279 resetExpansion(); 280 } 281 282 public void keyReleased(KeyEvent e) 283 { 284 TextListener textListener = textField.getTextListener(); 285 if (textListener != null) 286 textListener.textValueChanged(new TextEvent (this, TextEvent.TEXT_VALUE_CHANGED)); 287 } 288 289 public void keyTyped(KeyEvent 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 existing = textField.getText(); 299 JPopupMenu popup = null; 300 for (int i = history.size(); i-- > 0;) { 301 String s = history.get(i); 302 if (s.equals(existing)) 303 continue; 304 if (popup == null) 305 popup = new JPopupMenu (); 306 JMenuItem menuItem = new JMenuItem (); 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 popupActionListener = new ActionListener () { 317 public void actionPerformed(ActionEvent e) 318 { 319 textField.setText(e.getActionCommand()); 320 enter(); 321 } 322 }; 323 } 324 | Popular Tags |