summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
diff options
context:
space:
mode:
authormark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-10 21:46:48 +0000
committermark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-10 21:46:48 +0000
commitce57ab760f69de6db452def7ffbf5b114a2d8694 (patch)
treeea38c56431c5d4528fb54254c3f8e50f517bede3 /libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
parent50996fe55769882de3f410896032c887f0ff0d04 (diff)
downloadppe42-gcc-ce57ab760f69de6db452def7ffbf5b114a2d8694.tar.gz
ppe42-gcc-ce57ab760f69de6db452def7ffbf5b114a2d8694.zip
Imported GNU Classpath 0.90
* scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore. * gnu/classpath/jdwp/VMFrame.java (SIZE): New constant. * java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5. * java/lang/Math.java: New override file. * java/lang/Character.java: Merged from Classpath. (start, end): Now 'int's. (canonicalName): New field. (CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants. (UnicodeBlock): Added argument. (of): New overload. (forName): New method. Updated unicode blocks. (sets): Updated. * sources.am: Regenerated. * Makefile.in: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111942 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java')
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java250
1 files changed, 208 insertions, 42 deletions
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
index fc388948419..beb1a6dfeac 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
@@ -1,5 +1,5 @@
/* BasicTextUI.java --
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -46,15 +46,11 @@ import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
-import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
@@ -70,6 +66,7 @@ import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TextUI;
import javax.swing.plaf.UIResource;
+import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.DefaultCaret;
@@ -82,6 +79,7 @@ import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;
import javax.swing.text.Position;
+import javax.swing.text.Utilities;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
@@ -161,11 +159,11 @@ public abstract class BasicTextUI extends TextUI
* Indicates that the preferences of one of the child view has changed.
* This calls revalidate on the text component.
*
- * @param view the child view which's preference has changed
+ * @param v the child view which's preference has changed
* @param width <code>true</code> if the width preference has changed
* @param height <code>true</code> if the height preference has changed
*/
- public void preferenceChanged(View view, boolean width, boolean height)
+ public void preferenceChanged(View v, boolean width, boolean height)
{
textComponent.revalidate();
}
@@ -181,7 +179,7 @@ public abstract class BasicTextUI extends TextUI
view.setParent(null);
if (v != null)
- v.setParent(null);
+ v.setParent(this);
view = v;
}
@@ -207,10 +205,10 @@ public abstract class BasicTextUI extends TextUI
*/
public int getViewCount()
{
+ int count = 0;
if (view != null)
- return 1;
- else
- return 0;
+ count = 1;
+ return count;
}
/**
@@ -249,7 +247,11 @@ public abstract class BasicTextUI extends TextUI
public void paint(Graphics g, Shape s)
{
if (view != null)
- view.paint(g, s);
+ {
+ Rectangle b = s.getBounds();
+ view.setSize(b.width, b.height);
+ view.paint(g, s);
+ }
}
@@ -277,7 +279,7 @@ public abstract class BasicTextUI extends TextUI
public Shape modelToView(int position, Shape a, Position.Bias bias)
throws BadLocationException
{
- return ((View) view).modelToView(position, a, bias);
+ return view.modelToView(position, a, bias);
}
/**
@@ -363,12 +365,44 @@ public abstract class BasicTextUI extends TextUI
{
return view.getNextVisualPositionFrom(pos, b, a, d, biasRet);
}
+
+ /**
+ * Returns the startOffset of this view, which is always the beginning
+ * of the document.
+ *
+ * @return the startOffset of this view
+ */
+ public int getStartOffset()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the endOffset of this view, which is always the end
+ * of the document.
+ *
+ * @return the endOffset of this view
+ */
+ public int getEndOffset()
+ {
+ return getDocument().getLength();
+ }
+
+ /**
+ * Returns the document associated with this view.
+ *
+ * @return the document associated with this view
+ */
+ public Document getDocument()
+ {
+ return textComponent.getDocument();
+ }
}
/**
* Receives notifications when properties of the text component change.
*/
- class PropertyChangeHandler implements PropertyChangeListener
+ private class PropertyChangeHandler implements PropertyChangeListener
{
/**
* Notifies when a property of the text component changes.
@@ -448,7 +482,7 @@ public abstract class BasicTextUI extends TextUI
/**
* Receives notification when the model changes.
*/
- PropertyChangeHandler updateHandler = new PropertyChangeHandler();
+ private PropertyChangeHandler updateHandler = new PropertyChangeHandler();
/** The DocumentEvent handler. */
DocumentHandler documentHandler = new DocumentHandler();
@@ -515,20 +549,19 @@ public abstract class BasicTextUI extends TextUI
c.setOpaque(true);
textComponent = (JTextComponent) c;
-
Document doc = textComponent.getDocument();
if (doc == null)
{
- doc = getEditorKit(textComponent).createDefaultDocument();
- textComponent.setDocument(doc);
+ doc = getEditorKit(textComponent).createDefaultDocument();
+ textComponent.setDocument(doc);
}
-
- textComponent.addPropertyChangeListener(updateHandler);
- modelChanged();
-
installDefaults();
installListeners();
installKeyboardActions();
+
+ // We need to trigger this so that the view hierarchy gets initialized.
+ modelChanged();
+
}
/**
@@ -584,6 +617,7 @@ public abstract class BasicTextUI extends TextUI
protected void installListeners()
{
textComponent.addFocusListener(focuslistener);
+ textComponent.addPropertyChangeListener(updateHandler);
installDocumentListeners();
}
@@ -621,6 +655,11 @@ public abstract class BasicTextUI extends TextUI
*/
protected Keymap createKeymap()
{
+ // FIXME: It seems to me that this method implementation is wrong. It seems
+ // to fetch the focusInputMap and transform it to the KeyBinding/Keymap
+ // implemenation. I would think that it should be done the other way,
+ // fetching the keybindings (from prefix + ".bindings") and transform
+ // it to the newer InputMap/ActionMap implementation.
JTextComponent.KeyBinding[] bindings = null;
String prefix = getPropertyPrefix();
InputMapUIResource m = (InputMapUIResource) UIManager.get(prefix + ".focusInputMap");
@@ -637,10 +676,7 @@ public abstract class BasicTextUI extends TextUI
}
}
if (bindings == null)
- {
- bindings = new JTextComponent.KeyBinding[0];
- UIManager.put(prefix + ".focusInputMap", bindings);
- }
+ bindings = new JTextComponent.KeyBinding[0];
Keymap km = JTextComponent.addKeymap(getKeymapName(),
JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP));
@@ -726,8 +762,6 @@ public abstract class BasicTextUI extends TextUI
super.uninstallUI(component);
rootView.setView(null);
- textComponent.removePropertyChangeListener(updateHandler);
-
uninstallDefaults();
uninstallListeners();
uninstallKeyboardActions();
@@ -750,6 +784,7 @@ public abstract class BasicTextUI extends TextUI
*/
protected void uninstallListeners()
{
+ textComponent.removePropertyChangeListener(updateHandler);
textComponent.removeFocusListener(focuslistener);
textComponent.getDocument().removeDocumentListener(documentHandler);
}
@@ -786,7 +821,9 @@ public abstract class BasicTextUI extends TextUI
float w = v.getPreferredSpan(View.X_AXIS);
float h = v.getPreferredSpan(View.Y_AXIS);
- return new Dimension((int) w, (int) h);
+ Insets i = c.getInsets();
+ return new Dimension((int) w + i.left + i.right,
+ (int) h + i.top + i.bottom);
}
/**
@@ -817,18 +854,49 @@ public abstract class BasicTextUI extends TextUI
}
/**
- * Paints the text component.
+ * Paints the text component. This acquires a read lock on the model and then
+ * calls {@link #paintSafely(Graphics)} in order to actually perform the
+ * painting.
*
* @param g the <code>Graphics</code> context to paint to
* @param c not used here
*/
public final void paint(Graphics g, JComponent c)
{
- paintSafely(g);
+ try
+ {
+ Document doc = textComponent.getDocument();
+ if (doc instanceof AbstractDocument)
+ {
+ AbstractDocument aDoc = (AbstractDocument) doc;
+ aDoc.readLock();
+ }
+
+ paintSafely(g);
+ }
+ finally
+ {
+ Document doc = textComponent.getDocument();
+ if (doc instanceof AbstractDocument)
+ {
+ AbstractDocument aDoc = (AbstractDocument) doc;
+ aDoc.readUnlock();
+ }
+ }
}
/**
- * Actually performs the painting.
+ * This paints the text component while beeing sure that the model is not
+ * modified while painting.
+ *
+ * The following is performed in this order:
+ * <ol>
+ * <li>If the text component is opaque, the background is painted by
+ * calling {@link #paintBackground(Graphics)}.</li>
+ * <li>If there is a highlighter, the highlighter is painted.</li>
+ * <li>The view hierarchy is painted.</li>
+ * <li>The Caret is painter.</li>
+ * </ol>
*
* @param g the <code>Graphics</code> context to paint to
*/
@@ -840,9 +908,19 @@ public abstract class BasicTextUI extends TextUI
if (textComponent.isOpaque())
paintBackground(g);
- if (highlighter != null
- && textComponent.getSelectionStart() != textComponent.getSelectionEnd())
- highlighter.paint(g);
+ // Try painting with the highlighter without checking whether there
+ // is a selection because a highlighter can be used to do more than
+ // marking selected text.
+ if (highlighter != null)
+ {
+ // Handle restoring of the color here to prevent
+ // drawing problems when the Highlighter implementor
+ // forgets to restore it.
+ Color oldColor = g.getColor();
+ highlighter.paint(g);
+ g.setColor(oldColor);
+ }
+
rootView.paint(g, getVisibleEditorRect());
@@ -857,10 +935,23 @@ public abstract class BasicTextUI extends TextUI
*/
protected void paintBackground(Graphics g)
{
- // This method does nothing. All the background filling is done by the
- // ComponentUI update method. However, the method is called by paint
- // to provide a way for subclasses to draw something different (e.g.
- // background images etc) on the background.
+ Color old = g.getColor();
+ g.setColor(textComponent.getBackground());
+ g.fillRect(0, 0, textComponent.getWidth(), textComponent.getHeight());
+ g.setColor(old);
+ }
+
+ /**
+ * Overridden for better control over background painting. This now simply
+ * calls {@link #paint} and this delegates the background painting to
+ * {@link #paintBackground}.
+ *
+ * @param g the graphics to use
+ * @param c the component to be painted
+ */
+ public void update(Graphics g, JComponent c)
+ {
+ paint(g, c);
}
/**
@@ -895,7 +986,84 @@ public abstract class BasicTextUI extends TextUI
public void damageRange(JTextComponent t, int p0, int p1,
Position.Bias firstBias, Position.Bias secondBias)
{
- // TODO: Implement me.
+ try
+ {
+ // Limit p0 and p1 to sane values to prevent unfriendly
+ // BadLocationExceptions. This makes it possible for the highlighter
+ // to send us illegal values which can happen when a large number
+ // of selected characters are removed (eg. by pressing delete
+ // or backspace).
+ // The reference implementation does not throw an exception, too.
+ p0 = Math.min(p0, t.getDocument().getLength());
+ p1 = Math.min(p1, t.getDocument().getLength());
+
+ Rectangle l1 = modelToView(t, p0, firstBias);
+ Rectangle l2 = modelToView(t, p1, secondBias);
+ if (l1.y == l2.y)
+ t.repaint(l1.union(l2));
+ else
+ {
+ // The two rectangles lie on different lines and we need a
+ // different algorithm to calculate the damaged area:
+ // 1. The line of p0 is damaged from the position of p0
+ // to the right border.
+ // 2. All lines between the ones where p0 and p1 lie on
+ // are completely damaged. Use the allocation area to find
+ // out the bounds.
+ // 3. The final line is damaged from the left bound to the
+ // position of p1.
+ Insets insets = t.getInsets();
+
+ // Damage first line until the end.
+ l1.width = insets.right + t.getWidth() - l1.x;
+ t.repaint(l1);
+
+ // Note: Utilities.getPositionBelow() may return the offset
+ // that was put in. In that case there is no next line and
+ // we should stop searching for one.
+
+ int posBelow = Utilities.getPositionBelow(t, p0, l1.x);
+ if (posBelow < p1 && posBelow != -1 && posBelow != p0)
+ {
+ // Take the rectangle of the offset we just found and grow it
+ // to the maximum width. Retain y because this is our start
+ // height.
+ Rectangle grow = modelToView(t, posBelow);
+ grow.x = insets.left;
+ grow.width = t.getWidth() + insets.right;
+
+ // Find further lines which have to be damaged completely.
+ int nextPosBelow = posBelow;
+ while (nextPosBelow < p1 && nextPosBelow != -1 && posBelow != nextPosBelow)
+ {
+ posBelow = nextPosBelow;
+ nextPosBelow = Utilities.getPositionBelow(t, posBelow, l1.x);
+ }
+ // Now posBelow is an offset on the last line which has to be damaged
+ // completely. (newPosBelow is on the same line as p1)
+
+ // Retrieve the rectangle of posBelow and use its y and height
+ // value to calculate the final height of the multiple line
+ // spanning rectangle.
+ Rectangle end = modelToView(t, posBelow);
+ grow.height = end.y + end.height - grow.y;
+
+ // Mark that area as damage.
+ t.repaint(grow);
+ }
+
+ // Damage last line from its beginning to the position of p1.
+ l2.width += l2.x;
+ l2.x = insets.left;
+ t.repaint(l2);
+ }
+ }
+ catch (BadLocationException ex)
+ {
+ AssertionError err = new AssertionError("Unexpected bad location");
+ err.initCause(ex);
+ throw err;
+ }
}
/**
@@ -1061,7 +1229,6 @@ public abstract class BasicTextUI extends TextUI
*/
protected Rectangle getVisibleEditorRect()
{
- JTextComponent textComponent = getComponent();
int width = textComponent.getWidth();
int height = textComponent.getHeight();
@@ -1082,7 +1249,6 @@ public abstract class BasicTextUI extends TextUI
protected final void setView(View view)
{
rootView.setView(view);
- view.setParent(rootView);
textComponent.revalidate();
textComponent.repaint();
}
OpenPOWER on IntegriCloud