1 21 22 package org.armedbear.j; 23 24 import gnu.regexp.RE; 25 import gnu.regexp.REMatch; 26 import gnu.regexp.UncheckedRE; 27 import java.awt.Component ; 28 import java.awt.event.InputEvent ; 29 import java.awt.event.KeyEvent ; 30 import java.awt.event.MouseEvent ; 31 import java.awt.event.MouseListener ; 32 import java.lang.reflect.Method ; 33 import java.util.ArrayList ; 34 import java.util.List ; 35 import javax.swing.JList ; 36 import javax.swing.JPopupMenu ; 37 import javax.swing.JScrollPane ; 38 import javax.swing.MenuElement ; 39 import javax.swing.MenuSelectionManager ; 40 import javax.swing.SwingUtilities ; 41 import org.armedbear.j.mail.MailCommands; 42 43 public final class OpenFileTextFieldHandler extends DefaultTextFieldHandler 44 implements Constants, MouseListener 45 { 46 private static final boolean filenamesIgnoreCase = 47 Platform.isPlatformWindows(); 48 49 private String title = "Open File"; 50 51 private boolean allowRemote = true; 53 private boolean fileMustExist = false; 54 private boolean checkBuffers = true; 55 private boolean checkSourcePath = true; 56 57 private Object returned; 58 private String encoding; 59 60 private JPopupMenu popup; 61 private JList listbox; 62 63 private String originalText; 64 private String originalPrefix; 65 66 public OpenFileTextFieldHandler(Editor editor, HistoryTextField textField) 67 { 68 super(editor, textField); 69 textField.addMouseListener(this); 70 } 71 72 public final void setTitle(String s) 73 { 74 title = s; 75 } 76 77 public final void setAllowRemote(boolean b) 78 { 79 allowRemote = b; 80 } 81 82 public final void setFileMustExist(boolean b) 83 { 84 fileMustExist = b; 85 } 86 87 public final void setCheckBuffers(boolean b) 88 { 89 checkBuffers = b; 90 } 91 92 public final void setCheckSourcePath(boolean b) 93 { 94 checkSourcePath = b; 95 } 96 97 public void enter() 98 { 99 final Buffer buffer = editor.getBuffer(); 100 String entry = textField.getText(); 101 if (!entry.equals(buffer.getFileNameForDisplay())) 102 saveHistory(); 103 entry = preprocess(entry); 104 if (encoding != null && !Utilities.isSupportedEncoding(encoding)) { 105 FastStringBuffer sb = 106 new FastStringBuffer("Unsupported encoding \""); 107 sb.append(encoding); 108 sb.append('"'); 109 error(sb.toString()); 110 return; 111 } 112 File currentDir = buffer.getCompletionDirectory(); 113 if (entry.length() == 0) { 114 returned = currentDir; 115 done(); 116 return; 117 } 118 String value = editor.getAlias(entry); 120 if (value != null) 121 entry = value; 122 if (entry.startsWith("pop://") || entry.startsWith("{") || 123 entry.startsWith("mailbox:")) { 124 MailCommands.openMailbox(editor, entry); 125 editor.ensureActive(); 126 editor.setFocusToDisplay(); 127 editor.updateLocation(); 128 editor.updateDisplay(); 129 return; 130 } 131 File candidate = null; 132 if (Utilities.isFilenameAbsolute(entry)) { 133 candidate = File.getInstance(currentDir, entry); 134 if (candidate == null) { 135 error("Invalid path"); 136 return; 137 } 138 } else if (entry.startsWith("./") || entry.startsWith(".\\")) { 139 candidate = File.getInstance(currentDir, entry); 141 if (candidate == null) { 142 error("Invalid path"); 143 return; 144 } 145 } 146 if (candidate != null) { 147 if (candidate.isRemote()) { 148 if (!allowRemote) { 149 error("File is remote"); 150 return; 151 } 152 } else { 153 if (!candidate.exists()) { 155 if (fileMustExist) { 156 error("File not found"); 157 return; 158 } 159 if (!checkParentDirectory(candidate, title)) { 160 editor.setFocusToDisplay(); 161 editor.updateLocation(); 162 return; 163 } 164 } 165 } 166 returned = candidate; 167 done(); 168 return; 169 } 170 candidate = File.getInstance(currentDir, entry); 172 if (candidate != null && candidate.exists()) { 173 returned = candidate; 174 done(); 175 return; 176 } 177 if (checkBuffers) { 180 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 181 Buffer buf = it.nextBuffer(); 182 if (buf.getFile() == null) 183 continue; 184 boolean found; 185 if (filenamesIgnoreCase) 186 found = buf.getFile().getName().equalsIgnoreCase(entry); 187 else 188 found = buf.getFile().getName().equals(entry); 189 if (found) { 190 returned = buf; 191 done(); 192 return; 193 } 194 } 195 } 196 if (checkSourcePath) { 199 candidate = Utilities.findFile(editor, entry); 200 if (candidate != null) { 201 returned = candidate; 202 done(); 203 return; 204 } 205 } 206 if (allowRemote) { 208 if (entry.startsWith("www.")) { 209 returned = File.getInstance("http://".concat(entry)); 210 done(); 211 return; 212 } 213 if (entry.startsWith("ftp.")) { 214 returned = File.getInstance("ftp://".concat(entry)); 215 done(); 216 return; 217 } 218 } 219 if (currentDir.isRemote()) 221 currentDir = Directories.getUserHomeDirectory(); 222 candidate = File.getInstance(currentDir, entry); 223 if (candidate == null) { 224 error("Invalid path"); 225 return; 226 } 227 if (fileMustExist && !candidate.exists()) { 228 error("File not found"); 229 return; 230 } 231 if (!checkParentDirectory(candidate, title)) { 232 editor.setFocusToDisplay(); 233 editor.updateLocation(); 234 return; 235 } 236 returned = candidate; 237 done(); 238 } 239 240 private String preprocess(String s) 241 { 242 encoding = null; 243 s = s.trim(); 244 if (s.startsWith("-e ")) { 245 s = s.substring(3).trim(); 246 int index = s.indexOf(' '); 247 encoding = s.substring(0, index); 248 return s.substring(index+1).trim(); 249 } 250 int index = s.indexOf(" -e "); 251 if (index < 0) 252 return s; encoding = s.substring(index+4).trim(); 254 return s.substring(0, index).trim(); 255 } 256 257 private boolean checkParentDirectory(File file, String context) 258 { 259 File parentDir = file.getParentFile(); 260 if (parentDir != null && parentDir.isDirectory()) 261 return true; 262 FastStringBuffer sb = new FastStringBuffer("Invalid path \""); 263 sb.append(file.canonicalPath()); 264 sb.append('"'); 265 MessageDialog.showMessageDialog(sb.toString(), context); 266 return false; 267 } 268 269 private void done() 270 { 271 Object owner = textField.getOwner(); 272 if (owner instanceof OpenFileDialog) { 273 OpenFileDialog dialog = (OpenFileDialog) owner; 274 dialog.setResult(returned); 275 dialog.ok(); 276 return; 277 } 278 Debug.assertTrue(editor != null); 279 Buffer buf = null; 280 if (returned instanceof Buffer) { 281 buf = (Buffer) returned; 282 } else if (returned instanceof File) { 283 File file = (File) returned; 284 file.setEncoding(encoding); 285 if (file instanceof HttpFile) { 286 if (Editor.getModeList().modeAccepts(IMAGE_MODE, file.getName())) { 287 buf = Editor.getBufferList().findBuffer(file); 288 if (buf == null) 289 buf = new RemoteBuffer(file); 290 } else if (Editor.preferences().getBooleanProperty(Property.ENABLE_WEB)) { 291 int modeId = 292 Editor.getModeList().getModeIdForFileName(file.getName()); 293 if (modeId < 0 || modeId == HTML_MODE) { 294 if (editor.getMode() instanceof WebMode) { 295 buf = editor.getBuffer(); 297 Debug.assertTrue(buf instanceof WebBuffer); 298 ((WebBuffer)buf).saveHistory(buf.getFile(), 299 buf.getAbsoluteOffset(editor.getDot()), 300 ((WebBuffer)buf).getContentType()); 301 buf.setCache(null); 304 ((WebBuffer)buf).go(file, 0, null); 305 } else { 306 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 308 Buffer b = it.nextBuffer(); 309 if (b instanceof WebBuffer && b.getFile().equals(file)) { 310 buf = b; 311 break; 312 } 313 } 314 if (buf == null) { 315 buf = WebBuffer.createWebBuffer(file, null, null); 317 } 318 } 319 } 320 } 321 } 322 if (buf == null) 323 buf = editor.openFile(file); 324 } 325 Editor.setCurrentEditor(editor); 326 if (buf != null && buf != editor.getBuffer()) { 327 editor.makeNext(buf); 328 editor.switchToBuffer(buf); 329 } 330 if (Editor.getEditorList().contains(editor)) { 331 editor.ensureActive(); 332 editor.setFocusToDisplay(); 333 editor.updateLocation(); 334 editor.updateDisplay(); 335 } 336 } 337 338 private void saveHistory() 339 { 340 final History history = textField.getHistory(); 341 if (history != null) { 342 String entry = textField.getText().trim(); 343 if (entry.length() > 0) { 344 history.append(entry); 345 history.save(); 346 } 347 } 348 } 349 350 public void escape() 351 { 352 if (popup != null) { 353 Debug.bug(); 354 popup.setVisible(false); 355 popup = null; 356 } 357 Object owner = textField.getOwner(); 358 if (owner instanceof OpenFileDialog) { 359 OpenFileDialog dialog = (OpenFileDialog) owner; 360 dialog.cancel(); 361 } else { 362 editor.setFocusToDisplay(); 364 editor.updateLocation(); 365 editor.ensureActive(); 366 } 367 } 368 369 public boolean wantTab() 370 { 371 return true; 372 } 373 374 public void tab() 375 { 376 final String entry = textField.getText(); 377 if (entry.startsWith("http:") || entry.startsWith("https:") || 378 entry.startsWith("ftp:")) 379 return; 380 final File dir = editor.getCompletionDirectory(); 381 if (dir == null) 382 return; 383 String prefix = null; 384 if (Utilities.isFilenameAbsolute(entry) || entry.startsWith("..")) { 385 File file = File.getInstance(dir, entry); 386 if (file != null) { 387 if (file.isRemote()) 388 prefix = file.netPath(); 389 else if (dir.isRemote()) 390 prefix = file.netPath(); 391 else 392 prefix = file.canonicalPath(); 393 if (entry.endsWith(LocalFile.getSeparator())) 394 prefix = prefix.concat(LocalFile.getSeparator()); 395 } 396 } else 397 prefix = entry; 398 if (prefix == null) 399 return; 400 editor.setWaitCursor(); 401 final boolean showCompletionList; 402 if (textField.getOwner() instanceof OpenFileDialog) { 403 showCompletionList = false; 404 } else { 405 showCompletionList = Editor.preferences().getBooleanProperty( 406 Property.SHOW_COMPLETION_LIST); 407 } 408 if (showCompletionList) { 409 if (popup == null) { 410 long start = System.currentTimeMillis(); 411 completions = getCompletions(prefix); 412 long elapsed = System.currentTimeMillis() - start; 413 Log.debug("getCompletions " + elapsed + " ms " + 414 completions.size() + " completions"); 415 index = 0; 416 originalText = textField.getText(); 417 originalPrefix = prefix; 418 if (completions.size() == 1) { 419 String s = (String ) completions.get(0); 420 textField.setText(s); 421 Runnable r = new Runnable () { 422 public void run() 423 { 424 textField.setCaretPosition(textField.getText().length()); 425 } 426 }; 427 SwingUtilities.invokeLater(r); 428 } else if (completions.size() > 1) 429 showCompletionsPopup(); 430 } else 431 tabPopup(+1, true); 432 } else { 433 while (true) { 435 String s = getCompletion(prefix); 436 if (s == null) 437 break; 438 if (s.equals(entry)) { 439 prefix = entry; 441 reset(); 442 File file = File.getInstance(dir, entry); 443 if (file != null && file.isDirectory()) 444 continue; 445 else 446 break; 447 } 448 textField.setText(s); 451 textField.setCaretPosition(s.length()); 452 break; 453 } 454 } 455 editor.setDefaultCursor(); 456 } 457 458 public List getCompletions(String prefix) 459 { 460 final File dir = editor.getCompletionDirectory(); 461 ArrayList completions = new ArrayList (); 462 final String sourcePath = checkSourcePath ? getSourcePath() : null; 463 prefix = File.normalize(prefix); 464 boolean ignoreCase = Platform.isPlatformWindows() || 465 Editor.preferences().getBooleanProperty( 466 Property.FILENAME_COMPLETIONS_IGNORE_CASE); 467 FilenameCompletion completion = 468 new FilenameCompletion(dir, prefix, sourcePath, ignoreCase); 469 final File currentDirectory = getCurrentDirectory(); 470 List files = completion.listFiles(); 471 if (files != null) { 472 for (int i = 0, limit = files.size(); i < limit; i++) { 473 final File file = (File) files.get(i); 474 final String name = getNameForFile(file, currentDirectory); 475 if (file.isDirectory()) { 476 addCompletion(completions, name.concat(file.getSeparator()), 477 ignoreCase); 478 continue; 479 } 480 if (isExcluded(name)) 481 continue; 482 addCompletion(completions, name, ignoreCase); 483 } 484 } 485 if (checkBuffers && !Utilities.isFilenameAbsolute(prefix) && 486 prefix.indexOf(LocalFile.getSeparatorChar()) < 0) { 487 addCompletionsFromBufferList(completions, prefix, currentDirectory, 489 ignoreCase); 490 } 491 return completions; 492 } 493 494 private void addCompletionsFromBufferList(List list, String prefix, 495 File currentDirectory, boolean ignoreCase) 496 { 497 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 498 Buffer buf = it.nextBuffer(); 499 if (buf.getType() != Buffer.TYPE_NORMAL) 500 continue; 501 if (buf == editor.getBuffer()) 502 continue; 503 File file = buf.getFile(); 504 if (file != null) { 505 boolean isMatch = false; 506 if (ignoreCase) 507 isMatch = file.getName().regionMatches(true, 0, prefix, 0, 508 prefix.length()); 509 else 510 isMatch = file.getName().startsWith(prefix); 511 if (isMatch) 512 addCompletion(list, getNameForFile(file, currentDirectory), 513 ignoreCase); 514 } 515 } 516 } 517 518 private String getNameForFile(File file, File currentDirectory) 521 { 522 String name; 523 if (currentDirectory != null) { 524 if (currentDirectory.isLocal()) { 525 if (file.isRemote()) 526 name = file.netPath(); 527 else if (currentDirectory.equals(file.getParentFile())) 528 name = file.getName(); 529 else 530 name = file.canonicalPath(); 531 } else { 532 name = file.netPath(); 535 } 536 } else { 537 if (file.isRemote()) 538 name = file.netPath(); 539 else 540 name = file.canonicalPath(); 541 } 542 return name; 543 } 544 545 private void addCompletion(List list, String s, boolean ignoreCase) 547 { 548 if (s != null) { 549 for (int i = list.size(); i-- > 0;) { 550 if (ignoreCase) { 551 if (s.equalsIgnoreCase((String )list.get(i))) 552 return; 553 } else if (s.equals((String )list.get(i))) 554 return; 555 } 556 list.add(s); 558 } 559 } 560 561 private boolean isExcluded(String pathname) 562 { 563 final int length = pathname.length(); 564 if (length > 0) { 565 if (pathname.charAt(length - 1) == '~') 566 return true; 567 } 568 String extension = Utilities.getExtension(pathname); 569 if (Platform.isPlatformWindows()) 570 extension = extension.toLowerCase(); 571 if (extension.equals(".class") || 572 extension.equals(".cls") || 573 extension.equals(".abcl")) 574 { 575 return true; 576 } 577 if (Platform.isPlatformWindows()) { 578 if (extension.equals(".obj") || 579 extension.equals(".exe")) 580 { 581 return true; 582 } 583 } 584 return false; 585 } 586 587 private File getCurrentDirectory() 589 { 590 File file = editor.getBuffer().getFile(); 591 if (file == null) 592 return null; 593 if (file.isDirectory()) 594 return file; 595 return file.getParentFile(); 596 } 597 598 private String getSourcePath() 599 { 600 ArrayList dirs = new ArrayList (); 601 String sourcePathForMode = 603 editor.getBuffer().getStringProperty(Property.SOURCE_PATH); 604 if (sourcePathForMode != null) 605 dirs.addAll(Utilities.getDirectoriesInPath(sourcePathForMode)); 606 String globalSourcePath = 608 Editor.preferences().getStringProperty(Property.SOURCE_PATH); 609 if (globalSourcePath != null) { 610 List list = Utilities.getDirectoriesInPath(globalSourcePath); 611 for (int i = 0; i < list.size(); i++) { 612 String s = (String ) list.get(i); 613 if (!dirs.contains(s)) 614 dirs.add(s); 615 } 616 } 617 FastStringBuffer sb = new FastStringBuffer(); 619 for (int i = 0; i < dirs.size(); i++) { 620 sb.append((String )dirs.get(i)); 621 sb.append(LocalFile.getPathSeparatorChar()); 622 } 623 if (sb.length() > 0) 625 sb.setLength(sb.length() - 1); 626 return sb.toString(); 627 } 628 629 private final void error(String message) 630 { 631 MessageDialog.showMessageDialog(editor, message, title); 632 editor.setFocusToDisplay(); 633 editor.updateLocation(); 634 } 635 636 private void showCompletionsPopup() 637 { 638 String [] array = new String [completions.size()]; 639 completions.toArray(array); 640 popup = new JPopupMenu (); 641 popup.add(new CompletionsList(array)); 642 popup.show(textField, 0, textField.getHeight()); 643 final String completion = (String ) completions.get(0); 644 Runnable r = new Runnable () { 645 public void run() 646 { 647 updateTextField(completion); 648 } 649 }; 650 SwingUtilities.invokeLater(r); 651 } 652 653 private void tabPopup(int n, boolean wrap) 654 { 655 int count = listbox.getModel().getSize(); 656 if (count == 0) { 657 Debug.bug(); 658 return; 659 } 660 int index = listbox.getSelectedIndex(); 661 int i = index + n; 662 if (wrap) { 663 if (i >= count) 664 i = 0; 665 else if (i < 0) 666 i = count - 1; 667 } else { 668 if (i >= count || i < 0) 669 i = index; 670 } 671 if (i != index) { 672 listbox.setSelectedIndex(i); 673 listbox.ensureIndexIsVisible(i); 674 String completion = (String ) listbox.getSelectedValue(); 675 updateTextField(completion); 676 } 677 } 678 679 private void updateTextField(String completion) 680 { 681 if (completion == null) 682 return; 683 textField.setText(completion); 684 if (Editor.preferences().getBooleanProperty(Property.SELECT_COMPLETION)) { 685 if (originalText != null && originalText.length() > 0) { 686 boolean ignoreCase = 687 Editor.preferences().getBooleanProperty( 688 Property.FILENAME_COMPLETIONS_IGNORE_CASE); 689 boolean select = 690 completion.regionMatches(ignoreCase, 0, originalPrefix, 0, 691 originalPrefix.length()); 692 if (select) { 693 textField.setCaretPosition(originalPrefix.length()); 694 textField.moveCaretPosition(completion.length()); 695 textField.getCaret().setVisible(false); 696 } else { 697 char c = originalText.charAt(0); 698 if (c == '/' || c == '\\') { 699 int index; 700 if (ignoreCase) { 701 index = completion.toLowerCase().lastIndexOf( 702 originalText.toLowerCase()); 703 } else { 704 index = completion.lastIndexOf(originalText); 705 } 706 if (index >= 0) { 707 textField.setCaretPosition(index + originalText.length()); 708 textField.moveCaretPosition(completion.length()); 709 textField.getCaret().setVisible(false); 710 } 711 } else { 712 RE re = new UncheckedRE("[\\/]".concat(originalText), 713 ignoreCase ? RE.REG_ICASE : 0); 714 REMatch lastMatch = null; 715 int index = 0; 716 while (true) { 717 REMatch match = re.getMatch(completion, index); 718 if (match != null) { 719 lastMatch = match; 720 index = match.getEndIndex(); 721 } else 722 break; 723 } 724 if (lastMatch != null) { 725 textField.setCaretPosition(index); 726 textField.moveCaretPosition(completion.length()); 727 textField.getCaret().setVisible(false); 728 } 729 } 730 } 731 } 732 } 733 } 734 735 private void enterPopup() 736 { 737 popup.setVisible(false); 738 popup = null; 739 File file = File.getInstance(editor.getCompletionDirectory(), 740 textField.getText()); 741 if (file == null || file.isDirectory()) { 742 textField.requestFocus(); 743 end(); 744 } else { 745 editor.repaintNow(); 746 enter(); 747 } 748 } 749 750 private void end() 751 { 752 Runnable r = new Runnable () { 753 public void run() 754 { 755 textField.setCaretPosition(textField.getText().length()); 756 textField.getCaret().setVisible(true); 757 } 758 }; 759 SwingUtilities.invokeLater(r); 760 } 761 762 private void left() 763 { 764 reset(); 765 final int pos; 766 final int start = textField.getSelectionStart(); 767 if (start != textField.getSelectionEnd()) 768 pos = start; 769 else 770 pos = Math.max(0, textField.getCaretPosition() - 1); 771 textField.requestFocus(); 772 Runnable r = new Runnable () { 773 public void run() 774 { 775 textField.setCaretPosition(pos); 776 textField.getCaret().setVisible(true); 777 } 778 }; 779 SwingUtilities.invokeLater(r); 780 } 781 782 protected void reset() 783 { 784 if (popup != null) { 785 popup.setVisible(false); 786 popup = null; 787 } 788 super.reset(); 789 } 790 791 private class CompletionsList extends JScrollPane implements MenuElement , 792 MouseListener 793 { 794 public CompletionsList(String [] completions) 795 { 796 super(listbox = new JList (completions)); 797 listbox.setFont(textField.getFont()); 798 if (completions.length < 8) 799 listbox.setVisibleRowCount(completions.length); 800 listbox.setFocusTraversalKeysEnabled(false); 801 listbox.setSelectedIndex(0); 802 listbox.addMouseListener(this); 803 } 804 805 public void processMouseEvent(MouseEvent e, MenuElement [] path, 806 MenuSelectionManager manager) {} 807 808 public void processKeyEvent(KeyEvent e, MenuElement [] path, 809 MenuSelectionManager manager) 810 { 811 final int keyCode = e.getKeyCode(); 812 final int modifiers = e.getModifiers(); 813 final int id = e.getID(); 814 if (id == KeyEvent.KEY_PRESSED) { 815 switch (keyCode) { 816 case KeyEvent.VK_TAB: 817 if (modifiers == 0) 818 tabPopup(+1, true); 819 else if (modifiers == SHIFT_MASK) 820 tabPopup(-1, true); 821 e.consume(); 822 return; 823 case KeyEvent.VK_ENTER: { 824 enterPopup(); 825 e.consume(); 826 return; 827 } 828 case KeyEvent.VK_DELETE: 829 case KeyEvent.VK_ESCAPE: { 830 popup.setVisible(false); 831 popup = null; 832 textField.setText(originalText); 833 originalText = null; 834 originalPrefix = null; 835 textField.requestFocus(); 836 end(); 837 e.consume(); 838 return; 839 } 840 case KeyEvent.VK_UP: 841 case KeyEvent.VK_KP_UP: 842 tabPopup(-1, false); 843 e.consume(); 844 break; 845 case KeyEvent.VK_DOWN: 846 case KeyEvent.VK_KP_DOWN: 847 tabPopup(+1, false); 848 e.consume(); 849 break; 850 case KeyEvent.VK_LEFT: 851 case KeyEvent.VK_KP_LEFT: 852 left(); 853 e.consume(); 854 return; 855 case KeyEvent.VK_END: 856 case KeyEvent.VK_RIGHT: 857 case KeyEvent.VK_KP_RIGHT: 858 reset(); 859 originalText = null; 860 originalPrefix = null; 861 textField.requestFocus(); 862 end(); 863 e.consume(); 864 return; 865 case KeyEvent.VK_SHIFT: 866 break; 867 default: 868 break; 869 } 870 } else if (id == KeyEvent.KEY_TYPED) { 871 keyTyped(e); 873 } 874 super.processKeyEvent(e); 875 } 876 877 public void menuSelectionChanged(boolean isIncluded) {} 878 879 public MenuElement [] getSubElements() 880 { 881 return new MenuElement [0]; 882 } 883 884 public Component getComponent() 885 { 886 return this; 887 } 888 889 public void mouseClicked(MouseEvent e) 890 { 891 enterPopup(); 892 } 893 894 public void mousePressed(MouseEvent e) 895 { 896 int modifiers = e.getModifiers() & 0x1f; 898 if (modifiers == InputEvent.BUTTON1_MASK || modifiers == InputEvent.BUTTON2_MASK) { 899 listbox.setSelectedIndex(listbox.locationToIndex(e.getPoint())); 900 String s = (String ) listbox.getSelectedValue(); 901 textField.setText(s); 902 } 903 } 904 905 public void mouseReleased(MouseEvent e) {} 906 907 public void mouseEntered(MouseEvent e) {} 908 909 public void mouseExited(MouseEvent e) {} 910 } 911 912 public void keyPressed(KeyEvent e) 913 { 914 if (popup != null) { 915 int modifiers = e.getModifiers(); 916 switch (e.getKeyCode()) { 917 case KeyEvent.VK_ENTER: 918 enterPopup(); 919 e.consume(); 920 return; 921 case KeyEvent.VK_ESCAPE: 922 popup.setVisible(false); 923 popup = null; 924 textField.setText(originalText); 925 originalText = null; 926 originalPrefix = null; 927 textField.requestFocus(); 928 e.consume(); 929 return; 930 case KeyEvent.VK_TAB: 931 if (modifiers == 0) 932 tabPopup(+1, true); 933 else if (modifiers == SHIFT_MASK) 934 tabPopup(-1, true); 935 e.consume(); 936 return; 937 case KeyEvent.VK_UP: 938 case KeyEvent.VK_KP_UP: 939 if (modifiers == 0) { 940 tabPopup(-1, false); 941 e.consume(); 942 return; 943 } 944 break; 945 case KeyEvent.VK_DOWN: 946 case KeyEvent.VK_KP_DOWN: 947 if (modifiers == 0) { 948 tabPopup(+1, false); 949 e.consume(); 950 return; 951 } 952 break; 953 case KeyEvent.VK_RIGHT: 954 case KeyEvent.VK_KP_RIGHT: 955 case KeyEvent.VK_END: 956 textField.getCaret().setVisible(true); 957 break; 958 default: 959 break; 960 } 961 } else { 962 switch (e.getKeyCode()) { 963 case KeyEvent.VK_LEFT: 964 case KeyEvent.VK_KP_LEFT: 965 case KeyEvent.VK_RIGHT: 966 case KeyEvent.VK_KP_RIGHT: 967 textField.getCaret().setVisible(true); 968 originalText = null; 969 originalPrefix = null; 970 break; 971 } 972 } 973 super.keyPressed(e); 974 } 975 976 public void keyTyped(KeyEvent e) 977 { 978 char c = e.getKeyChar(); 979 if (c == 8) { 980 textField.getCaret().setVisible(true); 982 return; 983 } 984 if ((e.getModifiers() & (ALT_MASK | CTRL_MASK | META_MASK)) != 0) { 985 e.consume(); 986 return; 987 } 988 if (c >= ' ' && c != 127) { 989 if (popup != null) { 990 popup.setVisible(false); 991 popup = null; 992 } 993 String text = textField.getText(); 994 if (textField.getSelectionStart() != textField.getSelectionEnd()) { 995 if (originalText != null) { 996 text = originalText; 997 originalText = null; 998 originalPrefix = null; 999 } else { 1000 FastStringBuffer sb = 1001 new FastStringBuffer(text.substring(0, 1002 textField.getSelectionStart())); 1003 sb.append(text.substring(textField.getSelectionEnd())); 1004 text = sb.toString(); 1005 textField.setCaretPosition(textField.getSelectionStart()); 1006 } 1007 } 1008 final int pos = Math.min(textField.getCaretPosition(), text.length()); 1010 FastStringBuffer sb = new FastStringBuffer(text.substring(0, pos)); 1011 sb.append(c); 1012 if (pos < text.length()) 1013 sb.append(text.substring(pos)); 1014 textField.setText(sb.toString()); 1015 textField.requestFocus(); 1016 Runnable r = new Runnable () { 1017 public void run() 1018 { 1019 int caretPos; 1020 final String s = textField.getText(); 1021 if (s != null) 1022 caretPos = Math.min(pos + 1, s.length()); 1023 else 1024 caretPos = 0; 1025 textField.setCaretPosition(caretPos); 1026 textField.getCaret().setVisible(true); 1027 } 1028 }; 1029 SwingUtilities.invokeLater(r); 1030 } 1031 e.consume(); 1032 } 1033 1034 public void mousePressed(MouseEvent e) 1035 { 1036 Editor.setCurrentEditor(editor); 1037 originalText = null; 1038 originalPrefix = null; 1039 } 1040 1041 public void mouseReleased(MouseEvent e) {} 1042 1043 public void mouseClicked(MouseEvent e) {} 1044 1045 public void mouseEntered(MouseEvent e) {} 1046 1047 public void mouseExited(MouseEvent e) {} 1048} 1049 | Popular Tags |