1 7 8 package com.sun.java.swing; 9 10 import java.security.*; 11 import java.lang.reflect.*; 12 import java.awt.*; 13 import java.awt.event.*; 14 import java.awt.font.*; 15 import java.awt.geom.*; 16 import java.awt.print.PrinterGraphics ; 17 import java.text.AttributedCharacterIterator ; 18 import javax.swing.*; 19 import javax.swing.plaf.*; 20 import javax.swing.text.Highlighter ; 21 import javax.swing.text.JTextComponent ; 22 import javax.swing.text.DefaultHighlighter ; 23 import javax.swing.text.DefaultCaret ; 24 import javax.swing.table.TableCellRenderer ; 25 import sun.swing.PrintColorUIResource; 26 import sun.print.ProxyPrintGraphics; 27 import sun.awt.AppContext; 28 import sun.font.FontDesignMetrics; 29 import sun.java2d.SunGraphics2D; 30 import sun.security.action.GetPropertyAction; 31 import sun.security.util.SecurityConstants; 32 import java.io.*; 33 34 44 public class SwingUtilities2 { 45 private static LSBCacheEntry[] fontCache; 49 private static final int CACHE_SIZE = 6; 52 private static int nextIndex; 54 private static LSBCacheEntry searchKey; 57 58 private static final int MIN_CHAR_INDEX = (int)'W'; 61 private static final int MAX_CHAR_INDEX = (int)'W' + 1; 62 63 private static final FontRenderContext DEFAULT_FRC = new FontRenderContext( 64 null, false, false); 65 66 69 public static final FontRenderContext AA_FRC; 70 71 81 85 private static final boolean AA_TEXT; 86 87 90 private static final boolean AA_TEXT_DEFINED; 91 92 96 public static final Object AA_TEXT_PROPERTY_KEY = 97 new StringBuffer ("AATextPropertyKey"); 98 99 103 private static final StringBuilder SKIP_CLICK_COUNT = 104 new StringBuilder ("skipClickCount"); 105 106 112 public static final boolean DRAG_FIX; 113 114 private static Field inputEvent_CanAccessSystemClipboard_Field = null; 116 private static final String UntrustedClipboardAccess = 117 "UNTRUSTED_CLIPBOARD_ACCESS_KEY"; 118 119 static { 120 fontCache = new LSBCacheEntry[CACHE_SIZE]; 121 Object aa = java.security.AccessController.doPrivileged( 122 new GetPropertyAction("swing.aatext")); 123 AA_TEXT_DEFINED = (aa != null); 124 AA_TEXT = "true".equals(aa); 125 AA_FRC = new FontRenderContext(null, true, false); 126 127 Object dragFix = java.security.AccessController.doPrivileged( 128 new GetPropertyAction("sun.swing.enableImprovedDragGesture")); 129 DRAG_FIX = (dragFix != null); 130 } 131 132 144 151 private static boolean drawTextAntialiased(JComponent c) { 152 if (!AA_TEXT_DEFINED) { 153 if (c != null) { 154 return ((Boolean )c.getClientProperty( 156 AA_TEXT_PROPERTY_KEY)).booleanValue(); 157 } 158 return false; 160 } 161 return AA_TEXT; 163 } 164 165 172 public static boolean drawTextAntialiased(boolean aaText) { 173 if (!AA_TEXT_DEFINED) { 174 return aaText; 176 } 177 return AA_TEXT; 179 } 180 181 191 public static int getLeftSideBearing(JComponent c, FontMetrics fm, 192 String string) { 193 return getLeftSideBearing(c, fm, string.charAt(0)); 194 } 195 196 197 205 public static int getLeftSideBearing(JComponent c, FontMetrics fm, 206 char firstChar) { 207 int charIndex = (int)firstChar; 208 if (charIndex < MAX_CHAR_INDEX && charIndex >= MIN_CHAR_INDEX) { 209 byte[] lsbs = null; 210 211 FontRenderContext frc = getFRC(c, fm); 212 Font font = fm.getFont(); 213 synchronized(SwingUtilities2.class) { 214 LSBCacheEntry entry = null; 215 if (searchKey == null) { 216 searchKey = new LSBCacheEntry(frc, font); 217 } 218 else { 219 searchKey.reset(frc, font); 220 } 221 for (LSBCacheEntry cacheEntry : fontCache) { 223 if (searchKey.equals(cacheEntry)) { 224 entry = cacheEntry; 225 break; 226 } 227 } 228 if (entry == null) { 229 entry = searchKey; 231 fontCache[nextIndex] = searchKey; 232 searchKey = null; 233 nextIndex = (nextIndex + 1) % CACHE_SIZE; 234 } 235 return entry.getLeftSideBearing(firstChar); 236 } 237 } 238 return 0; 239 } 240 241 242 258 public static FontMetrics getFontMetrics(JComponent c, Graphics g) { 259 return getFontMetrics(c, g, g.getFont()); 260 } 261 262 263 280 public static FontMetrics getFontMetrics(JComponent c, Graphics g, 281 Font font) { 282 if (c != null) { 283 return c.getFontMetrics(font); 287 } 288 return Toolkit.getDefaultToolkit().getFontMetrics(font); 289 } 290 291 292 299 public static int stringWidth(JComponent c, FontMetrics fm, String string){ 300 return fm.stringWidth(string); 301 } 302 303 304 305 314 public static String clipStringIfNecessary(JComponent c, FontMetrics fm, 315 String string, 316 int availTextWidth) { 317 if ((string == null) || (string.equals(""))) { 318 return ""; 319 } 320 int textWidth = SwingUtilities2.stringWidth(c, fm, string); 321 if (textWidth > availTextWidth) { 322 return SwingUtilities2.clipString(c, fm, string, availTextWidth); 323 } 324 return string; 325 } 326 327 328 338 public static String clipString(JComponent c, FontMetrics fm, 339 String string, int availTextWidth) { 340 String clipString = "..."; 342 int width = SwingUtilities2.stringWidth(c, fm, clipString); 343 int nChars = 0; 346 for(int max = string.length(); nChars < max; nChars++) { 347 width += fm.charWidth(string.charAt(nChars)); 348 if (width > availTextWidth) { 349 break; 350 } 351 } 352 string = string.substring(0, nChars) + clipString; 353 return string; 354 } 355 356 360 private static FontRenderContext getFRC(JComponent c, FontMetrics fm) { 361 if (fm instanceof FontDesignMetrics) { 363 return ((FontDesignMetrics)fm).getFRC(); 364 } 365 if (fm == null && c != null) { 366 return getFRC(c, c.getFontMetrics(c.getFont())); 369 } 370 371 assert false; 374 return DEFAULT_FRC; 375 } 376 377 378 387 public static void drawString(JComponent c, Graphics g, String text, 388 int x, int y) { 389 391 if ( text == null || text.length() <= 0 ) { return; 396 } 397 if (isPrinting(g)) { 398 Graphics2D g2d = getGraphics2D(g); 399 if (g2d != null) { 400 TextLayout layout = new TextLayout(text, g2d.getFont(), 401 DEFAULT_FRC); 402 403 404 Color col = g2d.getColor(); 405 if (col instanceof PrintColorUIResource) { 406 g2d.setColor(((PrintColorUIResource)col).getPrintColor()); 407 } 408 409 layout.draw(g2d, x, y); 410 411 g2d.setColor(col); 412 413 return; 414 } 415 } 416 417 if (drawTextAntialiased(c) && (g instanceof Graphics2D)) { 419 Graphics2D g2 = (Graphics2D)g; 420 Object oldAAValue = g2.getRenderingHint( 421 RenderingHints.KEY_TEXT_ANTIALIASING); 422 g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 423 RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 424 g.drawString(text, x, y); 425 g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 426 oldAAValue); 427 } 428 else { 429 g.drawString(text, x, y); 430 } 431 } 432 433 434 445 public static void drawStringUnderlineCharAt(JComponent c,Graphics g, 446 String text, int underlinedIndex, int x,int y) { 447 SwingUtilities2.drawString(c, g, text, x, y); 448 if (underlinedIndex >= 0 && underlinedIndex < text.length() ) { 449 FontMetrics fm = g.getFontMetrics(); 451 int underlineRectX = x + SwingUtilities2.stringWidth(c, 452 fm, text.substring(0,underlinedIndex)); 453 int underlineRectY = y; 454 int underlineRectWidth = fm.charWidth(text. 455 charAt(underlinedIndex)); 456 int underlineRectHeight = 1; 457 g.fillRect(underlineRectX, underlineRectY + 1, 458 underlineRectWidth, underlineRectHeight); 459 } 460 } 461 462 463 470 public static int loc2IndexFileList(JList list, Point point) { 471 int index = list.locationToIndex(point); 472 if (index != -1) { 473 Object bySize = list.getClientProperty("List.isFileList"); 474 if (bySize instanceof Boolean && ((Boolean )bySize).booleanValue() && 475 !pointIsInActualBounds(list, index, point)) { 476 index = -1; 477 } 478 } 479 return index; 480 } 481 482 483 487 private static boolean pointIsInActualBounds(JList list, int index, 488 Point point) { 489 ListCellRenderer renderer = list.getCellRenderer(); 490 ListModel dataModel = list.getModel(); 491 Object value = dataModel.getElementAt(index); 492 Component item = renderer.getListCellRendererComponent(list, 493 value, index, false, false); 494 Dimension itemSize = item.getPreferredSize(); 495 Rectangle cellBounds = list.getCellBounds(index, index); 496 if (!item.getComponentOrientation().isLeftToRight()) { 497 cellBounds.x += (cellBounds.width - itemSize.width); 498 } 499 cellBounds.width = itemSize.width; 500 cellBounds.height = itemSize.height; 501 502 return cellBounds.contains(point); 503 } 504 505 506 513 public static boolean pointOutsidePrefSize(JTable table, int row, int column, Point p) { 514 if (table.convertColumnIndexToModel(column) != 0 || row == -1) { 515 return true; 516 } 517 TableCellRenderer tcr = table.getCellRenderer(row, column); 518 Object value = table.getValueAt(row, column); 519 Component cell = tcr.getTableCellRendererComponent(table, value, false, 520 false, row, column); 521 Dimension itemSize = cell.getPreferredSize(); 522 Rectangle cellBounds = table.getCellRect(row, column, false); 523 cellBounds.width = itemSize.width; 524 cellBounds.height = itemSize.height; 525 526 assert (p.x >= cellBounds.x && p.y >= cellBounds.y); 529 if (p.x > cellBounds.x + cellBounds.width || 530 p.y > cellBounds.y + cellBounds.height) { 531 return true; 532 } 533 return false; 534 } 535 536 540 public static boolean shouldIgnore(MouseEvent me, JComponent c) { 541 return c == null || !c.isEnabled() 542 || !SwingUtilities.isLeftMouseButton(me); 543 } 544 545 549 public static void adjustFocus(JComponent c) { 550 if (!c.hasFocus() && c.isRequestFocusEnabled()) { 551 c.requestFocus(); 552 } 553 } 554 555 561 public static int drawChars(JComponent c, Graphics g, 562 char[] data, 563 int offset, 564 int length, 565 int x, 566 int y) { 567 if ( length <= 0 ) { return x; 569 } 570 int nextX = x + getFontMetrics(c, g).charsWidth(data, offset, length); 571 if (isPrinting(g)) { 572 Graphics2D g2d = getGraphics2D(g); 573 if (g2d != null) { 574 FontRenderContext deviceFontRenderContext = g2d. 575 getFontRenderContext(); 576 FontRenderContext frc = getFRC(c, null); 577 if (frc.isAntiAliased() || frc.usesFractionalMetrics()) { 578 frc = new FontRenderContext(frc.getTransform(), false, false); 579 } 580 if (frc != null 581 && ! isFontRenderContextCompatible(deviceFontRenderContext, 582 frc)) { 583 TextLayout layout = 584 new TextLayout(new String (data,offset,length), 585 g2d.getFont(), 586 frc); 587 588 589 Color col = g2d.getColor(); 590 if (col instanceof PrintColorUIResource) { 591 g2d.setColor(((PrintColorUIResource)col).getPrintColor()); 592 } 593 594 layout.draw(g2d,x,y); 595 596 g2d.setColor(col); 597 598 return nextX; 599 } 600 } 601 } 602 if (drawTextAntialiased(c) && (g instanceof Graphics2D)) { 604 Graphics2D g2 = (Graphics2D)g; 605 Object oldAAValue = g2.getRenderingHint( 606 RenderingHints.KEY_TEXT_ANTIALIASING); 607 g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 608 RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 609 g.drawChars(data, offset, length, x, y); 610 g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 611 oldAAValue); 612 } 613 else { 614 g.drawChars(data, offset, length, x, y); 615 } 616 return nextX; 617 } 618 619 623 public static float drawString(JComponent c, Graphics g, 624 AttributedCharacterIterator iterator, 625 int x, 626 int y) { 627 628 float retVal; 629 boolean isPrinting = isPrinting(g); 630 Color col = g.getColor(); 631 632 if (isPrinting) { 633 634 if (col instanceof PrintColorUIResource) { 635 g.setColor(((PrintColorUIResource)col).getPrintColor()); 636 } 637 } 638 639 Graphics2D g2d = getGraphics2D(g); 640 if (g2d == null) { 641 g.drawString(iterator,x,y); retVal = x; 644 645 } else { 646 FontRenderContext frc; 647 if (isPrinting) { 648 frc = getFRC(c, null); 649 if (frc.isAntiAliased() || frc.usesFractionalMetrics()) { 650 frc = new FontRenderContext(frc.getTransform(), false, false); 651 } 652 } else if (drawTextAntialiased(c)) { 653 frc = AA_FRC; 654 } else { 655 frc = g2d.getFontRenderContext(); 656 } 657 TextLayout layout = new TextLayout(iterator, frc); 658 layout.draw(g2d, x, y); 659 retVal = layout.getAdvance(); 660 } 661 662 if (isPrinting) { 663 g.setColor(col); 664 } 665 666 return retVal; 667 } 668 669 673 public static boolean isFontRenderContextCompatible(FontRenderContext frc1, 674 FontRenderContext frc2) { 675 return (frc1 != null) ? frc1.equals(frc2) : frc2 == null; 676 } 677 678 682 public static Graphics2D getGraphics2D(Graphics g) { 683 if (g instanceof Graphics2D) { 684 return (Graphics2D) g; 685 } else if (g instanceof ProxyPrintGraphics) { 686 return (Graphics2D)(((ProxyPrintGraphics)g).getGraphics()); 687 } else { 688 return null; 689 } 690 } 691 692 696 public static FontRenderContext getFontRenderContext(Component c) { 697 if (c == null) { 698 return DEFAULT_FRC; 699 } else { 700 return getFRC(null, c.getFontMetrics(c.getFont())); 701 } 702 } 703 704 708 static boolean isPrinting(Graphics g) { 709 return (g instanceof PrinterGraphics || g instanceof PrintGraphics); 710 } 711 712 723 public static boolean useSelectedTextColor(Highlighter.Highlight h, JTextComponent c) { 724 Highlighter.HighlightPainter painter = h.getPainter(); 725 String painterClass = painter.getClass().getName(); 726 if (painterClass.indexOf("javax.swing.text.DefaultHighlighter") != 0 && 727 painterClass.indexOf("com.sun.java.swing.plaf.windows.WindowsTextUI") != 0) { 728 return false; 729 } 730 try { 731 DefaultHighlighter.DefaultHighlightPainter defPainter = 732 (DefaultHighlighter.DefaultHighlightPainter ) painter; 733 if (defPainter.getColor() != null && 734 !defPainter.getColor().equals(c.getSelectionColor())) { 735 return false; 736 } 737 } catch (ClassCastException e) { 738 return false; 739 } 740 return true; 741 } 742 743 749 private static class LSBCacheEntry { 750 private static final byte UNSET = Byte.MAX_VALUE; 752 private static final char[] oneChar = new char[1]; 754 755 private byte[] lsbCache; 756 private Font font; 757 private FontRenderContext frc; 758 759 public LSBCacheEntry(FontRenderContext frc, Font font) { 760 lsbCache = new byte[MAX_CHAR_INDEX - MIN_CHAR_INDEX]; 761 reset(frc, font); 762 } 763 764 public void reset(FontRenderContext frc, Font font) { 765 this.font = font; 766 this.frc = frc; 767 for (int counter = lsbCache.length - 1; counter >= 0; counter--) { 768 lsbCache[counter] = UNSET; 769 } 770 } 771 772 public int getLeftSideBearing(char aChar) { 773 int index = aChar - MIN_CHAR_INDEX; 774 assert (index >= 0 && index < (MAX_CHAR_INDEX - MIN_CHAR_INDEX)); 775 byte lsb = lsbCache[index]; 776 if (lsb == UNSET) { 777 oneChar[0] = aChar; 778 GlyphVector gv = font.createGlyphVector(frc, oneChar); 779 lsb = (byte)gv.getGlyphPixelBounds(0, frc, 0f, 0f).x; 780 lsbCache[index] = lsb; 781 } 782 return lsb; 783 } 784 785 public boolean equals(Object entry) { 786 if (entry == this) { 787 return true; 788 } 789 if (!(entry instanceof LSBCacheEntry)) { 790 return false; 791 } 792 LSBCacheEntry oEntry = (LSBCacheEntry)entry; 793 return (font.equals(oEntry.font) && 794 frc.equals(oEntry.frc)); 795 } 796 797 public int hashCode() { 798 int result = 17; 799 if (font != null) { 800 result = 37 * result + font.hashCode(); 801 } 802 if (frc != null) { 803 result = 37 * result + frc.hashCode(); 804 } 805 return result; 806 } 807 } 808 809 810 811 818 819 820 827 public static boolean canAccessSystemClipboard() { 828 boolean canAccess = false; 829 if (!GraphicsEnvironment.isHeadless()) { 830 SecurityManager sm = System.getSecurityManager(); 831 if (sm == null) { 832 canAccess = true; 833 } else { 834 try { 835 sm.checkSystemClipboardAccess(); 836 canAccess = true; 837 } catch (SecurityException e) { 838 } 839 if (canAccess && ! isTrustedContext()) { 840 canAccess = canCurrentEventAccessSystemClipboard(true); 841 } 842 } 843 } 844 return canAccess; 845 } 846 847 851 public static boolean canCurrentEventAccessSystemClipboard() { 852 return isTrustedContext() 853 || canCurrentEventAccessSystemClipboard(false); 854 } 855 856 862 public static boolean canEventAccessSystemClipboard(AWTEvent e) { 863 return isTrustedContext() 864 || canEventAccessSystemClipboard(e, false); 865 } 866 867 872 private static synchronized boolean inputEvent_canAccessSystemClipboard(InputEvent ie) { 873 if (inputEvent_CanAccessSystemClipboard_Field == null) { 874 inputEvent_CanAccessSystemClipboard_Field = 875 (Field)AccessController.doPrivileged( 876 new java.security.PrivilegedAction () { 877 public Object run() { 878 Field field = null; 879 try { 880 field = InputEvent.class. 881 getDeclaredField("canAccessSystemClipboard"); 882 field.setAccessible(true); 883 return field; 884 } catch (SecurityException e) { 885 } catch (NoSuchFieldException e) { 886 } 887 return null; 888 } 889 }); 890 } 891 if (inputEvent_CanAccessSystemClipboard_Field == null) { 892 return false; 893 } 894 boolean ret = false; 895 try { 896 ret = inputEvent_CanAccessSystemClipboard_Field. 897 getBoolean(ie); 898 } catch(IllegalAccessException e) { 899 } 900 return ret; 901 } 902 903 909 910 private static boolean isAccessClipboardGesture(InputEvent ie) { 911 boolean allowedGesture = false; 912 if (ie instanceof KeyEvent) { KeyEvent ke = (KeyEvent)ie; 914 int keyCode = ke.getKeyCode(); 915 int keyModifiers = ke.getModifiers(); 916 switch(keyCode) { 917 case KeyEvent.VK_C: 918 case KeyEvent.VK_V: 919 case KeyEvent.VK_X: 920 allowedGesture = (keyModifiers == InputEvent.CTRL_MASK); 921 break; 922 case KeyEvent.VK_INSERT: 923 allowedGesture = (keyModifiers == InputEvent.CTRL_MASK || 924 keyModifiers == InputEvent.SHIFT_MASK); 925 break; 926 case KeyEvent.VK_COPY: 927 case KeyEvent.VK_PASTE: 928 case KeyEvent.VK_CUT: 929 allowedGesture = true; 930 break; 931 case KeyEvent.VK_DELETE: 932 allowedGesture = ( keyModifiers == InputEvent.SHIFT_MASK); 933 break; 934 } 935 } 936 return allowedGesture; 937 } 938 939 947 private static boolean canEventAccessSystemClipboard(AWTEvent e, 948 boolean checkGesture) { 949 if (EventQueue.isDispatchThread()) { 950 954 if (e instanceof InputEvent 955 && (! checkGesture || isAccessClipboardGesture((InputEvent)e))) { 956 return inputEvent_canAccessSystemClipboard((InputEvent)e); 957 } else { 958 return false; 959 } 960 } else { 961 return true; 962 } 963 } 964 965 972 private static boolean canCurrentEventAccessSystemClipboard(boolean 973 checkGesture) { 974 AWTEvent event = EventQueue.getCurrentEvent(); 975 return canEventAccessSystemClipboard(event, checkGesture); 976 } 977 978 983 private static boolean isTrustedContext() { 984 return (System.getSecurityManager() == null) 985 || (AppContext.getAppContext(). 986 get(UntrustedClipboardAccess) == null); 987 } 988 989 public static String displayPropertiesToCSS(Font font, Color fg) { 990 StringBuffer rule = new StringBuffer ("body {"); 991 if (font != null) { 992 rule.append(" font-family: "); 993 rule.append(font.getFamily()); 994 rule.append(" ; "); 995 rule.append(" font-size: "); 996 rule.append(font.getSize()); 997 rule.append("pt ;"); 998 if (font.isBold()) { 999 rule.append(" font-weight: 700 ; "); 1000 } 1001 if (font.isItalic()) { 1002 rule.append(" font-style: italic ; "); 1003 } 1004 } 1005 if (fg != null) { 1006 rule.append(" color: #"); 1007 if (fg.getRed() < 16) { 1008 rule.append('0'); 1009 } 1010 rule.append(Integer.toHexString(fg.getRed())); 1011 if (fg.getGreen() < 16) { 1012 rule.append('0'); 1013 } 1014 rule.append(Integer.toHexString(fg.getGreen())); 1015 if (fg.getBlue() < 16) { 1016 rule.append('0'); 1017 } 1018 rule.append(Integer.toHexString(fg.getBlue())); 1019 rule.append(" ; "); 1020 } 1021 rule.append(" }"); 1022 return rule.toString(); 1023 } 1024 1025 1042 public static Object makeIcon(final Class <?> baseClass, 1043 final Class <?> rootClass, 1044 final String imageFile) { 1045 1046 return new UIDefaults.LazyValue() { 1047 public Object createValue(UIDefaults table) { 1048 1055 byte[] buffer = (byte[]) 1056 java.security.AccessController.doPrivileged( 1057 new java.security.PrivilegedAction () { 1058 public Object run() { 1059 try { 1060 InputStream resource = null; 1061 Class <?> srchClass = baseClass; 1062 1063 while (srchClass != null) { 1064 resource = srchClass.getResourceAsStream(imageFile); 1065 1066 if (resource != null || srchClass == rootClass) { 1067 break; 1068 } 1069 1070 srchClass = srchClass.getSuperclass(); 1071 } 1072 1073 if (resource == null) { 1074 return null; 1075 } 1076 1077 BufferedInputStream in = 1078 new BufferedInputStream(resource); 1079 ByteArrayOutputStream out = 1080 new ByteArrayOutputStream(1024); 1081 byte[] buffer = new byte[1024]; 1082 int n; 1083 while ((n = in.read(buffer)) > 0) { 1084 out.write(buffer, 0, n); 1085 } 1086 in.close(); 1087 out.flush(); 1088 return out.toByteArray(); 1089 } catch (IOException ioe) { 1090 System.err.println(ioe.toString()); 1091 } 1092 return null; 1093 } 1094 }); 1095 1096 if (buffer == null) { 1097 return null; 1098 } 1099 if (buffer.length == 0) { 1100 System.err.println("warning: " + imageFile + 1101 " is zero-length"); 1102 return null; 1103 } 1104 1105 return new IconUIResource(new ImageIcon(buffer)); 1106 } 1107 }; 1108 } 1109 1110 1117 public static void setSkipClickCount(Component comp, int count) { 1118 if (comp instanceof JTextComponent 1119 && ((JTextComponent ) comp).getCaret() instanceof DefaultCaret ) { 1120 1121 ((JTextComponent ) comp).putClientProperty(SKIP_CLICK_COUNT, count); 1122 } 1123 } 1124 1125 1133 public static int getAdjustedClickCount(JTextComponent comp, MouseEvent e) { 1134 int cc = e.getClickCount(); 1135 1136 if (cc == 1) { 1137 comp.putClientProperty(SKIP_CLICK_COUNT, null); 1138 } else { 1139 Integer sub = (Integer ) comp.getClientProperty(SKIP_CLICK_COUNT); 1140 if (sub != null) { 1141 return cc - sub; 1142 } 1143 } 1144 1145 return cc; 1146 } 1147} 1148 | Popular Tags |