Index: javax/swing/text/DefaultCaret.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultCaret.java,v
retrieving revision 1.19
diff -u -r1.19 DefaultCaret.java
--- javax/swing/text/DefaultCaret.java 19 Oct 2005 14:57:30 -0000 1.19
+++ javax/swing/text/DefaultCaret.java 3 Nov 2005 11:18:11 -0000
@@ -40,6 +40,8 @@
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
@@ -50,6 +52,7 @@
import java.util.EventListener;
import javax.swing.SwingUtilities;
+import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
@@ -65,6 +68,27 @@
public class DefaultCaret extends Rectangle
implements Caret, FocusListener, MouseListener, MouseMotionListener
{
+
+ /**
+ * Controls the blinking of the caret.
+ *
+ * @author Roman Kennke (address@hidden)
+ */
+ private class BlinkTimerListener implements ActionListener
+ {
+ /**
+ * Receives notification when the blink timer fires and updates the visible
+ * state of the caret.
+ *
+ * @param event the action event
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ visible = !visible;
+ repaint();
+ }
+ }
+
/**
* Listens for changes in the text component's document and updates the
* caret accordingly.
@@ -238,15 +262,26 @@
private Point magicCaretPosition = null;
/**
- * Indicates if this Caret
is currently visible or not.
+ * Indicates if this Caret
is currently visible or not. This is
+ * package private to avoid an accessor method.
*/
- private boolean visible = true;
+ boolean visible = false;
/**
* The current highlight entry.
*/
private Object highlightEntry;
+ private Timer blinkTimer;
+
+ /**
+ * Creates a new DefaultCaret
instance.
+ */
+ public DefaultCaret()
+ {
+ // Nothing to do here.
+ }
+
/**
* Sets the Caret update policy.
*
@@ -381,7 +416,7 @@
*/
public void focusGained(FocusEvent event)
{
- // TODO: Implement this properly.
+ setVisible(true);
}
/**
@@ -391,7 +426,8 @@
*/
public void focusLost(FocusEvent event)
{
- // TODO: Implement this properly.
+ if (event.isTemporary() == false)
+ setVisible(false);
}
/**
@@ -433,6 +469,11 @@
textComponent.removePropertyChangeListener(propertyChangeListener);
propertyChangeListener = null;
textComponent = null;
+
+ // Deinstall blink timer if present.
+ if (blinkTimer != null)
+ blinkTimer.stop();
+ blinkTimer = null;
}
/**
@@ -452,6 +493,7 @@
textComponent.addPropertyChangeListener(propertyChangeListener);
documentListener = new DocumentHandler();
textComponent.getDocument().addDocumentListener(documentListener);
+
repaint();
}
@@ -559,7 +601,7 @@
*/
protected final void repaint()
{
- textComponent.repaint(this);
+ getComponent().repaint(x, y, width, height);
}
/**
@@ -570,7 +612,8 @@
*/
public void paint(Graphics g)
{
- if (textComponent == null)
+ JTextComponent comp = getComponent();
+ if (comp == null)
return;
int dot = getDot();
@@ -578,25 +621,33 @@
try
{
- rect = textComponent.modelToView(dot);
+ rect = textComponent.modelToView(dot);
}
catch (BadLocationException e)
{
- // This should never happen as dot should be always valid.
- return;
+ assert false : "Unexpected bad caret location: " + dot;
+ return;
}
if (rect == null)
return;
-
- // First we need to delete the old caret.
- // FIXME: Implement deleting of old caret.
-
+
+ // Check if paint has possibly been called directly, without a previous
+ // call to damage(). In this case we need to do some cleanup first.
+ if ((x != rect.x) || (y != rect.y))
+ {
+ repaint(); // Erase previous location of caret.
+ x = rect.x;
+ y = rect.y;
+ width = 1;
+ height = rect.height;
+ }
+
// Now draw the caret on the new position if visible.
if (visible)
{
- g.setColor(textComponent.getCaretColor());
- g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height);
+ g.setColor(textComponent.getCaretColor());
+ g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height);
}
}
@@ -687,6 +738,8 @@
*/
public void setBlinkRate(int rate)
{
+ if (blinkTimer != null)
+ blinkTimer.setDelay(rate);
blinkRate = rate;
}
@@ -757,7 +810,29 @@
if (v != visible)
{
visible = v;
- repaint();
+ if (visible)
+ if (textComponent.isEnabled() && textComponent.isEditable())
+ {
+ if (blinkTimer == null)
+ initBlinkTimer();
+ blinkTimer.start();
+ }
+ else
+ {
+ if (blinkTimer != null)
+ blinkTimer.stop();
+ }
+ Rectangle area = null;
+ try
+ {
+ area = getComponent().modelToView(getDot());
+ }
+ catch (BadLocationException ex)
+ {
+ assert false: "Unexpected bad caret location: " + getDot();
+ }
+ if (area != null)
+ damage(area);
}
}
@@ -771,5 +846,36 @@
protected Highlighter.HighlightPainter getSelectionPainter()
{
return DefaultHighlighter.DefaultPainter;
+ }
+
+ /**
+ * Updates the carets rectangle properties to the specified rectangle and
+ * repaints the caret.
+ *
+ * @param r the rectangle to set as the caret rectangle
+ */
+ protected void damage(Rectangle r)
+ {
+ if (r == null)
+ return;
+ x = r.x;
+ y = r.y;
+ width = 1;
+ // height is normally set in paint and we leave it untouched. However, we
+ // must set a valid value here, since otherwise the painting mechanism
+ // sets a zero clip and never calls paint.
+ if (height <= 0)
+ height = getComponent().getHeight();
+ repaint();
+ }
+
+ /**
+ * Initializes the blink timer.
+ */
+ private void initBlinkTimer()
+ {
+ // Setup the blink timer.
+ blinkTimer = new Timer(getBlinkRate(), new BlinkTimerListener());
+ blinkTimer.setRepeats(true);
}
}
Index: javax/swing/text/JTextComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/JTextComponent.java,v
retrieving revision 1.43
diff -u -r1.43 JTextComponent.java
--- javax/swing/text/JTextComponent.java 19 Oct 2005 14:57:31 -0000 1.43
+++ javax/swing/text/JTextComponent.java 3 Nov 2005 11:18:11 -0000
@@ -50,7 +50,6 @@
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.awt.event.InputMethodListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
@@ -73,7 +72,6 @@
import javax.swing.KeyStroke;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;
-import javax.swing.Timer;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.event.CaretEvent;
@@ -304,48 +302,6 @@
}
/**
- * The timer that lets the caret blink.
- */
- private class CaretBlinkTimer extends Timer implements ActionListener
- {
- /**
- * Creates a new CaretBlinkTimer object with a default delay of 1 second.
- */
- public CaretBlinkTimer()
- {
- super(1000, null);
- addActionListener(this);
- }
-
- /**
- * Lets the caret blink.
- */
- public void actionPerformed(ActionEvent ev)
- {
- Caret c = caret;
- if (c != null)
- c.setVisible(!c.isVisible());
- }
-
- /**
- * Updates the blink delay according to the current caret.
- */
- public void update()
- {
- stop();
- Caret c = caret;
- if (c != null)
- {
- setDelay(c.getBlinkRate());
- if (editable)
- start();
- else
- c.setVisible(false);
- }
- }
- }
-
- /**
* According to this
* report, a pair of private classes wraps a address@hidden
@@ -701,8 +657,6 @@
private char focusAccelerator = '\0';
private NavigationFilter navigationFilter;
- private CaretBlinkTimer caretBlinkTimer;
-
/**
* Get a Keymap from the global keymap table, by name.
*
@@ -960,8 +914,6 @@
creatingKeymap = true;
}
- caretBlinkTimer = new CaretBlinkTimer();
-
setFocusable(true);
setEditable(true);
enableEvents(AWTEvent.KEY_EVENT_MASK);
@@ -1200,14 +1152,6 @@
if (editable == newValue)
return;
- if (newValue == true)
- caretBlinkTimer.start();
- else
- {
- caretBlinkTimer.stop();
- caret.setVisible(false);
- }
-
boolean oldValue = editable;
editable = newValue;
firePropertyChange("editable", oldValue, newValue);
@@ -1235,8 +1179,6 @@
Caret oldCaret = caret;
caret = newCaret;
-
- caretBlinkTimer.update();
if (caret != null)
caret.install(this);
Index: javax/swing/text/Utilities.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/Utilities.java,v
retrieving revision 1.16
diff -u -r1.16 Utilities.java
--- javax/swing/text/Utilities.java 31 Oct 2005 20:03:53 -0000 1.16
+++ javax/swing/text/Utilities.java 3 Nov 2005 11:18:11 -0000
@@ -522,4 +522,20 @@
// just break it on the character boundary
return mark;
}
+
+ /**
+ * Returns the paragraph element in the text component c
at
+ * the specified location offset
.
+ *
+ * @param c the text component
+ * @param offset the offset of the paragraph element to return
+ *
+ * @return the paragraph element at offset
+ */
+ public static Element getParagraphElement(JTextComponent c, int offset)
+ {
+ Element root = c.getDocument().getDefaultRootElement();
+ int parIndex = root.getElementIndex(offset);
+ return root.getElement(parIndex);
+ }
}