diff options
author | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-10 21:46:48 +0000 |
---|---|---|
committer | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-10 21:46:48 +0000 |
commit | ce57ab760f69de6db452def7ffbf5b114a2d8694 (patch) | |
tree | ea38c56431c5d4528fb54254c3f8e50f517bede3 /libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java | |
parent | 50996fe55769882de3f410896032c887f0ff0d04 (diff) | |
download | ppe42-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.java | 250 |
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(); } |