summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java')
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java264
1 files changed, 112 insertions, 152 deletions
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
index 34261cfe644..8e9c8c949f3 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
@@ -83,7 +83,6 @@ 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;
@@ -418,7 +417,19 @@ public abstract class BasicTextUI extends TextUI
if (event.getPropertyName().equals("document"))
{
// Document changed.
- modelChanged();
+ Object oldValue = event.getOldValue();
+ if (oldValue != null)
+ {
+ Document oldDoc = (Document) oldValue;
+ oldDoc.removeDocumentListener(documentHandler);
+ }
+ Object newValue = event.getNewValue();
+ if (newValue != null)
+ {
+ Document newDoc = (Document) newValue;
+ newDoc.addDocumentListener(documentHandler);
+ }
+ modelChanged();
}
BasicTextUI.this.propertyChange(event);
@@ -501,18 +512,6 @@ public abstract class BasicTextUI extends TextUI
DocumentHandler documentHandler = new DocumentHandler();
/**
- * The standard background color. This is the color which is used to paint
- * text in enabled text components.
- */
- Color background;
-
- /**
- * The inactive background color. This is the color which is used to paint
- * text in disabled text components.
- */
- Color inactiveBackground;
-
- /**
* Creates a new <code>BasicTextUI</code> instance.
*/
public BasicTextUI()
@@ -558,22 +557,23 @@ public abstract class BasicTextUI extends TextUI
*/
public void installUI(final JComponent c)
{
- super.installUI(c);
-
textComponent = (JTextComponent) c;
+ installDefaults();
+ textComponent.addPropertyChangeListener(updateHandler);
Document doc = textComponent.getDocument();
if (doc == null)
{
doc = getEditorKit(textComponent).createDefaultDocument();
textComponent.setDocument(doc);
}
- installDefaults();
+ else
+ {
+ doc.addDocumentListener(documentHandler);
+ modelChanged();
+ }
+
installListeners();
installKeyboardActions();
-
- // We need to trigger this so that the view hierarchy gets initialized.
- modelChanged();
-
}
/**
@@ -581,34 +581,60 @@ public abstract class BasicTextUI extends TextUI
*/
protected void installDefaults()
{
+ String prefix = getPropertyPrefix();
+ // Install the standard properties.
+ LookAndFeel.installColorsAndFont(textComponent, prefix + ".background",
+ prefix + ".foreground", prefix + ".font");
+ LookAndFeel.installBorder(textComponent, prefix + ".border");
+ textComponent.setMargin(UIManager.getInsets(prefix + ".margin"));
+
+ // Some additional text component only properties.
+ Color color = textComponent.getCaretColor();
+ if (color == null || color instanceof UIResource)
+ {
+ color = UIManager.getColor(prefix + ".caretForeground");
+ textComponent.setCaretColor(color);
+ }
+
+ // Fetch the colors for enabled/disabled text components.
+ color = textComponent.getDisabledTextColor();
+ if (color == null || color instanceof UIResource)
+ {
+ color = UIManager.getColor(prefix + ".inactiveBackground");
+ textComponent.setDisabledTextColor(color);
+ }
+ color = textComponent.getSelectedTextColor();
+ if (color == null || color instanceof UIResource)
+ {
+ color = UIManager.getColor(prefix + ".selectionForeground");
+ textComponent.setSelectedTextColor(color);
+ }
+ color = textComponent.getSelectionColor();
+ if (color == null || color instanceof UIResource)
+ {
+ color = UIManager.getColor(prefix + ".selectionBackground");
+ textComponent.setSelectionColor(color);
+ }
+
+ Insets margin = textComponent.getMargin();
+ if (margin == null || margin instanceof UIResource)
+ {
+ margin = UIManager.getInsets(prefix + ".margin");
+ textComponent.setMargin(margin);
+ }
+
Caret caret = textComponent.getCaret();
- if (caret == null)
+ if (caret == null || caret instanceof UIResource)
{
caret = createCaret();
textComponent.setCaret(caret);
+ caret.setBlinkRate(UIManager.getInt(prefix + ".caretBlinkRate"));
}
Highlighter highlighter = textComponent.getHighlighter();
- if (highlighter == null)
+ if (highlighter == null || highlighter instanceof UIResource)
textComponent.setHighlighter(createHighlighter());
- String prefix = getPropertyPrefix();
- LookAndFeel.installColorsAndFont(textComponent, prefix + ".background",
- prefix + ".foreground", prefix + ".font");
- LookAndFeel.installBorder(textComponent, prefix + ".border");
- textComponent.setMargin(UIManager.getInsets(prefix + ".margin"));
-
- caret.setBlinkRate(UIManager.getInt(prefix + ".caretBlinkRate"));
-
- // Fetch the colors for enabled/disabled text components.
- background = UIManager.getColor(prefix + ".background");
- inactiveBackground = UIManager.getColor(prefix + ".inactiveBackground");
- textComponent.setDisabledTextColor(UIManager.getColor(prefix
- + ".inactiveForeground"));
- textComponent.setSelectedTextColor(UIManager.getColor(prefix
- + ".selectionForeground"));
- textComponent.setSelectionColor(UIManager.getColor(prefix
- + ".selectionBackground"));
}
/**
@@ -670,18 +696,6 @@ public abstract class BasicTextUI extends TextUI
protected void installListeners()
{
textComponent.addFocusListener(focuslistener);
- textComponent.addPropertyChangeListener(updateHandler);
- installDocumentListeners();
- }
-
- /**
- * Installs the document listeners on the textComponent's model.
- */
- private void installDocumentListeners()
- {
- Document doc = textComponent.getDocument();
- if (doc != null)
- doc.addDocumentListener(documentHandler);
}
/**
@@ -845,9 +859,7 @@ public abstract class BasicTextUI extends TextUI
*/
protected void uninstallListeners()
{
- textComponent.removePropertyChangeListener(updateHandler);
textComponent.removeFocusListener(focuslistener);
- textComponent.getDocument().removeDocumentListener(documentHandler);
}
/**
@@ -1029,7 +1041,7 @@ public abstract class BasicTextUI extends TextUI
*/
public void damageRange(JTextComponent t, int p0, int p1)
{
- damageRange(t, p0, p1, null, null);
+ damageRange(t, p0, p1, Position.Bias.Forward, Position.Bias.Backward);
}
/**
@@ -1049,106 +1061,36 @@ public abstract class BasicTextUI extends TextUI
public void damageRange(JTextComponent t, int p0, int p1,
Position.Bias firstBias, Position.Bias secondBias)
{
- // Do nothing if the component cannot be properly displayed.
- if (t.getWidth() == 0 || t.getHeight() == 0)
- return;
-
- try
+ Rectangle alloc = getVisibleEditorRect();
+ if (alloc != null)
{
- // 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 == null || l2 == null)
+ Document doc = t.getDocument();
+
+ // Acquire lock here to avoid structural changes in between.
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readLock();
+ try
{
- // Unable to determine the start or end of the selection.
- t.repaint();
+ rootView.setSize(alloc.width, alloc.height);
+ Shape damage = rootView.modelToView(p0, firstBias, p1, secondBias,
+ alloc);
+ Rectangle r = damage instanceof Rectangle ? (Rectangle) damage
+ : damage.getBounds();
+ textComponent.repaint(r.x, r.y, r.width, r.height);
}
- else if (l1.y == l2.y)
+ catch (BadLocationException ex)
{
- SwingUtilities.computeUnion(l2.x, l2.y, l2.width, l2.height, l1);
- t.repaint(l1);
+ // Lets ignore this as it causes no serious problems.
+ // For debugging, comment this out.
+ // ex.printStackTrace();
}
- else
+ finally
{
- // 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);
- int p1RowStart = Utilities.getRowStart(t, p1);
-
- if (posBelow != -1
- && posBelow != p0
- && Utilities.getRowStart(t, posBelow) != p1RowStart)
- {
- // 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 != -1
- && posBelow != nextPosBelow
- && Utilities.getRowStart(t, nextPosBelow) != p1RowStart)
- {
- posBelow = nextPosBelow;
- nextPosBelow = Utilities.getPositionBelow(t, posBelow,
- l1.x);
-
- if (posBelow == nextPosBelow)
- break;
- }
- // 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);
+ // Release lock.
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readUnlock();
}
}
- catch (BadLocationException ex)
- {
- AssertionError err = new AssertionError("Unexpected bad location");
- err.initCause(ex);
- throw err;
- }
}
/**
@@ -1245,10 +1187,29 @@ public abstract class BasicTextUI extends TextUI
public Rectangle modelToView(JTextComponent t, int pos, Position.Bias bias)
throws BadLocationException
{
- Rectangle r = getVisibleEditorRect();
-
- return (r != null) ? rootView.modelToView(pos, r, bias).getBounds()
- : null;
+ // We need to read-lock here because we depend on the document
+ // structure not beeing changed in between.
+ Document doc = textComponent.getDocument();
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readLock();
+ Rectangle rect = null;
+ try
+ {
+ Rectangle r = getVisibleEditorRect();
+ if (r != null)
+ {
+ rootView.setSize(r.width, r.height);
+ Shape s = rootView.modelToView(pos, r, bias);
+ if (s != null)
+ rect = s.getBounds();
+ }
+ }
+ finally
+ {
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readUnlock();
+ }
+ return rect;
}
/**
@@ -1361,7 +1322,6 @@ public abstract class BasicTextUI extends TextUI
Document doc = textComponent.getDocument();
if (doc == null)
return;
- installDocumentListeners();
Element elem = doc.getDefaultRootElement();
if (elem == null)
return;
OpenPOWER on IntegriCloud