| 1 7 package javax.swing.text; 8 9 import java.awt.*; 10 import java.awt.event.*; 11 import java.awt.datatransfer.*; 12 import java.beans.*; 13 import java.awt.event.ActionEvent ; 14 import java.awt.event.ActionListener ; 15 import java.io.*; 16 import javax.swing.*; 17 import javax.swing.event.*; 18 import javax.swing.plaf.*; 19 import java.util.EventListener ; 20 import com.sun.java.swing.SwingUtilities2; 21 22 91 public class DefaultCaret extends Rectangle implements Caret , FocusListener, MouseListener, MouseMotionListener { 92 93 100 public static final int UPDATE_WHEN_ON_EDT = 0; 101 102 113 public static final int NEVER_UPDATE = 1; 114 115 125 public static final int ALWAYS_UPDATE = 2; 126 127 130 public DefaultCaret() { 131 } 132 133 185 public void setUpdatePolicy(int policy) { 186 updatePolicy = policy; 187 } 188 189 202 public int getUpdatePolicy() { 203 return updatePolicy; 204 } 205 206 212 protected final JTextComponent getComponent() { 213 return component; 214 } 215 216 226 protected final synchronized void repaint() { 227 if (component != null) { 228 component.repaint(x, y, width, height); 229 } 230 } 231 232 242 protected synchronized void damage(Rectangle r) { 243 if (r != null) { 244 int damageWidth = getCaretWidth(r.height); 245 x = r.x - 4 - (damageWidth >> 1); 246 y = r.y; 247 width = 9 + damageWidth; 248 height = r.height; 249 repaint(); 250 } 251 } 252 253 263 protected void adjustVisibility(Rectangle nloc) { 264 if(component == null) { 265 return; 266 } 267 if (SwingUtilities.isEventDispatchThread()) { 268 component.scrollRectToVisible(nloc); 269 } else { 270 SwingUtilities.invokeLater(new SafeScroller(nloc)); 271 } 272 } 273 274 279 protected Highlighter.HighlightPainter getSelectionPainter() { 280 return DefaultHighlighter.DefaultPainter; 281 } 282 283 289 protected void positionCaret(MouseEvent e) { 290 Point pt = new Point(e.getX(), e.getY()); 291 Position.Bias [] biasRet = new Position.Bias [1]; 292 int pos = component.getUI().viewToModel(component, pt, biasRet); 293 if(biasRet[0] == null) 294 biasRet[0] = Position.Bias.Forward; 295 if (pos >= 0) { 296 setDot(pos, biasRet[0]); 297 } 298 } 299 300 308 protected void moveCaret(MouseEvent e) { 309 Point pt = new Point(e.getX(), e.getY()); 310 Position.Bias [] biasRet = new Position.Bias [1]; 311 int pos = component.getUI().viewToModel(component, pt, biasRet); 312 if(biasRet[0] == null) 313 biasRet[0] = Position.Bias.Forward; 314 if (pos >= 0) { 315 moveDot(pos, biasRet[0]); 316 } 317 } 318 319 321 329 public void focusGained(FocusEvent e) { 330 if (component.isEnabled()) { 331 if (component.isEditable()) { 332 setVisible(true); 333 } 334 setSelectionVisible(true); 335 } 336 } 337 338 346 public void focusLost(FocusEvent e) { 347 setVisible(false); 348 setSelectionVisible(ownsSelection || e.isTemporary()); 349 } 350 351 352 355 private void selectWord(MouseEvent e) { 356 if (selectedWordEvent != null 357 && selectedWordEvent.getX() == e.getX() 358 && selectedWordEvent.getY() == e.getY()) { 359 return; 361 } 362 Action a = null; 363 ActionMap map = getComponent().getActionMap(); 364 if (map != null) { 365 a = map.get(DefaultEditorKit.selectWordAction); 366 } 367 if (a == null) { 368 if (selectWord == null) { 369 selectWord = new DefaultEditorKit.SelectWordAction (); 370 } 371 a = selectWord; 372 } 373 a.actionPerformed(new ActionEvent (getComponent(), 374 ActionEvent.ACTION_PERFORMED, null, e.getWhen(), e.getModifiers())); 375 selectedWordEvent = e; 376 } 377 378 380 388 public void mouseClicked(MouseEvent e) { 389 int nclicks = SwingUtilities2.getAdjustedClickCount(getComponent(), e); 390 391 if (! e.isConsumed()) { 392 if (SwingUtilities.isLeftMouseButton(e)) { 393 if(nclicks == 1) { 395 selectedWordEvent = null; 396 } else if(nclicks == 2 397 && SwingUtilities2.canEventAccessSystemClipboard(e)) { 398 selectWord(e); 399 selectedWordEvent = null; 400 } else if(nclicks == 3 401 && SwingUtilities2.canEventAccessSystemClipboard(e)) { 402 Action a = null; 403 ActionMap map = getComponent().getActionMap(); 404 if (map != null) { 405 a = map.get(DefaultEditorKit.selectLineAction); 406 } 407 if (a == null) { 408 if (selectLine == null) { 409 selectLine = new DefaultEditorKit.SelectLineAction (); 410 } 411 a = selectLine; 412 } 413 a.actionPerformed(new ActionEvent (getComponent(), 414 ActionEvent.ACTION_PERFORMED, null, e.getWhen(), e.getModifiers())); 415 } 416 } else if (SwingUtilities.isMiddleMouseButton(e)) { 417 if (nclicks == 1 && component.isEditable() && component.isEnabled() 419 && SwingUtilities2.canEventAccessSystemClipboard(e)) { 420 JTextComponent c = (JTextComponent ) e.getSource(); 422 if (c != null) { 423 try { 424 Toolkit tk = c.getToolkit(); 425 Clipboard buffer = tk.getSystemSelection(); 426 if (buffer != null) { 427 adjustCaret(e); 429 TransferHandler th = c.getTransferHandler(); 430 if (th != null) { 431 Transferable trans = null; 432 433 try { 434 trans = buffer.getContents(null); 435 } catch (IllegalStateException ise) { 436 UIManager.getLookAndFeel().provideErrorFeedback(c); 438 } 439 440 if (trans != null) { 441 th.importData(c, trans); 442 } 443 } 444 adjustFocus(true); 445 } 446 } catch (HeadlessException he) { 447 } 449 } 450 } 451 } 452 } 453 } 454 455 467 public void mousePressed(MouseEvent e) { 468 int nclicks = SwingUtilities2.getAdjustedClickCount(getComponent(), e); 469 470 if (SwingUtilities.isLeftMouseButton(e)) { 471 if (e.isConsumed()) { 472 shouldHandleRelease = true; 473 } else { 474 shouldHandleRelease = false; 475 adjustCaretAndFocus(e); 476 if (nclicks == 2 477 && SwingUtilities2.canEventAccessSystemClipboard(e)) { 478 selectWord(e); 479 } 480 } 481 } 482 } 483 484 void adjustCaretAndFocus(MouseEvent e) { 485 adjustCaret(e); 486 adjustFocus(false); 487 } 488 489 492 private void adjustCaret(MouseEvent e) { 493 if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0 && 494 getDot() != -1) { 495 moveCaret(e); 496 } else { 497 positionCaret(e); 498 } 499 } 500 501 506 private void adjustFocus(boolean inWindow) { 507 if ((component != null) && component.isEnabled() && 508 component.isRequestFocusEnabled()) { 509 if (inWindow) { 510 component.requestFocusInWindow(); 511 } 512 else { 513 component.requestFocus(); 514 } 515 } 516 } 517 518 524 public void mouseReleased(MouseEvent e) { 525 if (!e.isConsumed() 526 && shouldHandleRelease 527 && SwingUtilities.isLeftMouseButton(e)) { 528 529 adjustCaretAndFocus(e); 530 } 531 } 532 533 539 public void mouseEntered(MouseEvent e) { 540 } 541 542 548 public void mouseExited(MouseEvent e) { 549 } 550 551 553 563 public void mouseDragged(MouseEvent e) { 564 if ((! e.isConsumed()) && SwingUtilities.isLeftMouseButton(e)) { 565 moveCaret(e); 566 } 567 } 568 569 575 public void mouseMoved(MouseEvent e) { 576 } 577 578 580 596 public void paint(Graphics g) { 597 if(isVisible()) { 598 try { 599 TextUI mapper = component.getUI(); 600 Rectangle r = mapper.modelToView(component, dot, dotBias); 601 602 if ((r == null) || ((r.width == 0) && (r.height == 0))) { 603 return; 604 } 605 if (width > 0 && height > 0 && 606 !this._contains(r.x, r.y, r.width, r.height)) { 607 Rectangle clip = g.getClipBounds(); 610 611 if (clip != null && !clip.contains(this)) { 612 repaint(); 615 } 616 damage(r); 620 } 621 g.setColor(component.getCaretColor()); 622 int paintWidth = getCaretWidth(r.height); 623 r.x -= paintWidth >> 1; 624 g.fillRect(r.x, r.y, paintWidth , r.height - 1); 625 626 Document doc = component.getDocument(); 632 if (doc instanceof AbstractDocument ) { 633 Element bidi = ((AbstractDocument )doc).getBidiRootElement(); 634 if ((bidi != null) && (bidi.getElementCount() > 1)) { 635 flagXPoints[0] = r.x + ((dotLTR) ? paintWidth : 0); 637 flagYPoints[0] = r.y; 638 flagXPoints[1] = flagXPoints[0]; 639 flagYPoints[1] = flagYPoints[0] + 4; 640 flagXPoints[2] = flagXPoints[0] + ((dotLTR) ? 4 : -4); 641 flagYPoints[2] = flagYPoints[0]; 642 g.fillPolygon(flagXPoints, flagYPoints, 3); 643 } 644 } 645 } catch (BadLocationException e) { 646 } 649 } 650 } 651 652 663 public void install(JTextComponent c) { 664 component = c; 665 Document doc = c.getDocument(); 666 dot = mark = 0; 667 dotLTR = markLTR = true; 668 dotBias = markBias = Position.Bias.Forward; 669 if (doc != null) { 670 doc.addDocumentListener(handler); 671 } 672 c.addPropertyChangeListener(handler); 673 c.addFocusListener(this); 674 c.addMouseListener(this); 675 c.addMouseMotionListener(this); 676 677 if (component.hasFocus()) { 680 focusGained(null); 681 } 682 683 Number ratio = (Number ) c.getClientProperty("caretAspectRatio"); 684 if (ratio != null) { 685 aspectRatio = ratio.floatValue(); 686 } else { 687 aspectRatio = -1; 688 } 689 690 Integer width = (Integer ) c.getClientProperty("caretWidth"); 691 if (width != null) { 692 caretWidth = width.intValue(); 693 } else { 694 caretWidth = -1; 695 } 696 } 697 698 706 public void deinstall(JTextComponent c) { 707 c.removeMouseListener(this); 708 c.removeMouseMotionListener(this); 709 c.removeFocusListener(this); 710 c.removePropertyChangeListener(handler); 711 Document doc = c.getDocument(); 712 if (doc != null) { 713 doc.removeDocumentListener(handler); 714 } 715 synchronized(this) { 716 component = null; 717 } 718 if (flasher != null) { 719 flasher.stop(); 720 } 721 722 723 } 724 725 732 public void addChangeListener(ChangeListener l) { 733 listenerList.add(ChangeListener.class, l); 734 } 735 736 742 public void removeChangeListener(ChangeListener l) { 743 listenerList.remove(ChangeListener.class, l); 744 } 745 746 759 public ChangeListener[] getChangeListeners() { 760 return (ChangeListener[])listenerList.getListeners( 761 ChangeListener.class); 762 } 763 764 772 protected void fireStateChanged() { 773 Object [] listeners = listenerList.getListenerList(); 775 for (int i = listeners.length-2; i>=0; i-=2) { 778 if (listeners[i]==ChangeListener.class) { 779 if (changeEvent == null) 781 changeEvent = new ChangeEvent(this); 782 ((ChangeListener)listeners[i+1]).stateChanged(changeEvent); 783 } 784 } 785 } 786 787 823 public <T extends EventListener > T[] getListeners(Class <T> listenerType) { 824 return listenerList.getListeners(listenerType); 825 } 826 827 832 public void setSelectionVisible(boolean vis) { 833 if (vis != selectionVisible) { 834 selectionVisible = vis; 835 if (selectionVisible) { 836 Highlighter h = component.getHighlighter(); 838 if ((dot != mark) && (h != null) && (selectionTag == null)) { 839 int p0 = Math.min(dot, mark); 840 int p1 = Math.max(dot, mark); 841 Highlighter.HighlightPainter p = getSelectionPainter(); 842 try { 843 selectionTag = h.addHighlight(p0, p1, p); 844 } catch (BadLocationException bl) { 845 selectionTag = null; 846 } 847 } 848 } else { 849 if (selectionTag != null) { 851 Highlighter h = component.getHighlighter(); 852 h.removeHighlight(selectionTag); 853 selectionTag = null; 854 } 855 } 856 } 857 } 858 859 864 public boolean isSelectionVisible() { 865 return selectionVisible; 866 } 867 868 882 public boolean isActive() { 883 return active; 884 } 885 886 903 public boolean isVisible() { 904 return visible; 905 } 906 907 941 public void setVisible(boolean e) { 942 if (component != null) { 946 active = e; 947 TextUI mapper = component.getUI(); 948 if (visible != e) { 949 visible = e; 950 try { 952 Rectangle loc = mapper.modelToView(component, dot,dotBias); 953 damage(loc); 954 } catch (BadLocationException badloc) { 955 } 957 } 958 } 959 if (flasher != null) { 960 if (visible) { 961 flasher.start(); 962 } else { 963 flasher.stop(); 964 } 965 } 966 } 967 968 974 public void setBlinkRate(int rate) { 975 if (rate != 0) { 976 if (flasher == null) { 977 flasher = new Timer(rate, handler); 978 &
|