/[classpath]/classpath/javax/swing/text/DefaultCaret.java
ViewVC logotype

Diff of /classpath/javax/swing/text/DefaultCaret.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.7.2.9 by gnu_andrew, Wed Nov 2 00:44:02 2005 UTC revision 1.7.2.10 by gnu_andrew, Sun Nov 27 21:00:42 2005 UTC
# Line 40  package javax.swing.text; Line 40  package javax.swing.text;
40  import java.awt.Graphics;  import java.awt.Graphics;
41  import java.awt.Point;  import java.awt.Point;
42  import java.awt.Rectangle;  import java.awt.Rectangle;
43    import java.awt.event.ActionEvent;
44    import java.awt.event.ActionListener;
45  import java.awt.event.FocusEvent;  import java.awt.event.FocusEvent;
46  import java.awt.event.FocusListener;  import java.awt.event.FocusListener;
47  import java.awt.event.MouseEvent;  import java.awt.event.MouseEvent;
# Line 49  import java.beans.PropertyChangeEvent; Line 51  import java.beans.PropertyChangeEvent;
51  import java.beans.PropertyChangeListener;  import java.beans.PropertyChangeListener;
52  import java.util.EventListener;  import java.util.EventListener;
53    
54    import javax.swing.JComponent;
55  import javax.swing.SwingUtilities;  import javax.swing.SwingUtilities;
56    import javax.swing.Timer;
57  import javax.swing.event.ChangeEvent;  import javax.swing.event.ChangeEvent;
58  import javax.swing.event.ChangeListener;  import javax.swing.event.ChangeListener;
59  import javax.swing.event.DocumentEvent;  import javax.swing.event.DocumentEvent;
# Line 65  import javax.swing.event.EventListenerLi Line 69  import javax.swing.event.EventListenerLi
69  public class DefaultCaret extends Rectangle  public class DefaultCaret extends Rectangle
70    implements Caret, FocusListener, MouseListener, MouseMotionListener    implements Caret, FocusListener, MouseListener, MouseMotionListener
71  {  {
72    
73      /**
74       * Controls the blinking of the caret.
75       *
76       * @author Roman Kennke (kennke@aicas.com)
77       * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
78       */
79      private class BlinkTimerListener implements ActionListener
80      {
81        /**
82         * Forces the next event to be ignored. The next event should be ignored
83         * if we force the caret to appear. We do not know how long will it take
84         * to fire the comming event; this may be near immediately. Better to leave
85         * the caret visible one iteration longer.
86         */
87        boolean ignoreNextEvent;
88        
89        /**
90         * Receives notification when the blink timer fires and updates the visible
91         * state of the caret.
92         *
93         * @param event the action event
94         */
95        public void actionPerformed(ActionEvent event)
96        {
97          if (ignoreNextEvent)
98            ignoreNextEvent = false;
99          else
100            {
101              visible = !visible;
102              repaint();
103            }
104        }
105      }
106    
107    /**    /**
108     * Listens for changes in the text component's document and updates the     * Listens for changes in the text component's document and updates the
109     * caret accordingly.     * caret accordingly.
# Line 238  public class DefaultCaret extends Rectan Line 277  public class DefaultCaret extends Rectan
277    private Point magicCaretPosition = null;    private Point magicCaretPosition = null;
278    
279    /**    /**
280     * Indicates if this <code>Caret</code> is currently visible or not.     * Indicates if this <code>Caret</code> is currently visible or not. This is
281       * package private to avoid an accessor method.
282     */     */
283    private boolean visible = true;    boolean visible = false;
284    
285    /**    /**
286     * The current highlight entry.     * The current highlight entry.
287     */     */
288    private Object highlightEntry;    private Object highlightEntry;
289    
290      private Timer blinkTimer;
291      
292      private BlinkTimerListener blinkListener;
293    
294      /**
295       * Creates a new <code>DefaultCaret</code> instance.
296       */
297      public DefaultCaret()
298      {
299        // Nothing to do here.
300      }
301    
302    /**    /**
303     * Sets the Caret update policy.     * Sets the Caret update policy.
304     *         *    
# Line 292  public class DefaultCaret extends Rectan Line 344  public class DefaultCaret extends Rectan
344     */     */
345    public void mouseDragged(MouseEvent event)    public void mouseDragged(MouseEvent event)
346    {    {
347      // FIXME: Implement this properly.      moveCaret(event);
348    }    }
349    
350    /**    /**
# Line 322  public class DefaultCaret extends Rectan Line 374  public class DefaultCaret extends Rectan
374     */     */
375    public void mouseClicked(MouseEvent event)    public void mouseClicked(MouseEvent event)
376    {    {
377      // FIXME: Implement this properly.      // TODO: Implement double- and triple-click behaviour here.
378    }    }
379    
380    /**    /**
# Line 344  public class DefaultCaret extends Rectan Line 396  public class DefaultCaret extends Rectan
396     */     */
397    public void mouseExited(MouseEvent event)    public void mouseExited(MouseEvent event)
398    {    {
399      // TODO: What to do here, if anything?      // Nothing to do here.
400    }    }
401    
402    /**    /**
# Line 357  public class DefaultCaret extends Rectan Line 409  public class DefaultCaret extends Rectan
409     */     */
410    public void mousePressed(MouseEvent event)    public void mousePressed(MouseEvent event)
411    {    {
412      // FIXME: Implement this properly.      positionCaret(event);
     if (!(event.getButton() == MouseEvent.BUTTON1))  
       return;  
     setDot(textComponent.viewToModel(event.getPoint()));  
413    }    }
414    
415    /**    /**
# Line 381  public class DefaultCaret extends Rectan Line 430  public class DefaultCaret extends Rectan
430     */     */
431    public void focusGained(FocusEvent event)    public void focusGained(FocusEvent event)
432    {    {
433      // TODO: Implement this properly.      setVisible(true);    
434        updateTimerStatus();
435    }    }
436    
437    /**    /**
438     * Sets the caret to <code>invisible</code>.     * Sets the caret to <code>invisible</code>.
439     *     *
440     * @param event the <code>FocusEvent</code>     * @param event the <code>FocusEvent</code>
441     */     */
442    public void focusLost(FocusEvent event)    public void focusLost(FocusEvent event)
443    {    {
444      // TODO: Implement this properly.      if (event.isTemporary() == false)
445          {
446            setVisible(false);
447            // Stop the blinker, if running.
448            if (blinkTimer != null && blinkTimer.isRunning())
449              blinkTimer.stop();
450          }
451      }
452      
453      /**
454       * Install (if not present) and start the timer, if the caret must blink. The
455       * caret does not blink if it is invisible, or the component is disabled or
456       * not editable.
457       */
458      private void updateTimerStatus()
459      {
460        if (textComponent.isEnabled() && textComponent.isEditable())
461          {
462            if (blinkTimer == null)
463              initBlinkTimer();
464            if (!blinkTimer.isRunning())
465              blinkTimer.start();
466          }
467        else
468          {
469            if (blinkTimer != null)
470              blinkTimer.stop();
471          }
472    }    }
473    
474    /**    /**
# Line 402  public class DefaultCaret extends Rectan Line 479  public class DefaultCaret extends Rectan
479     */     */
480    protected void moveCaret(MouseEvent event)    protected void moveCaret(MouseEvent event)
481    {    {
482      // FIXME: Implement this properly.      int newDot = getComponent().viewToModel(event.getPoint());
483        moveDot(newDot);
484    }    }
485    
486    /**    /**
# Line 413  public class DefaultCaret extends Rectan Line 491  public class DefaultCaret extends Rectan
491     */     */
492    protected void positionCaret(MouseEvent event)    protected void positionCaret(MouseEvent event)
493    {    {
494      // FIXME: Implement this properly.      int newDot = getComponent().viewToModel(event.getPoint());
495        setDot(newDot);
496    }    }
497    
498    /**    /**
# Line 433  public class DefaultCaret extends Rectan Line 512  public class DefaultCaret extends Rectan
512      textComponent.removePropertyChangeListener(propertyChangeListener);      textComponent.removePropertyChangeListener(propertyChangeListener);
513      propertyChangeListener = null;      propertyChangeListener = null;
514      textComponent = null;      textComponent = null;
515    
516        // Deinstall blink timer if present.
517        if (blinkTimer != null)
518          blinkTimer.stop();
519        blinkTimer = null;
520    }    }
521    
522    /**    /**
# Line 452  public class DefaultCaret extends Rectan Line 536  public class DefaultCaret extends Rectan
536      textComponent.addPropertyChangeListener(propertyChangeListener);      textComponent.addPropertyChangeListener(propertyChangeListener);
537      documentListener = new DocumentHandler();      documentListener = new DocumentHandler();
538      textComponent.getDocument().addDocumentListener(documentListener);      textComponent.getDocument().addDocumentListener(documentListener);
539    
540      repaint();      repaint();
541    }    }
542    
# Line 559  public class DefaultCaret extends Rectan Line 644  public class DefaultCaret extends Rectan
644     */     */
645    protected final void repaint()    protected final void repaint()
646    {    {
647      textComponent.repaint(this);      getComponent().repaint(x, y, width, height);
648    }    }
649    
650    /**    /**
# Line 570  public class DefaultCaret extends Rectan Line 655  public class DefaultCaret extends Rectan
655     */     */
656    public void paint(Graphics g)    public void paint(Graphics g)
657    {    {
658      if (textComponent == null)      JTextComponent comp = getComponent();
659        if (comp == null)
660        return;        return;
661    
662      int dot = getDot();      int dot = getDot();
# Line 578  public class DefaultCaret extends Rectan Line 664  public class DefaultCaret extends Rectan
664    
665      try      try
666        {        {
667          rect = textComponent.modelToView(dot);          rect = textComponent.modelToView(dot);
668        }        }
669      catch (BadLocationException e)      catch (BadLocationException e)
670        {        {
671          // This should never happen as dot should be always valid.          assert false : "Unexpected bad caret location: " + dot;
672          return;          return;
673        }        }
674    
675      if (rect == null)      if (rect == null)
676        return;        return;
677        
678      // First we need to delete the old caret.      // Check if paint has possibly been called directly, without a previous
679      // FIXME: Implement deleting of old caret.      // call to damage(). In this case we need to do some cleanup first.
680            if ((x != rect.x) || (y != rect.y))
681          {
682            repaint(); // Erase previous location of caret.
683            x = rect.x;
684            y = rect.y;
685            width = 1;
686            height = rect.height;
687          }
688    
689      // Now draw the caret on the new position if visible.      // Now draw the caret on the new position if visible.
690      if (visible)      if (visible)
691        {        {
692          g.setColor(textComponent.getCaretColor());          g.setColor(textComponent.getCaretColor());
693          g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height);          g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height);
694        }        }
695    }    }
696    
# Line 687  public class DefaultCaret extends Rectan Line 781  public class DefaultCaret extends Rectan
781     */     */
782    public void setBlinkRate(int rate)    public void setBlinkRate(int rate)
783    {    {
784        if (blinkTimer != null)
785          blinkTimer.setDelay(rate);
786      blinkRate = rate;      blinkRate = rate;
787    }    }
788    
# Line 712  public class DefaultCaret extends Rectan Line 808  public class DefaultCaret extends Rectan
808     */     */
809    public void moveDot(int dot)    public void moveDot(int dot)
810    {    {
811      this.dot = dot;      if (dot >= 0)
812      handleHighlight();        {
813      repaint();          this.dot = dot;
814            handleHighlight();
815            adjustVisibility(this);
816            appear();
817          }
818    }    }
819    
820    /**    /**
821     * Sets the current position of this <code>Caret</code> within the     * Sets the current position of this <code>Caret</code> within the
822     * <code>Document</code>. This also sets the <code>mark</code> to the     * <code>Document</code>. This also sets the <code>mark</code> to the new
823     * new location.     * location.
824     *     *
825     * @param dot the new position to be set     * @param dot
826     *     *          the new position to be set
827     * @see #moveDot(int)     * @see #moveDot(int)
828     */     */
829    public void setDot(int dot)    public void setDot(int dot)
830    {    {
831      this.dot = dot;      if (dot >= 0)
832      this.mark = dot;        {
833      handleHighlight();          this.mark = dot;
834      repaint();          this.dot = dot;
835            handleHighlight();
836            adjustVisibility(this);
837            appear();
838          }
839    }    }
840      
841      /**
842       * Show the caret (may be hidden due blinking) and adjust the timer not to
843       * hide it (possibly immediately).
844       *
845       * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
846       */
847      void appear()
848      {
849        // All machinery is only required if the carret is blinking.
850        if (blinkListener != null)
851          {
852            blinkListener.ignoreNextEvent = true;
853    
854            // If the caret is visible, erase the current position by repainting
855            // over.
856            if (visible)
857              repaint();
858    
859            // Draw the caret in the new position.
860            visible = true;
861    
862            Rectangle area = null;
863            try
864              {
865                area = getComponent().modelToView(getDot());
866              }
867            catch (BadLocationException ex)
868              {
869                assert false : "Unexpected bad caret location: " + getDot();
870              }
871            if (area != null)
872              damage(area);
873          }
874        repaint();
875      }  
876    
877    /**    /**
878     * Returns <code>true</code> if this <code>Caret</code> is currently visible,     * Returns <code>true</code> if this <code>Caret</code> is currently visible,
# Line 757  public class DefaultCaret extends Rectan Line 897  public class DefaultCaret extends Rectan
897      if (v != visible)      if (v != visible)
898        {        {
899          visible = v;          visible = v;
900          repaint();          updateTimerStatus();
901            Rectangle area = null;
902            try
903              {            
904                area = getComponent().modelToView(getDot());
905              }
906            catch (BadLocationException ex)
907              {
908                assert false: "Unexpected bad caret location: " + getDot();
909              }
910            if (area != null)
911              damage(area);
912        }        }
913    }    }
914    
# Line 772  public class DefaultCaret extends Rectan Line 923  public class DefaultCaret extends Rectan
923    {    {
924      return DefaultHighlighter.DefaultPainter;      return DefaultHighlighter.DefaultPainter;
925    }    }
926    
927      /**
928       * Updates the carets rectangle properties to the specified rectangle and
929       * repaints the caret.
930       *
931       * @param r the rectangle to set as the caret rectangle
932       */
933      protected void damage(Rectangle r)
934      {
935        if (r == null)
936          return;
937        x = r.x;
938        y = r.y;
939        width = 1;
940        // height is normally set in paint and we leave it untouched. However, we
941        // must set a valid value here, since otherwise the painting mechanism
942        // sets a zero clip and never calls paint.
943        if (height <= 0)
944          height = getComponent().getHeight();
945        repaint();
946      }
947    
948      /**
949       * Adjusts the text component so that the caret is visible. This default
950       * implementation simply calls
951       * {@link JComponent#scrollRectToVisible(Rectangle)} on the text component.
952       * Subclasses may wish to change this.
953       */
954      protected void adjustVisibility(Rectangle rect)
955      {
956        getComponent().scrollRectToVisible(rect);
957      }
958    
959      /**
960       * Initializes the blink timer.
961       */
962      private void initBlinkTimer()
963      {
964        // Setup the blink timer.
965        blinkListener = new BlinkTimerListener();
966        blinkTimer = new Timer(getBlinkRate(), blinkListener);
967        blinkTimer.setRepeats(true);
968      }
969  }  }

Legend:
Removed from v.1.7.2.9  
changed lines
  Added in v.1.7.2.10

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26