1 19 20 package org.netbeans.editor; 21 22 import java.awt.Rectangle ; 23 import java.awt.Frame ; 24 import java.awt.event.ActionEvent ; 25 import java.awt.event.KeyEvent ; 26 import java.util.logging.Level ; 27 import java.util.logging.Logger ; 28 import javax.swing.SwingUtilities ; 29 import javax.swing.Action ; 30 import javax.swing.KeyStroke ; 31 import javax.swing.text.JTextComponent ; 32 import javax.swing.text.BadLocationException ; 33 import javax.swing.text.EditorKit ; 34 import javax.swing.text.Document ; 35 import javax.swing.text.TextAction ; 36 import javax.swing.text.Caret ; 37 import javax.swing.plaf.TextUI ; 38 import javax.swing.text.Element ; 39 import javax.swing.text.View ; 40 import org.netbeans.lib.editor.util.CharSequenceUtilities; 41 import org.netbeans.lib.editor.util.swing.DocumentUtilities; 42 import org.openide.util.NbBundle; 43 44 68 69 public class Utilities { 70 71 private static final String WRONG_POSITION_LOCALE = "wrong_position"; 73 74 public static final int CASE_UPPER = 0; 75 76 77 public static final int CASE_LOWER = 1; 78 79 80 public static final int CASE_SWITCH = 2; 81 82 83 private static TextAction focusedComponentAction; 84 85 private Utilities() { 86 } 88 89 94 public static int getRowStart(JTextComponent c, int offset) 95 throws BadLocationException { 96 Rectangle r = c.modelToView(offset); 97 if (r == null){ 98 return -1; 99 } 100 EditorUI eui = getEditorUI(c); 101 if (eui != null){ 102 return c.viewToModel(new java.awt.Point (eui.textLeftMarginWidth, r.y)); 103 } 104 return -1; 105 } 106 107 112 public static int getRowStart(BaseDocument doc, int offset) 113 throws BadLocationException { 114 return getRowStart(doc, offset, 0); 115 } 116 117 128 public static int getRowStart(BaseDocument doc, int offset, int lineShift) 129 throws BadLocationException { 130 131 checkOffsetValid(doc, offset); 132 133 if (lineShift != 0) { 134 Element lineRoot = doc.getParagraphElement(0).getParentElement(); 135 int line = lineRoot.getElementIndex(offset); 136 line += lineShift; 137 if (line < 0 || line >= lineRoot.getElementCount()) { 138 return -1; } 140 return lineRoot.getElement(line).getStartOffset(); 141 142 } else { return doc.getParagraphElement(offset).getStartOffset(); 144 } 145 } 146 147 155 public static int getRowFirstNonWhite(BaseDocument doc, int offset) 156 throws BadLocationException { 157 158 checkOffsetValid(doc, offset); 159 160 Element lineElement = doc.getParagraphElement(offset); 161 return getFirstNonWhiteFwd(doc, 162 lineElement.getStartOffset(), 163 lineElement.getEndOffset() - 1 164 ); 165 } 166 167 175 public static int getRowLastNonWhite(BaseDocument doc, int offset) 176 throws BadLocationException { 177 178 checkOffsetValid(doc, offset); 179 180 Element lineElement = doc.getParagraphElement(offset); 181 return getFirstNonWhiteBwd(doc, 182 lineElement.getEndOffset() - 1, 183 lineElement.getStartOffset() 184 ); 185 } 186 187 193 public static int getRowIndent(BaseDocument doc, int offset) 194 throws BadLocationException { 195 offset = getRowFirstNonWhite(doc, offset); 196 if (offset == -1) { 197 return -1; 198 } 199 return doc.getVisColFromPos(offset); 200 } 201 202 213 public static int getRowIndent(BaseDocument doc, int offset, boolean downDir) 214 throws BadLocationException { 215 int p = getRowFirstNonWhite(doc, offset); 216 if (p == -1) { 217 p = getFirstNonWhiteRow(doc, offset, downDir); 218 if (p == -1) { 219 return -1; } 221 p = getRowFirstNonWhite(doc, p); 222 if (p == -1) { 223 return -1; } 225 } 226 return doc.getVisColFromPos(p); 227 } 228 229 235 public static int getRowEnd(JTextComponent c, int offset) 236 throws BadLocationException { 237 Rectangle r = c.modelToView(offset); 238 if (r == null){ 239 return -1; 240 } 241 return c.viewToModel(new java.awt.Point (Integer.MAX_VALUE, r.y)); 242 } 243 244 public static int getRowEnd(BaseDocument doc, int offset) 245 throws BadLocationException { 246 checkOffsetValid(doc, offset); 247 248 return doc.getParagraphElement(offset).getEndOffset() - 1; 249 } 250 251 private static int findBestSpan(JTextComponent c, int lineBegin, int lineEnd, int x) 252 throws BadLocationException { 253 if (lineBegin == lineEnd){ 254 return lineEnd; 255 } 256 int low = lineBegin; 257 int high = lineEnd; 258 while (low <= high) { 259 260 if (high - low < 3){ 261 int bestSpan = Integer.MAX_VALUE; 262 int bestPos = -1; 263 for (int i = low; i<=high; i++){ 264 Rectangle tempRect = c.modelToView(i); 265 if (Math.abs(x-tempRect.x) < bestSpan){ 266 bestSpan = Math.abs(x-tempRect.x); 267 bestPos = i; 268 } 269 } 270 return bestPos; 271 } 272 273 int mid = (low + high) / 2; 274 275 Rectangle tempRect = c.modelToView(mid); 276 if (tempRect.x > x){ 277 high = mid; 278 } else if (tempRect.x < x) { 279 low = mid; 280 } else { 281 return mid; 282 } 283 } 284 return lineBegin; 285 } 286 287 295 public static int getPositionAbove(JTextComponent c, int offset, int x) 296 throws BadLocationException { 297 int rowStart = getRowStart(c, offset); 298 int endInit = c.getUI().getNextVisualPositionFrom(c, 299 rowStart, null, javax.swing.SwingConstants.WEST, null); 300 301 if (x == BaseKit.MAGIC_POSITION_MAX){ 302 return endInit; 303 } 304 305 EditorUI eui = getEditorUI(c); 306 if (eui == null){ 307 return offset; } 309 310 Rectangle r = c.modelToView(endInit); 311 if (r == null){ 312 return offset; } 314 315 if (x == eui.textLeftMarginWidth){ 316 return getRowStart(c, endInit); 317 } 318 319 int end = c.viewToModel(new java.awt.Point (Math.max(eui.textLeftMarginWidth, x + 2*r.width ),r.y)); 320 Rectangle tempRect = c.modelToView(end); 321 if (tempRect == null || tempRect.x < x){ 322 end = endInit; 323 } 324 325 int start = c.viewToModel(new java.awt.Point (Math.max(eui.textLeftMarginWidth, x - 2*r.width ),r.y)); 326 tempRect = c.modelToView(start); 327 if (tempRect == null && tempRect.x > x){ 328 start = getRowStart(c, end); 329 } 330 331 int best = findBestSpan(c, start, end, x); 332 333 if (best<c.getDocument().getLength()){ 334 int tmp = best + 1; 336 int nextVisualPosition = c.getUI().getNextVisualPositionFrom(c, 337 tmp, javax.swing.text.Position.Bias.Backward, javax.swing.SwingConstants.WEST, null); 338 if (nextVisualPosition<best && nextVisualPosition >= 0){ 339 return nextVisualPosition; 340 } 341 } 342 343 return best; 344 } 345 346 354 public static int getPositionBelow(JTextComponent c, int offset, int x) 355 throws BadLocationException { 356 int startInit = getRowEnd(c, offset) + 1; 357 358 Rectangle r = c.modelToView(startInit); 359 if (r == null){ 360 return offset; } 362 363 EditorUI eui = getEditorUI(c); 364 if (eui != null && x ==eui.textLeftMarginWidth){ 365 return startInit; 366 } 367 368 int start = c.viewToModel(new java.awt.Point (Math.min(Integer.MAX_VALUE, r.x + x - 2*r.width ),r.y)); 369 Rectangle tempRect = c.modelToView(start); 370 if (tempRect!=null && tempRect.x > x){ 371 start = startInit; 372 } 373 374 int end = c.viewToModel(new java.awt.Point (Math.min(Integer.MAX_VALUE, r.x + x + 2*r.width ),r.y)); 375 tempRect = c.modelToView(end); 376 if (tempRect!=null && tempRect.x < x){ 377 end = getRowEnd(c, start); 378 } 379 380 int best = findBestSpan(c, start, end, x); 381 382 if (best>0){ 383 int tmp = best - 1; 389 int nextVisualPosition = c.getUI().getNextVisualPositionFrom(c, 390 tmp, javax.swing.text.Position.Bias.Forward, javax.swing.SwingConstants.EAST, null); 391 if (nextVisualPosition>best && nextVisualPosition <= c.getDocument().getLength()){ 392 tempRect = c.modelToView(nextVisualPosition); 395 if (tempRect == null){ 396 return nextVisualPosition; 397 } 398 int rightX = tempRect.x; 399 int nextVisualPositionLeft = c.getUI().getNextVisualPositionFrom(c, 400 nextVisualPosition, javax.swing.text.Position.Bias.Backward, javax.swing.SwingConstants.WEST, null); 401 tempRect = c.modelToView(nextVisualPositionLeft); 402 if (tempRect == null){ 403 return nextVisualPosition; 404 } 405 int leftX = tempRect.x; 406 407 if (Math.abs(leftX - x) > Math.abs(rightX - x)){ 408 return nextVisualPosition; 409 } else { 410 return nextVisualPositionLeft; 411 } 412 } 413 } 414 415 return best; 416 } 417 418 423 public static int getWordStart(JTextComponent c, int offset) 424 throws BadLocationException { 425 return getWordStart((BaseDocument)c.getDocument(), offset); 426 } 427 428 public static int getWordStart(BaseDocument doc, int offset) 429 throws BadLocationException { 430 return doc.find(new FinderFactory.PreviousWordBwdFinder(doc, false, true), 431 offset, 0); 432 } 433 434 public static int getWordEnd(JTextComponent c, int offset) 435 throws BadLocationException { 436 return getWordEnd((BaseDocument)c.getDocument(), offset); 437 } 438 439 public static int getWordEnd(BaseDocument doc, int offset) 440 throws BadLocationException { 441 int ret = doc.find(new FinderFactory.NextWordFwdFinder(doc, false, true), 442 offset, -1); 443 return (ret > 0) ? ret : doc.getLength(); 444 } 445 446 public static int getNextWord(JTextComponent c, int offset) 447 throws BadLocationException { 448 int nextWordOffset = getNextWord((BaseDocument)c.getDocument(), offset); 449 int nextVisualPosition = -1; 450 if (nextWordOffset > 0){ 451 nextVisualPosition = c.getUI().getNextVisualPositionFrom(c, 452 nextWordOffset - 1, null, javax.swing.SwingConstants.EAST, null); 453 } 454 return (nextVisualPosition == -1) ? nextWordOffset : nextVisualPosition; 455 } 456 457 public static int getNextWord(BaseDocument doc, int offset) 458 throws BadLocationException { 459 Finder nextWordFinder = (Finder)doc.getProperty(SettingsNames.NEXT_WORD_FINDER); 460 offset = doc.find(nextWordFinder, offset, -1); 461 if (offset < 0) { 462 offset = doc.getLength(); 463 } 464 return offset; 465 } 466 467 public static int getPreviousWord(JTextComponent c, int offset) 468 throws BadLocationException { 469 int prevWordOffset = getPreviousWord((BaseDocument)c.getDocument(), offset); 470 int nextVisualPosition = c.getUI().getNextVisualPositionFrom(c, 471 prevWordOffset, null, javax.swing.SwingConstants.WEST, null); 472 if (nextVisualPosition == 0 && prevWordOffset == 0){ 473 return 0; 474 } 475 return (nextVisualPosition + 1 == prevWordOffset) ? prevWordOffset : nextVisualPosition + 1; 476 } 477 478 public static int getPreviousWord(BaseDocument doc, int offset) 479 throws BadLocationException { 480 Finder prevWordFinder = (Finder)doc.getProperty(SettingsNames.PREVIOUS_WORD_FINDER); 481 offset = doc.find(prevWordFinder, offset, 0); 482 if (offset < 0) { 483 offset = 0; 484 } 485 return offset; 486 } 487 488 493 public static int getFirstWhiteFwd(BaseDocument doc, int offset) 494 throws BadLocationException { 495 return getFirstWhiteFwd(doc, offset, -1); 496 } 497 498 505 public static int getFirstWhiteFwd(BaseDocument doc, int offset, int limitPos) 506 throws BadLocationException { 507 return doc.find(new FinderFactory.WhiteFwdFinder(doc), offset, limitPos); 508 } 509 510 515 public static int getFirstNonWhiteFwd(BaseDocument doc, int offset) 516 throws BadLocationException { 517 return getFirstNonWhiteFwd(doc, offset, -1); 518 } 519 520 527 public static int getFirstNonWhiteFwd(BaseDocument doc, int offset, int limitPos) 528 throws BadLocationException { 529 return doc.find(new FinderFactory.NonWhiteFwdFinder(doc), offset, limitPos); 530 } 531 532 539 public static int getFirstWhiteBwd(BaseDocument doc, int offset) 540 throws BadLocationException { 541 return getFirstWhiteBwd(doc, offset, 0); 542 } 543 544 553 public static int getFirstWhiteBwd(BaseDocument doc, int offset, int limitPos) 554 throws BadLocationException { 555 return doc.find(new FinderFactory.WhiteBwdFinder(doc), offset, limitPos); 556 } 557 558 565 public static int getFirstNonWhiteBwd(BaseDocument doc, int offset) 566 throws BadLocationException { 567 return getFirstNonWhiteBwd(doc, offset, 0); 568 } 569 570 579 public static int getFirstNonWhiteBwd(BaseDocument doc, int offset, int limitPos) 580 throws BadLocationException { 581 return doc.find(new FinderFactory.NonWhiteBwdFinder(doc), offset, limitPos); 582 } 583 584 588 public static int getLineOffset(BaseDocument doc, int offset) 589 throws BadLocationException { 590 591 checkOffsetValid(offset, doc.getLength() + 1); 592 593 Element lineRoot = doc.getParagraphElement(0).getParentElement(); 594 return lineRoot.getElementIndex(offset); 595 } 596 597 601 public static int getRowStartFromLineOffset(BaseDocument doc, int lineIndex) { 602 Element lineRoot = doc.getParagraphElement(0).getParentElement(); 603 if (lineIndex < 0 || lineIndex >= lineRoot.getElementCount()) { 604 return -1; 606 } else { 607 return lineRoot.getElement(lineIndex).getStartOffset(); 608 } 609 } 610 611 616 public static int getVisualColumn(BaseDocument doc, int offset) 617 throws BadLocationException { 618 619 int docLen = doc.getLength(); 620 if (offset == docLen + 1) { offset = docLen; 622 } 623 624 return doc.getVisColFromPos(offset); 625 } 626 627 630 public static String getIdentifier(BaseDocument doc, int offset) 631 throws BadLocationException { 632 int[] blk = getIdentifierBlock(doc, offset); 633 return (blk != null) ? doc.getText(blk[0], blk[1] - blk[0]) : null; 634 } 635 636 637 644 public static int[] getIdentifierBlock(JTextComponent c, int offset) 645 throws BadLocationException { 646 CharSequence id = null; 647 int[] ret = null; 648 Document doc = c.getDocument(); 649 int idStart = javax.swing.text.Utilities.getWordStart(c, offset); 650 if (idStart >= 0) { 651 int idEnd = javax.swing.text.Utilities.getWordEnd(c, idStart); 652 if (idEnd >= 0) { 653 id = DocumentUtilities.getText(doc, idStart, idEnd - idStart); 654 ret = new int[] { idStart, idEnd }; 655 CharSequence trim = CharSequenceUtilities.trim(id); 656 if (trim.length() == 0 || (trim.length() == 1 && !Character.isJavaIdentifierPart(trim.charAt(0)))) { 657 int prevWordStart = javax.swing.text.Utilities.getPreviousWord(c, offset); 658 if (offset == javax.swing.text.Utilities.getWordEnd(c,prevWordStart )){ 659 ret = new int[] { prevWordStart, offset }; 660 } else { 661 return null; 662 } 663 } else if ((id != null) && (id.length() != 0) && (CharSequenceUtilities.indexOf(id, '.') != -1)){ int index = offset - idStart; 665 int begin = CharSequenceUtilities.lastIndexOf(id.subSequence(0, index), '.'); 666 begin = (begin == -1) ? 0 : begin + 1; int end = CharSequenceUtilities.indexOf(id, '.', index); 668 end = (end == -1) ? id.length() : end; 669 ret = new int[] { idStart+begin, idStart+end }; 670 } 671 } 672 } 673 return ret; 674 } 675 676 677 678 686 public static int[] getIdentifierBlock(BaseDocument doc, int offset) 687 throws BadLocationException { 688 int[] ret = null; 689 int idStart = getWordStart(doc, offset); 690 if (idStart >= 0) { 691 int idEnd = getWordEnd(doc, idStart); 692 if (idEnd >= 0) { 693 String id = doc.getText(idStart, idEnd - idStart); 694 if (doc.getSyntaxSupport().isIdentifier(id)) { 695 ret = new int[] { idStart, idEnd }; 696 } else { id = getWord(doc, offset); if (doc.getSyntaxSupport().isIdentifier(id)) { 699 ret = new int[] { offset, offset + id.length() }; 700 } 701 } 702 } 703 } 704 return ret; 705 } 706 707 708 713 public static String getWord(JTextComponent c, int offset) 714 throws BadLocationException { 715 int[] blk = getIdentifierBlock(c, offset); 716 Document doc = c.getDocument(); 717 return (blk != null) ? doc.getText(blk[0], blk[1] - blk[0]) : null; 718 } 719 720 721 728 public static int[] getSelectionOrIdentifierBlock(JTextComponent c, int offset) 729 throws BadLocationException { 730 Document doc = c.getDocument(); 731 Caret caret = c.getCaret(); 732 int[] ret; 733 if (caret.isSelectionVisible()) { 734 ret = new int[] { c.getSelectionStart(), c.getSelectionEnd() }; 735 } else if (doc instanceof BaseDocument){ 736 ret = getIdentifierBlock((BaseDocument)doc, caret.getDot()); 737 } else { 738 ret = getIdentifierBlock(c, offset); 739 } 740 return ret; 741 } 742 743 746 public static int[] getSelectionOrIdentifierBlock(JTextComponent c) { 747 try { 748 return getSelectionOrIdentifierBlock(c, c.getCaret().getDot()); 749 } catch (BadLocationException e) { 750 return null; 751 } 752 } 753 754 757 public static String getIdentifierBefore(BaseDocument doc, int offset) 758 throws BadLocationException { 759 int wordStart = getWordStart(doc, offset); 760 if (wordStart != -1) { 761 String word = new String (doc.getChars(wordStart, 762 offset - wordStart), 0, offset - wordStart); 763 if (doc.getSyntaxSupport().isIdentifier(word)) { 764 return word; 765 } 766 } 767 return null; 768 } 769 770 773 public static String getSelectionOrIdentifier(JTextComponent c, int offset) 774 throws BadLocationException { 775 Document doc = c.getDocument(); 776 Caret caret = c.getCaret(); 777 String ret; 778 if (caret.isSelectionVisible()) { 779 ret = c.getSelectedText(); 780 if (ret != null) return ret; 781 } 782 if (doc instanceof BaseDocument){ 783 ret = getIdentifier((BaseDocument) doc, caret.getDot()); 784 } else { 785 ret = getWord(c, offset); 786 } 787 return ret; 788 } 789 790 791 public static String getSelectionOrIdentifier(JTextComponent c) { 792 try { 793 return getSelectionOrIdentifier(c, c.getCaret().getDot()); 794 } catch (BadLocationException e) { 795 return null; 796 } 797 } 798 799 801 public static String getWord(BaseDocument doc, int offset) 802 throws BadLocationException { 803 int wordEnd = getWordEnd(doc, offset); 804 if (wordEnd != -1) { 805 return new String (doc.getChars(offset, wordEnd - offset), 0, 806 wordEnd - offset); 807 } 808 return null; 809 } 810 811 812 818 public static boolean changeCase(BaseDocument doc, int offset, int len, int type) 819 throws BadLocationException { 820 char[] orig = doc.getChars(offset, len); 821 char[] changed = (char[])orig.clone(); 822 for (int i = 0; i < orig.length; i++) { 823 switch (type) { 824 case CASE_UPPER: 825 changed[i] = Character.toUpperCase(orig[i]); 826 break; 827 case CASE_LOWER: 828 changed[i] = Character.toLowerCase(orig[i]); 829 break; 830 case CASE_SWITCH: 831 if (Character.isUpperCase(orig[i])) { 832 changed[i] = Character.toLowerCase(orig[i]); 833 } else if (Character.isLowerCase(orig[i])) { 834 changed[i] = Character.toUpperCase(orig[i]); 835 } 836 break; 837 } 838 } 839 for (int i = 0; i < orig.length; i++) { 841 if (orig[i] != changed[i]) { 842 doc.atomicLock(); 843 try { 844 doc.remove(offset, orig.length); 845 doc.insertString(offset, new String (changed), null); 846 } finally { 847 doc.atomicUnlock(); 848 } 849 return true; } 851 } 852 return false; 853 } 854 855 860 public static boolean isRowEmpty(BaseDocument doc, int offset) 861 throws BadLocationException { 862 Element lineElement = doc.getParagraphElement(offset); 863 return (lineElement.getStartOffset() + 1 == lineElement.getEndOffset()); 864 } 865 866 public static int getFirstNonEmptyRow(BaseDocument doc, int offset, boolean downDir) 867 throws BadLocationException { 868 while (offset != -1 && isRowEmpty(doc, offset)) { 869 offset = getRowStart(doc, offset, downDir ? +1 : -1); 870 } 871 return offset; 872 } 873 874 879 public static boolean isRowWhite(BaseDocument doc, int offset) 880 throws BadLocationException { 881 Element lineElement = doc.getParagraphElement(offset); 882 offset = doc.find(new FinderFactory.NonWhiteFwdFinder(doc), 883 lineElement.getStartOffset(), lineElement.getEndOffset() - 1); 884 return (offset == -1); 885 } 886 887 public static int getFirstNonWhiteRow(BaseDocument doc, int offset, boolean downDir) 888 throws BadLocationException { 889 if (isRowWhite(doc, offset)) { 890 if (downDir) { offset = getFirstNonWhiteFwd(doc, offset); 892 } else { offset = getFirstNonWhiteBwd(doc, offset); 894 } 895 } 896 return offset; 897 } 898 899 905 public static int reformat(BaseDocument doc, int startOffset, int endOffset) 906 throws BadLocationException { 907 return doc.getFormatter().reformat(doc, startOffset, endOffset); 908 } 909 910 911 public static void reformatLine(BaseDocument doc, int pos) 912 throws BadLocationException { 913 int lineStart = getRowStart(doc, pos); 914 int lineEnd = getRowEnd(doc, pos); 915 reformat(doc, lineStart, lineEnd); 916 } 917 918 919 public static int getRowCount(BaseDocument doc, int startPos, int endPos) 920 throws BadLocationException { 921 if (startPos > endPos) { 922 return 0; 923 } 924 Element lineRoot = doc.getParagraphElement(0).getParentElement(); 925 return lineRoot.getElementIndex(endPos) - lineRoot.getElementIndex(startPos) + 1; 926 } 927 928 929 public static int getRowCount(BaseDocument doc) { 930 return doc.getParagraphElement(0).getParentElement().getElementCount(); 931 } 932 933 936 public static String getTabInsertString(BaseDocument doc, int offset) 937 throws BadLocationException { 938 int col = getVisualColumn(doc, offset); 939 Formatter f = doc.getFormatter(); 940 boolean expandTabs = f.expandTabs(); 941 if (expandTabs) { 942 int spacesPerTab = f.getSpacesPerTab(); 943 int len = (col + spacesPerTab) / spacesPerTab * spacesPerTab - col; 944 return new String (Analyzer.getSpacesBuffer(len), 0, len); 945 } else { return "\t"; } 948 } 949 950 955 public static int getNextTabColumn(BaseDocument doc, int offset) 956 throws BadLocationException { 957 int col = getVisualColumn(doc, offset); 958 int tabSize = doc.getFormatter().getSpacesPerTab(); 959 return (col + tabSize) / tabSize * tabSize; 960 } 961 962 public static void setStatusText(JTextComponent c, String text) { 963 StatusBar sb = getEditorUI(c).getStatusBar(); 964 if (sb != null) { 965 sb.setText(StatusBar.CELL_MAIN, text); 966 } 967 } 968 969 public static void setStatusText(JTextComponent c, String text, 970 Coloring extraColoring) { 971 StatusBar sb = getEditorUI(c).getStatusBar(); 972 if (sb != null) { 973 sb.setText(StatusBar.CELL_MAIN, text, extraColoring); 974 } 975 } 976 977 public static void setStatusBoldText(JTextComponent c, String text) { 978 StatusBar sb = getEditorUI(c).getStatusBar(); 979 if (sb != null) { 980 sb.setBoldText(StatusBar.CELL_MAIN, text); 981 } 982 } 983 984 public static String getStatusText(JTextComponent c) { 985 StatusBar sb = getEditorUI(c).getStatusBar(); 986 return (sb != null) ? sb.getText(StatusBar.CELL_MAIN) : null; 987 } 988 989 public static void clearStatusText(JTextComponent c) { 990 setStatusText(c, ""); } 992 993 public static void insertMark(BaseDocument doc, Mark mark, int offset) 994 throws BadLocationException , InvalidMarkException { 995 mark.insert(doc, offset); 996 } 997 998 public static void moveMark(BaseDocument doc, Mark mark, int newOffset) 999 throws BadLocationException , InvalidMarkException { 1000 mark.move(doc, newOffset); 1001 } 1002 1003 public static void returnFocus() { 1004 JTextComponent c = getLastActiveComponent(); 1005 if (c != null) { 1006 requestFocus(c); 1007 } 1008 } 1009 1010 public static void requestFocus(JTextComponent c) { 1011 if (c != null) { 1012 if (!ImplementationProvider.getDefault().activateComponent(c)) { 1013 Frame f = EditorUI.getParentFrame(c); 1014 if (f != null) { 1015 f.requestFocus(); 1016 } 1017 c.requestFocus(); 1018 } 1019 } 1020 } 1021 1022 public static void runInEventDispatchThread(Runnable r) { 1023 if (SwingUtilities.isEventDispatchThread()) { 1024 r.run(); 1025 } else { 1026 SwingUtilities.invokeLater(r); 1027 } 1028 } 1029 1030 public static String debugPosition(BaseDocument doc, int offset) { 1031 String ret; 1032 1033 if (offset >= 0) { 1034 try { 1035 int line = getLineOffset(doc, offset) + 1; 1036 int col = getVisualColumn(doc, offset) + 1; 1037 ret = String.valueOf(line) + ":" + String.valueOf(col); } catch (BadLocationException e) { 1039 ret = NbBundle.getBundle(BaseKit.class).getString( WRONG_POSITION_LOCALE ) 1040 + ' ' + offset + " > " + doc.getLength(); } 1042 } else { 1043 ret = String.valueOf(offset); 1044 } 1045 1046 return ret; 1047 } 1048 1049 public static String offsetToLineColumnString(BaseDocument doc, int offset) { 1050 return String.valueOf(offset) + "[" + debugPosition(doc, offset) + "]"; } 1052 1053 1056 public static String debugDocument(Document doc) { 1057 return "<" + System.identityHashCode(doc) + ", title='" + doc.getProperty(Document.TitleProperty) 1059 + "', stream='" + doc.getProperty(Document.StreamDescriptionProperty) 1060 + ", " + doc.toString() + ">"; } 1062 1063 public static void performAction(Action a, ActionEvent evt, JTextComponent target) { 1064 if (a instanceof BaseAction) { 1065 ((BaseAction)a).actionPerformed(evt, target); 1066 } else { 1067 a.actionPerformed(evt); 1068 } 1069 } 1070 1071 1073 public static JTextComponent getLastActiveComponent() { 1074 return Registry.getMostActiveComponent(); 1075 } 1076 1077 1082 public static JTextComponent getFocusedComponent() { 1083 1084 class FocusedComponentAction extends TextAction { 1085 1086 FocusedComponentAction() { 1087 super("focused-component"); } 1089 1090 1091 JTextComponent getFocusedComponent2() { 1092 return getFocusedComponent(); 1093 } 1094 1095 public void actionPerformed(ActionEvent evt){} 1096 }; 1097 1098 if (focusedComponentAction == null) { 1099 focusedComponentAction = new FocusedComponentAction(); 1100 } 1101 1102 return ((FocusedComponentAction)focusedComponentAction).getFocusedComponent2(); 1103 } 1104 1105 1112 public static EditorUI getEditorUI(JTextComponent target) { 1113 TextUI ui = target.getUI(); 1114 return (ui instanceof BaseTextUI) 1115 ? ((BaseTextUI)ui).getEditorUI() 1116 : null; 1117 } 1118 1119 1126 public static BaseKit getKit(JTextComponent target) { 1127 if (target == null) return null; EditorKit ekit = target.getUI().getEditorKit(target); 1129 return (ekit instanceof BaseKit) ? (BaseKit)ekit : null; 1130 } 1131 1132 1153 public static Class getKitClass(JTextComponent target) { 1154 EditorKit kit = (target != null) ? target.getUI().getEditorKit(target) : null; 1155 return (kit != null) ? kit.getClass() : null; 1156 } 1157 1158 1165 public static BaseDocument getDocument(JTextComponent target) { 1166 Document doc = target.getDocument(); 1167 return (doc instanceof BaseDocument) ? (BaseDocument)doc : null; 1168 } 1169 1170 1179 public static SyntaxSupport getSyntaxSupport(JTextComponent target) { 1180 Document doc = target.getDocument(); 1181 return (doc instanceof BaseDocument) ? ((BaseDocument)doc).getSyntaxSupport() : null; 1182 } 1183 1184 1194 public static View getRootView(JTextComponent component, Class rootViewClass) { 1195 View view = null; 1196 TextUI textUI = component.getUI(); 1197 if (textUI != null) { 1198 view = textUI.getRootView(component); 1199 while (view != null && !rootViewClass.isInstance(view) 1200 && view.getViewCount() == 1 ) { 1202 view = view.getView(0); } 1204 } 1205 1206 return view; 1207 } 1208 1209 1214 public static View getDocumentView(JTextComponent component) { 1215 return getRootView(component, DrawEngineDocView.class); 1216 } 1217 1218 1224 public static String keySequenceToString( KeyStroke [] seq ) { 1225 StringBuffer sb = new StringBuffer (); 1226 for( int i=0; i<seq.length; i++ ) { 1227 if( i>0 ) sb.append( ' ' ); sb.append( keyStrokeToString( seq[i] ) ); 1229 } 1230 return sb.toString(); 1231 } 1232 1233 1239 public static String keyStrokeToString( KeyStroke stroke ) { 1240 String modifText = KeyEvent.getKeyModifiersText( stroke.getModifiers() ); 1241 String keyText = (stroke.getKeyCode() == KeyEvent.VK_UNDEFINED) ? 1242 String.valueOf(stroke.getKeyChar()) : getKeyText(stroke.getKeyCode()); 1243 if( modifText.length() > 0 ) return modifText + '+' + keyText; 1244 else return keyText; 1245 } 1246 1247 1250 private static String getKeyText(int keyCode) { 1251 String ret = KeyEvent.getKeyText(keyCode); 1252 if (ret != null) { 1253 switch (keyCode) { 1254 case KeyEvent.VK_KP_DOWN: 1255 ret = prefixNumpad(ret, KeyEvent.VK_DOWN); 1256 break; 1257 case KeyEvent.VK_KP_LEFT: 1258 ret = prefixNumpad(ret, KeyEvent.VK_LEFT); 1259 break; 1260 case KeyEvent.VK_KP_RIGHT: 1261 ret = prefixNumpad(ret, KeyEvent.VK_RIGHT); 1262 break; 1263 case KeyEvent.VK_KP_UP: 1264 ret = prefixNumpad(ret, KeyEvent.VK_UP); 1265 break; 1266 } 1267 } 1268 return ret; 1269 } 1270 1271 private static String prefixNumpad(String key, int testKeyCode) { 1272 if (key.equals(KeyEvent.getKeyText(testKeyCode))) { 1273 key = NbBundle.getBundle(BaseKit.class).getString("key-prefix-numpad") + key; 1274 } 1275 return key; 1276 } 1277 1278 private static void checkOffsetValid(Document doc, int offset) throws BadLocationException { 1279 checkOffsetValid(offset, doc.getLength()); 1280 } 1281 1282 private static void checkOffsetValid(int offset, int limitOffset) throws BadLocationException { 1283 if (offset < 0 || offset > limitOffset) { 1284 throw new BadLocationException ("Invalid offset=" + offset + " not within <0, " + limitOffset + ">", offset); 1287 } 1288 } 1289 1290 1300 public static void annotateLoggable(Throwable t) { 1301 Logger.getLogger("org.netbeans.editor").log(Level.INFO, null, t); } 1303 1304} 1305 | Popular Tags |