aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/text
diff options
context:
space:
mode:
authorMark Wielaard <mark@gcc.gnu.org>2006-05-18 17:29:21 +0000
committerMark Wielaard <mark@gcc.gnu.org>2006-05-18 17:29:21 +0000
commit4f9533c7722fa07511a94d005227961f4a4dec23 (patch)
tree9f9c470de62ee62fba1331a396450d728d2b1fad /libjava/classpath/javax/swing/text
parenteaec4980e139903ae9b274d1abcf3a13946603a8 (diff)
downloadgcc-4f9533c7722fa07511a94d005227961f4a4dec23.zip
gcc-4f9533c7722fa07511a94d005227961f4a4dec23.tar.gz
gcc-4f9533c7722fa07511a94d005227961f4a4dec23.tar.bz2
Imported GNU Classpath 0.90
Imported GNU Classpath 0.90 * scripts/makemake.tcl: LocaleData.java moved to gnu/java/locale. * sources.am: Regenerated. * gcj/javaprims.h: Regenerated. * Makefile.in: Regenerated. * gcj/Makefile.in: Regenerated. * include/Makefile.in: Regenerated. * testsuite/Makefile.in: Regenerated. * gnu/java/lang/VMInstrumentationImpl.java: New override. * gnu/java/net/local/LocalSocketImpl.java: Likewise. * gnu/classpath/jdwp/VMMethod.java: Likewise. * gnu/classpath/jdwp/VMVirtualMachine.java: Update to latest interface. * java/lang/Thread.java: Add UncaughtExceptionHandler. * java/lang/reflect/Method.java: Implements GenericDeclaration and isSynthetic(), * java/lang/reflect/Field.java: Likewise. * java/lang/reflect/Constructor.java * java/lang/Class.java: Implements Type, GenericDeclaration, getSimpleName() and getEnclosing*() methods. * java/lang/Class.h: Add new public methods. * java/lang/Math.java: Add signum(), ulp() and log10(). * java/lang/natMath.cc (log10): New function. * java/security/VMSecureRandom.java: New override. * java/util/logging/Logger.java: Updated to latest classpath version. * java/util/logging/LogManager.java: New override. From-SVN: r113887
Diffstat (limited to 'libjava/classpath/javax/swing/text')
-rw-r--r--libjava/classpath/javax/swing/text/AbstractDocument.java151
-rw-r--r--libjava/classpath/javax/swing/text/AsyncBoxView.java6
-rw-r--r--libjava/classpath/javax/swing/text/BoxView.java9
-rw-r--r--libjava/classpath/javax/swing/text/CompositeView.java131
-rw-r--r--libjava/classpath/javax/swing/text/DefaultCaret.java179
-rw-r--r--libjava/classpath/javax/swing/text/DefaultEditorKit.java1088
-rw-r--r--libjava/classpath/javax/swing/text/DefaultHighlighter.java142
-rw-r--r--libjava/classpath/javax/swing/text/FieldView.java182
-rw-r--r--libjava/classpath/javax/swing/text/FlowView.java2
-rw-r--r--libjava/classpath/javax/swing/text/GapContent.java18
-rw-r--r--libjava/classpath/javax/swing/text/InternationalFormatter.java2
-rw-r--r--libjava/classpath/javax/swing/text/JTextComponent.java2
-rw-r--r--libjava/classpath/javax/swing/text/PlainView.java78
-rw-r--r--libjava/classpath/javax/swing/text/Position.java2
-rw-r--r--libjava/classpath/javax/swing/text/Segment.java5
-rw-r--r--libjava/classpath/javax/swing/text/StyleContext.java12
-rw-r--r--libjava/classpath/javax/swing/text/Utilities.java103
-rw-r--r--libjava/classpath/javax/swing/text/View.java29
-rw-r--r--libjava/classpath/javax/swing/text/WrappedPlainView.java223
-rw-r--r--libjava/classpath/javax/swing/text/html/FormView.java45
-rw-r--r--libjava/classpath/javax/swing/text/html/HTML.java4
-rw-r--r--libjava/classpath/javax/swing/text/html/HTMLDocument.java46
-rw-r--r--libjava/classpath/javax/swing/text/html/HTMLEditorKit.java3
-rw-r--r--libjava/classpath/javax/swing/text/html/ListView.java131
-rw-r--r--libjava/classpath/javax/swing/text/html/NullView.java4
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/Entity.java2
-rw-r--r--libjava/classpath/javax/swing/text/rtf/package.html48
27 files changed, 1948 insertions, 699 deletions
diff --git a/libjava/classpath/javax/swing/text/AbstractDocument.java b/libjava/classpath/javax/swing/text/AbstractDocument.java
index a3e8c46..1ef8173 100644
--- a/libjava/classpath/javax/swing/text/AbstractDocument.java
+++ b/libjava/classpath/javax/swing/text/AbstractDocument.java
@@ -51,6 +51,7 @@ import javax.swing.event.DocumentListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
+import javax.swing.text.DocumentFilter;
import javax.swing.tree.TreeNode;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CompoundEdit;
@@ -148,6 +149,11 @@ public abstract class AbstractDocument implements Document, Serializable
*/
Object documentCV = new Object();
+ /** An instance of a DocumentFilter.FilterBypass which allows calling
+ * the insert, remove and replace method without checking for an installed
+ * document filter.
+ */
+ DocumentFilter.FilterBypass bypass;
/**
* Creates a new <code>AbstractDocument</code> with the specified
@@ -180,6 +186,19 @@ public abstract class AbstractDocument implements Document, Serializable
content = doc;
context = ctx;
}
+
+ /** Returns the DocumentFilter.FilterBypass instance for this
+ * document and create it if it does not exist yet.
+ *
+ * @return This document's DocumentFilter.FilterBypass instance.
+ */
+ private DocumentFilter.FilterBypass getBypass()
+ {
+ if (bypass == null)
+ bypass = new Bypass();
+
+ return bypass;
+ }
/**
* Returns the paragraph {@link Element} that holds the specified position.
@@ -329,7 +348,7 @@ public abstract class AbstractDocument implements Document, Serializable
*
* @return the {@link AttributeContext} used in this <code>Document</code>
*/
- protected AttributeContext getAttributeContext()
+ protected final AttributeContext getAttributeContext()
{
return context;
}
@@ -366,7 +385,7 @@ public abstract class AbstractDocument implements Document, Serializable
* @return the thread that currently modifies this <code>Document</code>
* if there is one, otherwise <code>null</code>
*/
- protected Thread getCurrentWriter()
+ protected final Thread getCurrentWriter()
{
return currentWriter;
}
@@ -392,7 +411,7 @@ public abstract class AbstractDocument implements Document, Serializable
* @return a {@link Position} which will always mark the end of the
* <code>Document</code>
*/
- public Position getEndPosition()
+ public final Position getEndPosition()
{
// FIXME: Properly implement this by calling Content.createPosition().
return new Position()
@@ -437,7 +456,7 @@ public abstract class AbstractDocument implements Document, Serializable
* @return the property for <code>key</code> or <code>null</code> if there
* is no such property stored
*/
- public Object getProperty(Object key)
+ public final Object getProperty(Object key)
{
// FIXME: make me thread-safe
Object value = null;
@@ -470,7 +489,7 @@ public abstract class AbstractDocument implements Document, Serializable
* @return a {@link Position} which will always mark the beginning of the
* <code>Document</code>
*/
- public Position getStartPosition()
+ public final Position getStartPosition()
{
// FIXME: Properly implement this using Content.createPosition().
return new Position()
@@ -521,6 +540,13 @@ public abstract class AbstractDocument implements Document, Serializable
/**
* Inserts a String into this <code>Document</code> at the specified
* position and assigning the specified attributes to it.
+ *
+ * <p>If a {@link DocumentFilter} is installed in this document, the
+ * corresponding method of the filter object is called.</p>
+ *
+ * <p>The method has no effect when <code>text</code> is <code>null</code>
+ * or has a length of zero.</p>
+ *
*
* @param offset the location at which the string should be inserted
* @param text the content to be inserted
@@ -532,6 +558,19 @@ public abstract class AbstractDocument implements Document, Serializable
public void insertString(int offset, String text, AttributeSet attributes)
throws BadLocationException
{
+ // Bail out if we have a bogus insertion (Behavior observed in RI).
+ if (text == null || text.length() == 0)
+ return;
+
+ if (documentFilter == null)
+ insertStringImpl(offset, text, attributes);
+ else
+ documentFilter.insertString(getBypass(), offset, text, attributes);
+ }
+
+ void insertStringImpl(int offset, String text, AttributeSet attributes)
+ throws BadLocationException
+ {
// Just return when no text to insert was given.
if (text == null || text.length() == 0)
return;
@@ -589,7 +628,7 @@ public abstract class AbstractDocument implements Document, Serializable
* @param key the key of the property to be stored
* @param value the value of the property to be stored
*/
- public void putProperty(Object key, Object value)
+ public final void putProperty(Object key, Object value)
{
// FIXME: make me thread-safe
if (properties == null)
@@ -602,7 +641,7 @@ public abstract class AbstractDocument implements Document, Serializable
* Blocks until a read lock can be obtained. Must block if there is
* currently a writer modifying the <code>Document</code>.
*/
- public void readLock()
+ public final void readLock()
{
if (currentWriter != null && currentWriter.equals(Thread.currentThread()))
return;
@@ -627,7 +666,7 @@ public abstract class AbstractDocument implements Document, Serializable
* Releases the read lock. If this was the only reader on this
* <code>Document</code>, writing may begin now.
*/
- public void readUnlock()
+ public final void readUnlock()
{
// Note we could have a problem here if readUnlock was called without a
// prior call to readLock but the specs simply warn users to ensure that
@@ -673,7 +712,16 @@ public abstract class AbstractDocument implements Document, Serializable
/**
* Removes a piece of content from this <code>Document</code>.
- *
+ *
+ * <p>If a {@link DocumentFilter} is installed in this document, the
+ * corresponding method of the filter object is called. The
+ * <code>DocumentFilter</code> is called even if <code>length</code>
+ * is zero. This is different from {@link #replace}.</p>
+ *
+ * <p>Note: When <code>length</code> is zero or below the call is not
+ * forwarded to the underlying {@link AbstractDocument.Content} instance
+ * of this document and no exception is thrown.</p>
+ *
* @param offset the start offset of the fragment to be removed
* @param length the length of the fragment to be removed
*
@@ -683,6 +731,18 @@ public abstract class AbstractDocument implements Document, Serializable
*/
public void remove(int offset, int length) throws BadLocationException
{
+ if (documentFilter == null)
+ removeImpl(offset, length);
+ else
+ documentFilter.remove(getBypass(), offset, length);
+ }
+
+ void removeImpl(int offset, int length) throws BadLocationException
+ {
+ // Prevent some unneccessary method invocation (observed in the RI).
+ if (length <= 0)
+ return;
+
DefaultDocumentEvent event =
new DefaultDocumentEvent(offset, length,
DocumentEvent.EventType.REMOVE);
@@ -707,6 +767,13 @@ public abstract class AbstractDocument implements Document, Serializable
/**
* Replaces a piece of content in this <code>Document</code> with
* another piece of content.
+ *
+ * <p>If a {@link DocumentFilter} is installed in this document, the
+ * corresponding method of the filter object is called.</p>
+ *
+ * <p>The method has no effect if <code>length</code> is zero (and
+ * only zero) and, at the same time, <code>text</code> is
+ * <code>null</code> or has zero length.</p>
*
* @param offset the start offset of the fragment to be removed
* @param length the length of the fragment to be removed
@@ -720,11 +787,36 @@ public abstract class AbstractDocument implements Document, Serializable
* @since 1.4
*/
public void replace(int offset, int length, String text,
+ AttributeSet attributes)
+ throws BadLocationException
+ {
+ // Bail out if we have a bogus replacement (Behavior observed in RI).
+ if (length == 0
+ && (text == null || text.length() == 0))
+ return;
+
+ if (documentFilter == null)
+ {
+ // It is important to call the methods which again do the checks
+ // of the arguments and the DocumentFilter because subclasses may
+ // have overridden these methods and provide crucial behavior
+ // which would be skipped if we call the non-checking variants.
+ // An example for this is PlainDocument where insertString can
+ // provide a filtering of newlines.
+ remove(offset, length);
+ insertString(offset, text, attributes);
+ }
+ else
+ documentFilter.replace(getBypass(), offset, length, text, attributes);
+
+ }
+
+ void replaceImpl(int offset, int length, String text,
AttributeSet attributes)
throws BadLocationException
{
- remove(offset, length);
- insertString(offset, text, attributes);
+ removeImpl(offset, length);
+ insertStringImpl(offset, text, attributes);
}
/**
@@ -854,7 +946,7 @@ public abstract class AbstractDocument implements Document, Serializable
* Blocks until a write lock can be obtained. Must wait if there are
* readers currently reading or another thread is currently writing.
*/
- protected void writeLock()
+ protected final void writeLock()
{
if (currentWriter != null && currentWriter.equals(Thread.currentThread()))
return;
@@ -881,7 +973,7 @@ public abstract class AbstractDocument implements Document, Serializable
* Releases the write lock. This allows waiting readers or writers to
* obtain the lock.
*/
- protected void writeUnlock()
+ protected final void writeUnlock()
{
synchronized (documentCV)
{
@@ -2239,4 +2331,37 @@ public abstract class AbstractDocument implements Document, Serializable
+ getStartOffset() + "," + getEndOffset() + "\n");
}
}
+
+ /** A class whose methods delegate to the insert, remove and replace methods
+ * of this document which do not check for an installed DocumentFilter.
+ */
+ class Bypass extends DocumentFilter.FilterBypass
+ {
+
+ public Document getDocument()
+ {
+ return AbstractDocument.this;
+ }
+
+ public void insertString(int offset, String string, AttributeSet attr)
+ throws BadLocationException
+ {
+ AbstractDocument.this.insertStringImpl(offset, string, attr);
+ }
+
+ public void remove(int offset, int length)
+ throws BadLocationException
+ {
+ AbstractDocument.this.removeImpl(offset, length);
+ }
+
+ public void replace(int offset, int length, String string,
+ AttributeSet attrs)
+ throws BadLocationException
+ {
+ AbstractDocument.this.replaceImpl(offset, length, string, attrs);
+ }
+
+ }
+
}
diff --git a/libjava/classpath/javax/swing/text/AsyncBoxView.java b/libjava/classpath/javax/swing/text/AsyncBoxView.java
index 1988bba..90447f8 100644
--- a/libjava/classpath/javax/swing/text/AsyncBoxView.java
+++ b/libjava/classpath/javax/swing/text/AsyncBoxView.java
@@ -1030,7 +1030,7 @@ public class AsyncBoxView
*
* @since 1.4
*/
- public void setEstimatedMajorSpan(boolean estimated)
+ protected void setEstimatedMajorSpan(boolean estimated)
{
estimatedMajorSpan = estimated;
}
@@ -1045,7 +1045,7 @@ public class AsyncBoxView
*
* @since 1.4
*/
- public boolean getEstimatedMajorSpan()
+ protected boolean getEstimatedMajorSpan()
{
return estimatedMajorSpan;
}
@@ -1367,7 +1367,7 @@ public class AsyncBoxView
/**
* Updates the layout for this view. This is implemented to trigger
- * {link ChildLocator#childChanged} for the changed view, if there is
+ * {@link ChildLocator#childChanged} for the changed view, if there is
* any.
*
* @param ec the element change, may be <code>null</code> if there were
diff --git a/libjava/classpath/javax/swing/text/BoxView.java b/libjava/classpath/javax/swing/text/BoxView.java
index b5907dc..a184a81 100644
--- a/libjava/classpath/javax/swing/text/BoxView.java
+++ b/libjava/classpath/javax/swing/text/BoxView.java
@@ -1,5 +1,5 @@
/* BoxView.java -- An composite view
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -591,9 +591,12 @@ public class BoxView
for (int i = 0; i < count; ++i)
{
copy.setBounds(r);
- childAllocation(i, r);
+ // The next call modifies copy.
+ childAllocation(i, copy);
if (copy.contains(x, y))
{
+ // Modify r on success.
+ r.setBounds(copy);
result = getView(i);
break;
}
@@ -919,7 +922,7 @@ public class BoxView
return super.viewToModel(x, y, a, bias);
}
- protected boolean flipEastAndWestEnds(int position, Position.Bias bias)
+ protected boolean flipEastAndWestAtEnds(int position, Position.Bias bias)
{
// FIXME: What to do here?
return super.flipEastAndWestAtEnds(position, bias);
diff --git a/libjava/classpath/javax/swing/text/CompositeView.java b/libjava/classpath/javax/swing/text/CompositeView.java
index a10aca7..17f13db 100644
--- a/libjava/classpath/javax/swing/text/CompositeView.java
+++ b/libjava/classpath/javax/swing/text/CompositeView.java
@@ -1,5 +1,5 @@
/* CompositeView.java -- An abstract view that manages child views
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -218,21 +218,24 @@ public abstract class CompositeView
throws BadLocationException
{
int childIndex = getViewIndex(pos, bias);
+ if (childIndex == -1)
+ throw new BadLocationException("Position " + pos + " is not represented by view.", pos);
+
Shape ret = null;
- if (childIndex != -1)
- {
- View child = getView(childIndex);
- Shape childAlloc = getChildAllocation(childIndex, a);
- if (childAlloc == null)
- ret = createDefaultLocation(a, bias);
- Shape result = child.modelToView(pos, childAlloc, bias);
- if (result != null)
- ret = result;
- else
- ret = createDefaultLocation(a, bias);
- }
- else
+
+ View child = getView(childIndex);
+ Shape childAlloc = getChildAllocation(childIndex, a);
+
+ if (childAlloc == null)
ret = createDefaultLocation(a, bias);
+
+ Shape result = child.modelToView(pos, childAlloc, bias);
+
+ if (result != null)
+ ret = result;
+ else
+ ret = createDefaultLocation(a, bias);
+
return ret;
}
@@ -301,7 +304,7 @@ public abstract class CompositeView
{
Rectangle r = getInsideAllocation(a);
View view = getViewAtPoint((int) x, (int) y, r);
- return view.viewToModel(x, y, a, b);
+ return view.viewToModel(x, y, r, b);
}
return 0;
}
@@ -630,8 +633,51 @@ public abstract class CompositeView
Position.Bias[] biasRet)
throws BadLocationException
{
- // FIXME: Implement this correctly.
- return pos;
+ // TODO: It is unknown to me how this method has to be implemented and
+ // there is no specification telling me how to do it properly. Therefore
+ // the implementation was done for cases that are known.
+ //
+ // If this method ever happens to act silly for your particular case then
+ // it is likely that it is a cause of not knowing about your case when it
+ // was implemented first. You are free to fix the behavior.
+ //
+ // Here are the assumptions that lead to the implementation:
+ // If direction is NORTH chose the View preceding the one that contains the
+ // offset 'pos' (imagine the views are stacked on top of each other where
+ // the top is 0 and the bottom is getViewCount()-1.
+ // Consecutively when the direction is SOUTH the View following the one
+ // the offset 'pos' lies in is questioned.
+ //
+ // This limitation is described as PR 27345.
+ int index = getViewIndex(pos, b);
+ View v = null;
+
+ if (index == -1)
+ return pos;
+
+ switch (direction)
+ {
+ case NORTH:
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index <= 0)
+ return pos;
+
+ v = getView(index - 1);
+ break;
+ case SOUTH:
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index >= getViewCount() - 1)
+ return pos;
+
+ v = getView(index + 1);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ return v.getNextVisualPositionFrom(pos, b, a, direction, biasRet);
}
/**
@@ -664,8 +710,55 @@ public abstract class CompositeView
Position.Bias[] biasRet)
throws BadLocationException
{
- // FIXME: Implement this correctly.
- return pos;
+ // TODO: It is unknown to me how this method has to be implemented and
+ // there is no specification telling me how to do it properly. Therefore
+ // the implementation was done for cases that are known.
+ //
+ // If this method ever happens to act silly for your particular case then
+ // it is likely that it is a cause of not knowing about your case when it
+ // was implemented first. You are free to fix the behavior.
+ //
+ // Here are the assumptions that lead to the implementation:
+ // If direction is EAST increase the offset by one and ask the View to
+ // which that index belong to calculate the 'next visual position'.
+ // If the direction is WEST do the same with offset 'pos' being decreased
+ // by one.
+ // This behavior will fail in a right-to-left or bidi environment!
+ //
+ // This limitation is described as PR 27346.
+ int index;
+
+ View v = null;
+
+ switch (direction)
+ {
+ case EAST:
+ index = getViewIndex(pos + 1, b);
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index == -1)
+ return pos;
+
+ v = getView(index);
+ break;
+ case WEST:
+ index = getViewIndex(pos - 1, b);
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index == -1)
+ return pos;
+
+ v = getView(index);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ return v.getNextVisualPositionFrom(pos,
+ b,
+ a,
+ direction,
+ biasRet);
}
/**
diff --git a/libjava/classpath/javax/swing/text/DefaultCaret.java b/libjava/classpath/javax/swing/text/DefaultCaret.java
index f2a68c0..c9369af 100644
--- a/libjava/classpath/javax/swing/text/DefaultCaret.java
+++ b/libjava/classpath/javax/swing/text/DefaultCaret.java
@@ -59,17 +59,48 @@ import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.EventListenerList;
+import javax.swing.text.Position.Bias;
/**
* The default implementation of the {@link Caret} interface.
*
- * @author orgininal author unknown
+ * @author original author unknown
* @author Roman Kennke (roman@kennke.org)
*/
public class DefaultCaret extends Rectangle
implements Caret, FocusListener, MouseListener, MouseMotionListener
{
+
+ /** A text component in the current VM which currently has a
+ * text selection or <code>null</code>.
+ */
+ static JTextComponent componentWithSelection;
+
+ /** An implementation of NavigationFilter.FilterBypass which delegates
+ * to the corresponding methods of the <code>DefaultCaret</code>.
+ *
+ * @author Robert Schuster (robertschuster@fsfe.org)
+ */
+ class Bypass extends NavigationFilter.FilterBypass
+ {
+
+ public Caret getCaret()
+ {
+ return DefaultCaret.this;
+ }
+ public void moveDot(int dot, Bias bias)
+ {
+ DefaultCaret.this.moveDotImpl(dot);
+ }
+
+ public void setDot(int dot, Bias bias)
+ {
+ DefaultCaret.this.setDotImpl(dot);
+ }
+
+ }
+
/**
* Controls the blinking of the caret.
*
@@ -294,12 +325,29 @@ public class DefaultCaret extends Rectangle
private BlinkTimerListener blinkListener;
/**
+ * A <code>NavigationFilter.FilterBypass</code> instance which
+ * is provided to the a <code>NavigationFilter</code> to
+ * unconditionally set or move the caret.
+ */
+ NavigationFilter.FilterBypass bypass;
+
+ /**
* Creates a new <code>DefaultCaret</code> instance.
*/
public DefaultCaret()
{
// Nothing to do here.
}
+
+ /** Returns the caret's <code>NavigationFilter.FilterBypass</code> instance
+ * and creates it if it does not yet exist.
+ *
+ * @return The caret's <code>NavigationFilter.FilterBypass</code> instance.
+ */
+ private NavigationFilter.FilterBypass getBypass()
+ {
+ return (bypass == null) ? bypass = new Bypass() : bypass;
+ }
/**
* Sets the Caret update policy.
@@ -346,7 +394,8 @@ public class DefaultCaret extends Rectangle
*/
public void mouseDragged(MouseEvent event)
{
- moveCaret(event);
+ if (event.getButton() == MouseEvent.BUTTON1)
+ moveCaret(event);
}
/**
@@ -379,7 +428,7 @@ public class DefaultCaret extends Rectangle
{
int count = event.getClickCount();
- if (count >= 2)
+ if (event.getButton() == MouseEvent.BUTTON1 && count >= 2)
{
int newDot = getComponent().viewToModel(event.getPoint());
JTextComponent t = getComponent();
@@ -387,29 +436,42 @@ public class DefaultCaret extends Rectangle
try
{
if (count == 3)
- t.select(Utilities.getRowStart(t, newDot), Utilities.getRowEnd(t, newDot));
+ {
+ setDot(Utilities.getRowStart(t, newDot));
+ moveDot( Utilities.getRowEnd(t, newDot));
+ }
else
{
- int nextWord = Utilities.getNextWord(t, newDot);
+ int wordStart = Utilities.getWordStart(t, newDot);
// When the mouse points at the offset of the first character
// in a word Utilities().getPreviousWord will not return that
// word but we want to select that. We have to use
- // Utilities.nextWord() to get it.
- if (newDot == nextWord)
- t.select(nextWord, Utilities.getNextWord(t, nextWord));
+ // Utilities.getWordStart() to get it.
+ if (newDot == wordStart)
+ {
+ setDot(wordStart);
+ moveDot(Utilities.getWordEnd(t, wordStart));
+ }
else
{
+ int nextWord = Utilities.getNextWord(t, newDot);
int previousWord = Utilities.getPreviousWord(t, newDot);
int previousWordEnd = Utilities.getWordEnd(t, previousWord);
// If the user clicked in the space between two words,
// then select the space.
if (newDot >= previousWordEnd && newDot <= nextWord)
- t.select(previousWordEnd, nextWord);
+ {
+ setDot(previousWordEnd);
+ moveDot(nextWord);
+ }
// Otherwise select the word under the mouse pointer.
else
- t.select(previousWord, previousWordEnd);
+ {
+ setDot(previousWord);
+ moveDot(previousWordEnd);
+ }
}
}
}
@@ -417,8 +479,6 @@ public class DefaultCaret extends Rectangle
{
// TODO: Swallowing ok here?
}
-
- dot = newDot;
}
}
@@ -455,10 +515,35 @@ public class DefaultCaret extends Rectangle
*/
public void mousePressed(MouseEvent event)
{
- if (event.isShiftDown())
- moveCaret(event);
- else
- positionCaret(event);
+ int button = event.getButton();
+
+ // The implementation assumes that consuming the event makes the AWT event
+ // mechanism forget about this event instance and not transfer focus.
+ // By observing how the RI reacts the following behavior has been
+ // implemented (in regard to text components):
+ // - a left-click moves the caret
+ // - a left-click when shift is held down expands the selection
+ // - a right-click or click with any additionaly mouse button
+ // on a text component is ignored
+ // - a middle-click positions the caret and pastes the clipboard
+ // contents.
+ // - a middle-click when shift is held down is ignored
+
+ if (button == MouseEvent.BUTTON1)
+ if (event.isShiftDown())
+ moveCaret(event);
+ else
+ positionCaret(event);
+ else if(button == MouseEvent.BUTTON2)
+ if (event.isShiftDown())
+ event.consume();
+ else
+ {
+ positionCaret(event);
+ textComponent.paste();
+ }
+ else
+ event.consume();
}
/**
@@ -636,10 +721,13 @@ public class DefaultCaret extends Rectangle
{
try
{
- if (highlightEntry == null)
- highlightEntry = highlighter.addHighlight(0, 0, getSelectionPainter());
- else
+ if (highlightEntry != null)
highlighter.changeHighlight(highlightEntry, 0, 0);
+
+ // Free the global variable which stores the text component with an active
+ // selection.
+ if (componentWithSelection == textComponent)
+ componentWithSelection = null;
}
catch (BadLocationException e)
{
@@ -675,6 +763,17 @@ public class DefaultCaret extends Rectangle
highlightEntry = highlighter.addHighlight(p0, p1, getSelectionPainter());
else
highlighter.changeHighlight(highlightEntry, p0, p1);
+
+ // If another component currently has a text selection clear that selection
+ // first.
+ if (componentWithSelection != null)
+ if (componentWithSelection != textComponent)
+ {
+ Caret c = componentWithSelection.getCaret();
+ c.setDot(c.getDot());
+ }
+ componentWithSelection = textComponent;
+
}
catch (BadLocationException e)
{
@@ -776,7 +875,7 @@ public class DefaultCaret extends Rectangle
if (visible)
{
g.setColor(textComponent.getCaretColor());
- g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height);
+ g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height - 1);
}
}
@@ -888,12 +987,24 @@ public class DefaultCaret extends Rectangle
* Moves the <code>dot</code> location without touching the
* <code>mark</code>. This is used when making a selection.
*
+ * <p>If the underlying text component has a {@link NavigationFilter}
+ * installed the caret will call the corresponding method of that object.</p>
+ *
* @param dot the location where to move the dot
*
* @see #setDot(int)
*/
public void moveDot(int dot)
{
+ NavigationFilter filter = textComponent.getNavigationFilter();
+ if (filter != null)
+ filter.moveDot(getBypass(), dot, Bias.Forward);
+ else
+ moveDotImpl(dot);
+ }
+
+ void moveDotImpl(int dot)
+ {
if (dot >= 0)
{
Document doc = textComponent.getDocument();
@@ -902,8 +1013,8 @@ public class DefaultCaret extends Rectangle
this.dot = Math.max(this.dot, 0);
handleHighlight();
- adjustVisibility(this);
appear();
+ adjustVisibility(this);
}
}
@@ -912,12 +1023,24 @@ public class DefaultCaret extends Rectangle
* <code>Document</code>. This also sets the <code>mark</code> to the new
* location.
*
+ * <p>If the underlying text component has a {@link NavigationFilter}
+ * installed the caret will call the corresponding method of that object.</p>
+ *
* @param dot
* the new position to be set
* @see #moveDot(int)
*/
public void setDot(int dot)
{
+ NavigationFilter filter = textComponent.getNavigationFilter();
+ if (filter != null)
+ filter.setDot(getBypass(), dot, Bias.Forward);
+ else
+ setDotImpl(dot);
+ }
+
+ void setDotImpl(int dot)
+ {
if (dot >= 0)
{
Document doc = textComponent.getDocument();
@@ -927,8 +1050,8 @@ public class DefaultCaret extends Rectangle
this.mark = this.dot;
clearHighlight();
- adjustVisibility(this);
appear();
+ adjustVisibility(this);
}
}
@@ -1043,7 +1166,16 @@ public class DefaultCaret extends Rectangle
// 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();
+ try
+ {
+ height = textComponent.modelToView(dot).height;
+ }
+ catch (BadLocationException ble)
+ {
+ // Should not happen.
+ throw new InternalError("Caret location not within document range.");
+ }
+
repaint();
}
@@ -1068,4 +1200,5 @@ public class DefaultCaret extends Rectangle
blinkTimer = new Timer(getBlinkRate(), blinkListener);
blinkTimer.setRepeats(true);
}
+
}
diff --git a/libjava/classpath/javax/swing/text/DefaultEditorKit.java b/libjava/classpath/javax/swing/text/DefaultEditorKit.java
index c005696..1b68618 100644
--- a/libjava/classpath/javax/swing/text/DefaultEditorKit.java
+++ b/libjava/classpath/javax/swing/text/DefaultEditorKit.java
@@ -63,6 +63,663 @@ import javax.swing.Action;
*/
public class DefaultEditorKit extends EditorKit
{
+ static class SelectionPreviousWordAction
+ extends TextAction
+ {
+ SelectionPreviousWordAction()
+ {
+ super(selectionPreviousWordAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ try
+ {
+ JTextComponent t = getTextComponent(event);
+
+ if (t != null)
+ {
+ int offs = Utilities.getPreviousWord(t, t.getCaretPosition());
+
+ Caret c = t.getCaret();
+ c.moveDot(offs);
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class SelectionNextWordAction
+ extends TextAction
+ {
+ SelectionNextWordAction()
+ {
+ super(selectionNextWordAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ try
+ {
+ JTextComponent t = getTextComponent(event);
+
+ if (t != null)
+ {
+ int offs = Utilities.getNextWord(t, t.getCaretPosition());
+
+ Caret c = t.getCaret();
+ c.moveDot(offs);
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class PreviousWordAction
+ extends TextAction
+ {
+ PreviousWordAction()
+ {
+ super(previousWordAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ try
+ {
+ JTextComponent t = getTextComponent(event);
+
+ if (t != null)
+ {
+ int offs = Utilities.getPreviousWord(t, t.getCaretPosition());
+
+ Caret c = t.getCaret();
+ c.setDot(offs);
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class NextWordAction
+ extends TextAction
+ {
+ NextWordAction()
+ {
+ super(nextWordAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ try
+ {
+ JTextComponent t = getTextComponent(event);
+
+ if (t != null)
+ {
+ int offs = Utilities.getNextWord(t, t.getCaretPosition());
+
+ Caret c = t.getCaret();
+ c.setDot(offs);
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class SelectAllAction
+ extends TextAction
+ {
+ SelectAllAction()
+ {
+ super(selectAllAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ int offs = t.getDocument().getLength();
+ Caret c = t.getCaret();
+ c.setDot(0);
+ c.moveDot(offs);
+
+ try
+ {
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class SelectionBeginAction
+ extends TextAction
+ {
+ SelectionBeginAction()
+ {
+ super(selectionBeginAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ Caret c = t.getCaret();
+ c.moveDot(0);
+ try
+ {
+ c.setMagicCaretPosition(t.modelToView(0).getLocation());
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class SelectionEndAction
+ extends TextAction
+ {
+ SelectionEndAction()
+ {
+ super(selectionEndAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ int offs = t.getDocument().getLength();
+ Caret c = t.getCaret();
+ c.moveDot(offs);
+ try
+ {
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class SelectionEndLineAction
+ extends TextAction
+ {
+ SelectionEndLineAction()
+ {
+ super(selectionEndLineAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ try
+ {
+ Point p = t.modelToView(t.getCaret().getDot()).getLocation();
+ int cur = t.getCaretPosition();
+ int y = p.y;
+ int length = t.getDocument().getLength();
+ while (y == p.y && cur < length)
+ y = t.modelToView(++cur).getLocation().y;
+ if (cur != length)
+ cur--;
+
+ Caret c = t.getCaret();
+ c.moveDot(cur);
+ c.setMagicCaretPosition(t.modelToView(cur).getLocation());
+ }
+ catch (BadLocationException ble)
+ {
+ // Nothing to do here
+ }
+ }
+ }
+
+ static class SelectionBeginLineAction
+ extends TextAction
+ {
+ SelectionBeginLineAction()
+ {
+ super(selectionBeginLineAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+
+ try
+ {
+ // TODO: There is a more efficent solution, but
+ // viewToModel doesn't work properly.
+ Point p = t.modelToView(t.getCaret().getDot()).getLocation();
+
+ int cur = t.getCaretPosition();
+ int y = p.y;
+
+ while (y == p.y && cur > 0)
+ y = t.modelToView(--cur).getLocation().y;
+ if (cur != 0)
+ cur++;
+
+ Caret c = t.getCaret();
+ c.moveDot(cur);
+ c.setMagicCaretPosition(t.modelToView(cur).getLocation());
+ }
+ catch (BadLocationException ble)
+ {
+ // Do nothing here.
+ }
+ }
+ }
+
+ static class SelectionDownAction
+ extends TextAction
+ {
+ SelectionDownAction()
+ {
+ super(selectionDownAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ try
+ {
+ if (t != null)
+ {
+ Caret c = t.getCaret();
+ // The magic caret position may be null when the caret
+ // has not moved yet.
+ Point mcp = c.getMagicCaretPosition();
+ int x = (mcp != null) ? mcp.x : 0;
+ int pos = Utilities.getPositionBelow(t, t.getCaretPosition(), x);
+
+ if (pos > -1)
+ t.moveCaretPosition(pos);
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // FIXME: Swallowing allowed?
+ }
+ }
+ }
+
+ static class SelectionUpAction
+ extends TextAction
+ {
+ SelectionUpAction()
+ {
+ super(selectionUpAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ try
+ {
+ if (t != null)
+ {
+ Caret c = t.getCaret();
+ // The magic caret position may be null when the caret
+ // has not moved yet.
+ Point mcp = c.getMagicCaretPosition();
+ int x = (mcp != null) ? mcp.x : 0;
+ int pos = Utilities.getPositionAbove(t, t.getCaretPosition(), x);
+
+ if (pos > -1)
+ t.moveCaretPosition(pos);
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // FIXME: Swallowing allowed?
+ }
+ }
+ }
+
+ static class SelectionForwardAction
+ extends TextAction
+ {
+ SelectionForwardAction()
+ {
+ super(selectionForwardAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ int offs = t.getCaretPosition() + 1;
+
+ if(offs <= t.getDocument().getLength())
+ {
+ Caret c = t.getCaret();
+ c.moveDot(offs);
+ try
+ {
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+ }
+ }
+
+ static class SelectionBackwardAction
+ extends TextAction
+ {
+ SelectionBackwardAction()
+ {
+ super(selectionBackwardAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ int offs = t.getCaretPosition() - 1;
+
+ if(offs >= 0)
+ {
+ Caret c = t.getCaret();
+ c.moveDot(offs);
+ try
+ {
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+ }
+ }
+
+ static class DownAction
+ extends TextAction
+ {
+ DownAction()
+ {
+ super(downAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ try
+ {
+ if (t != null)
+ {
+ Caret c = t.getCaret();
+ // The magic caret position may be null when the caret
+ // has not moved yet.
+ Point mcp = c.getMagicCaretPosition();
+ int x = (mcp != null) ? mcp.x : 0;
+ int pos = Utilities.getPositionBelow(t, t.getCaretPosition(), x);
+
+ if (pos > -1)
+ t.setCaretPosition(pos);
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // FIXME: Swallowing allowed?
+ }
+ }
+ }
+
+ static class UpAction
+ extends TextAction
+ {
+ UpAction()
+ {
+ super(upAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ try
+ {
+ if (t != null)
+ {
+ Caret c = t.getCaret();
+ // The magic caret position may be null when the caret
+ // has not moved yet.
+ Point mcp = c.getMagicCaretPosition();
+ int x = (mcp != null) ? mcp.x : 0;
+ int pos = Utilities.getPositionAbove(t, t.getCaretPosition(), x);
+
+ if (pos > -1)
+ t.setCaretPosition(pos);
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // FIXME: Swallowing allowed?
+ }
+ }
+ }
+
+ static class ForwardAction
+ extends TextAction
+ {
+ ForwardAction()
+ {
+ super(forwardAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ int offs = t.getCaretPosition() + 1;
+ if (offs <= t.getDocument().getLength())
+ {
+ Caret c = t.getCaret();
+ c.setDot(offs);
+
+ try
+ {
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ catch (BadLocationException ble)
+ {
+ // Should not happen.
+ }
+ }
+ }
+
+ }
+ }
+
+ static class BackwardAction
+ extends TextAction
+ {
+ BackwardAction()
+ {
+ super(backwardAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ int offs = t.getCaretPosition() - 1;
+ if (offs >= 0)
+ {
+ Caret c = t.getCaret();
+ c.setDot(offs);
+
+ try
+ {
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ catch (BadLocationException ble)
+ {
+ // Should not happen.
+ }
+ }
+ }
+ }
+ }
+
+ static class DeletePrevCharAction
+ extends TextAction
+ {
+ DeletePrevCharAction()
+ {
+ super(deletePrevCharAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ try
+ {
+ int pos = t.getSelectionStart();
+ int len = t.getSelectionEnd() - pos;
+
+ if (len > 0)
+ t.getDocument().remove(pos, len);
+ else if (pos > 0)
+ {
+ pos--;
+ t.getDocument().remove(pos, 1);
+ Caret c = t.getCaret();
+ c.setDot(pos);
+ c.setMagicCaretPosition(t.modelToView(pos).getLocation());
+ }
+ }
+ catch (BadLocationException e)
+ {
+ // FIXME: we're not authorized to throw this.. swallow it?
+ }
+ }
+ }
+ }
+
+ static class DeleteNextCharAction
+ extends TextAction
+ {
+ DeleteNextCharAction()
+ {
+ super(deleteNextCharAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ try
+ {
+ int pos = t.getSelectionStart();
+ int len = t.getSelectionEnd() - pos;
+
+ if (len > 0)
+ t.getDocument().remove(pos, len);
+ else if (pos < t.getDocument().getLength())
+ t.getDocument().remove(pos, 1);
+
+ Caret c = t.getCaret();
+ c.setDot(pos);
+ c.setMagicCaretPosition(t.modelToView(pos).getLocation());
+ }
+ catch (BadLocationException e)
+ {
+ // FIXME: we're not authorized to throw this.. swallow it?
+ }
+ }
+ }
+ }
+
+ static class EndLineAction
+ extends TextAction
+ {
+ EndLineAction()
+ {
+ super(endLineAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ try
+ {
+ int offs = Utilities.getRowEnd(t, t.getCaretPosition());
+
+ if (offs > -1)
+ {
+ Caret c = t.getCaret();
+ c.setDot(offs);
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch (BadLocationException ble)
+ {
+ // Nothing to do here
+ }
+ }
+ }
+
+ static class BeginLineAction
+ extends TextAction
+ {
+ BeginLineAction()
+ {
+ super(beginLineAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ try
+ {
+ int offs = Utilities.getRowStart(t, t.getCaretPosition());
+
+ if (offs > -1)
+ {
+ Caret c = t.getCaret();
+ c.setDot(offs);
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch (BadLocationException ble)
+ {
+ // Do nothing here.
+ }
+ }
+ }
+
/**
* Creates a beep on the PC speaker.
*
@@ -692,6 +1349,7 @@ public class DefaultEditorKit extends EditorKit
// to handle this.
private static Action[] defaultActions =
new Action[] {
+ // These classes are public because they are so in the RI.
new BeepAction(),
new CopyAction(),
new CutAction(),
@@ -700,404 +1358,38 @@ public class DefaultEditorKit extends EditorKit
new InsertContentAction(),
new InsertTabAction(),
new PasteAction(),
- new TextAction(beginLineAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- try
- {
- int offs = Utilities.getRowStart(t, t.getCaretPosition());
-
- if (offs > -1)
- {
- Caret c = t.getCaret();
- c.setDot(offs);
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- }
- catch (BadLocationException ble)
- {
- // Do nothing here.
- }
- }
- },
- new TextAction(endLineAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- try
- {
- int offs = Utilities.getRowEnd(t, t.getCaretPosition());
-
- if (offs > -1)
- {
- Caret c = t.getCaret();
- c.setDot(offs);
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- }
- catch (BadLocationException ble)
- {
- // Nothing to do here
- }
- }
- },
- new TextAction(deleteNextCharAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- if (t != null)
- {
- try
- {
- int pos = t.getSelectionStart();
- int len = t.getSelectionEnd() - pos;
-
- if (len > 0)
- t.getDocument().remove(pos, len);
- else if (pos < t.getDocument().getLength())
- t.getDocument().remove(pos, 1);
-
- Caret c = t.getCaret();
- c.setDot(pos);
- c.setMagicCaretPosition(t.modelToView(pos).getLocation());
- }
- catch (BadLocationException e)
- {
- // FIXME: we're not authorized to throw this.. swallow it?
- }
- }
- }
- },
- new TextAction(deletePrevCharAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- if (t != null)
- {
- try
- {
- int pos = t.getSelectionStart();
- int len = t.getSelectionEnd() - pos;
-
- if (len > 0)
- t.getDocument().remove(pos, len);
- else if (pos > 0)
- {
- pos--;
- t.getDocument().remove(pos, 1);
- Caret c = t.getCaret();
- c.setDot(pos);
- c.setMagicCaretPosition(t.modelToView(pos).getLocation());
- }
- }
- catch (BadLocationException e)
- {
- // FIXME: we're not authorized to throw this.. swallow it?
- }
- }
- }
- },
- new TextAction(backwardAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- if (t != null)
- {
- int offs = t.getCaretPosition() - 1;
- if (offs >= 0)
- {
- Caret c = t.getCaret();
- c.setDot(offs);
-
- try
- {
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- catch (BadLocationException ble)
- {
- // Should not happen.
- }
- }
- }
- }
- },
- new TextAction(forwardAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- if (t != null)
- {
- int offs = t.getCaretPosition() + 1;
- if (offs <= t.getDocument().getLength())
- {
- Caret c = t.getCaret();
- c.setDot(offs);
-
- try
- {
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- catch (BadLocationException ble)
- {
- // Should not happen.
- }
- }
- }
-
- }
- },
- new TextAction(upAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- try
- {
- if (t != null)
- {
- Caret c = t.getCaret();
- // The magic caret position may be null when the caret
- // has not moved yet.
- Point mcp = c.getMagicCaretPosition();
- int x = (mcp != null) ? mcp.x : 0;
- int pos = Utilities.getPositionAbove(t, t.getCaretPosition(), x);
-
- if (pos > -1)
- t.setCaretPosition(pos);
- }
- }
- catch(BadLocationException ble)
- {
- // FIXME: Swallowing allowed?
- }
- }
- },
- new TextAction(downAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- try
- {
- if (t != null)
- {
- Caret c = t.getCaret();
- // The magic caret position may be null when the caret
- // has not moved yet.
- Point mcp = c.getMagicCaretPosition();
- int x = (mcp != null) ? mcp.x : 0;
- int pos = Utilities.getPositionBelow(t, t.getCaretPosition(), x);
-
- if (pos > -1)
- t.setCaretPosition(pos);
- }
- }
- catch(BadLocationException ble)
- {
- // FIXME: Swallowing allowed?
- }
- }
- },
- new TextAction(selectionBackwardAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- if (t != null)
- {
- int offs = t.getCaretPosition() - 1;
-
- if(offs >= 0)
- {
- Caret c = t.getCaret();
- c.moveDot(offs);
- try
- {
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- catch(BadLocationException ble)
- {
- // Can't happen.
- }
- }
- }
- }
- },
- new TextAction(selectionForwardAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- if (t != null)
- {
- int offs = t.getCaretPosition() + 1;
-
- if(offs <= t.getDocument().getLength())
- {
- Caret c = t.getCaret();
- c.moveDot(offs);
- try
- {
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- catch(BadLocationException ble)
- {
- // Can't happen.
- }
- }
- }
- }
- },
- new TextAction(selectionUpAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- try
- {
- if (t != null)
- {
- Caret c = t.getCaret();
- // The magic caret position may be null when the caret
- // has not moved yet.
- Point mcp = c.getMagicCaretPosition();
- int x = (mcp != null) ? mcp.x : 0;
- int pos = Utilities.getPositionAbove(t, t.getCaretPosition(), x);
-
- if (pos > -1)
- t.moveCaretPosition(pos);
- }
- }
- catch(BadLocationException ble)
- {
- // FIXME: Swallowing allowed?
- }
- }
- },
- new TextAction(selectionDownAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- try
- {
- if (t != null)
- {
- Caret c = t.getCaret();
- // The magic caret position may be null when the caret
- // has not moved yet.
- Point mcp = c.getMagicCaretPosition();
- int x = (mcp != null) ? mcp.x : 0;
- int pos = Utilities.getPositionBelow(t, t.getCaretPosition(), x);
-
- if (pos > -1)
- t.moveCaretPosition(pos);
- }
- }
- catch(BadLocationException ble)
- {
- // FIXME: Swallowing allowed?
- }
- }
- },
- new TextAction(selectionBeginLineAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
-
- try
- {
- // TODO: There is a more efficent solution, but
- // viewToModel doesn't work properly.
- Point p = t.modelToView(t.getCaret().getDot()).getLocation();
-
- int cur = t.getCaretPosition();
- int y = p.y;
-
- while (y == p.y && cur > 0)
- y = t.modelToView(--cur).getLocation().y;
- if (cur != 0)
- cur++;
-
- Caret c = t.getCaret();
- c.moveDot(cur);
- c.setMagicCaretPosition(t.modelToView(cur).getLocation());
- }
- catch (BadLocationException ble)
- {
- // Do nothing here.
- }
- }
- },
- new TextAction(selectionEndLineAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- try
- {
- Point p = t.modelToView(t.getCaret().getDot()).getLocation();
- int cur = t.getCaretPosition();
- int y = p.y;
- int length = t.getDocument().getLength();
- while (y == p.y && cur < length)
- y = t.modelToView(++cur).getLocation().y;
- if (cur != length)
- cur--;
-
- Caret c = t.getCaret();
- c.moveDot(cur);
- c.setMagicCaretPosition(t.modelToView(cur).getLocation());
- }
- catch (BadLocationException ble)
- {
- // Nothing to do here
- }
- }
- },
- new TextAction(selectionEndAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- int offs = t.getDocument().getLength();
- Caret c = t.getCaret();
- c.moveDot(offs);
- try
- {
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- catch(BadLocationException ble)
- {
- // Can't happen.
- }
- }
- },
- new TextAction(selectionBeginAction)
- {
- public void actionPerformed(ActionEvent event)
- {
- JTextComponent t = getTextComponent(event);
- Caret c = t.getCaret();
- c.moveDot(0);
- try
- {
- c.setMagicCaretPosition(t.modelToView(0).getLocation());
- }
- catch(BadLocationException ble)
- {
- // Can't happen.
- }
- }
- }
+
+ // These are (package-)private inner classes.
+ new DeleteNextCharAction(),
+ new DeletePrevCharAction(),
+
+ new BeginLineAction(),
+ new SelectionBeginLineAction(),
+
+ new EndLineAction(),
+ new SelectionEndLineAction(),
+
+ new BackwardAction(),
+ new SelectionBackwardAction(),
+
+ new ForwardAction(),
+ new SelectionForwardAction(),
+
+ new UpAction(),
+ new SelectionUpAction(),
+
+ new DownAction(),
+ new SelectionDownAction(),
+
+ new NextWordAction(),
+ new SelectionNextWordAction(),
+
+ new PreviousWordAction(),
+ new SelectionPreviousWordAction(),
+
+ new SelectionBeginAction(),
+ new SelectionEndAction(),
+ new SelectAllAction(),
};
/**
diff --git a/libjava/classpath/javax/swing/text/DefaultHighlighter.java b/libjava/classpath/javax/swing/text/DefaultHighlighter.java
index 33b5fca..59f7731 100644
--- a/libjava/classpath/javax/swing/text/DefaultHighlighter.java
+++ b/libjava/classpath/javax/swing/text/DefaultHighlighter.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.text;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
@@ -45,6 +47,7 @@ import java.awt.Rectangle;
import java.awt.Shape;
import java.util.ArrayList;
+import javax.swing.SwingUtilities;
import javax.swing.plaf.TextUI;
public class DefaultHighlighter extends LayeredHighlighter
@@ -71,60 +74,102 @@ public class DefaultHighlighter extends LayeredHighlighter
}
public void paint(Graphics g, int p0, int p1, Shape bounds,
- JTextComponent c)
+ JTextComponent t)
{
- Rectangle r0 = null;
- Rectangle r1 = null;
- Rectangle rect = bounds.getBounds();
-
- try
- {
- r0 = c.modelToView(p0);
- r1 = c.modelToView(p1);
- }
- catch (BadLocationException e)
- {
- // This should never occur.
- return;
- }
+ if (p0 == p1)
+ return;
- if (r0 == null || r1 == null)
- return;
+ Rectangle rect = bounds.getBounds();
if (color == null)
- g.setColor(c.getSelectionColor());
+ g.setColor(t.getSelectionColor());
else
- g.setColor(color);
-
- // Check if only one line to highlight.
- if (r0.y == r1.y)
- {
- r0.width = r1.x - r0.x;
- paintHighlight(g, r0);
- return;
- }
-
- // First line, from p0 to end-of-line.
- r0.width = rect.x + rect.width - r0.x;
- paintHighlight(g, r0);
-
- // FIXME: All the full lines in between, if any (assumes that all lines
- // have the same height -- not a good assumption with JEditorPane/JTextPane).
- r0.y += r0.height;
- r0.x = rect.x;
- r0.width = rect.width;
+ g.setColor(color);
+
+ TextUI ui = t.getUI();
- while (r0.y < r1.y)
- {
- paintHighlight(g, r0);
- r0.y += r0.height;
- }
-
- // Last line, from beginning-of-line to p1.
- // The "-1" is neccessary else we would paint one pixel column more
- // than in the case where the selection is only on one line.
- r0.width = r1.x + r1.width - 1;
- paintHighlight(g, r0);
+ try
+ {
+
+ Rectangle l0 = ui.modelToView(t, p0, null);
+ Rectangle l1 = ui.modelToView(t, p1, null);
+
+ // Note: The computed locations may lie outside of the allocation
+ // area if the text is scrolled.
+
+ if (l0.y == l1.y)
+ {
+ SwingUtilities.computeUnion(l0.x, l0.y, l0.width, l0.height, l1);
+
+ // Paint only inside the allocation area.
+ SwingUtilities.computeIntersection(rect.x, rect.y, rect.width, rect.height, l1);
+
+ paintHighlight(g, l1);
+ }
+ else
+ {
+ // 1. The line of p0 is painted from the position of p0
+ // to the right border.
+ // 2. All lines between the ones where p0 and p1 lie on
+ // are completely highlighted. The allocation area is used to find
+ // out the bounds.
+ // 3. The final line is painted from the left border to the
+ // position of p1.
+
+ // Highlight first line until the end.
+ // If rect.x is non-zero the calculation will properly adjust the
+ // area to be painted.
+ l0.x -= rect.x;
+ l0.width = rect.width - l0.x - rect.x;
+
+ paintHighlight(g, l0);
+
+ int posBelow = Utilities.getPositionBelow(t, p0, l0.x);
+ int p1RowStart = Utilities.getRowStart(t, p1);
+ if (posBelow != -1
+ && posBelow != p0
+ && Utilities.getRowStart(t, posBelow)
+ != p1RowStart)
+ {
+ Rectangle grow = ui.modelToView(t, posBelow);
+ grow.x = rect.x;
+ grow.width = rect.width;
+
+ // Find further lines which have to be highlighted completely.
+ int nextPosBelow = posBelow;
+ while (nextPosBelow != -1
+ && Utilities.getRowStart(t, nextPosBelow) != p1RowStart)
+ {
+ posBelow = nextPosBelow;
+ nextPosBelow = Utilities.getPositionBelow(t, posBelow, l0.x);
+
+ if (nextPosBelow == posBelow)
+ break;
+ }
+ // Now posBelow is an offset on the last line which has to be painted
+ // 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 = ui.modelToView(t, posBelow);
+ grow.height = end.y + end.height - grow.y;
+
+ paintHighlight(g, grow);
+ }
+
+ // Paint last line from its beginning to the position of p1.
+ l1.width = l1.x + l1.width - rect.x;
+ l1.x = rect.x;
+ paintHighlight(g, l1);
+ }
+ }
+ catch (BadLocationException ex)
+ {
+ AssertionError err = new AssertionError("Unexpected bad location exception");
+ err.initCause(ex);
+ throw err;
+ }
}
public Shape paintLayer(Graphics g, int p0, int p1, Shape bounds,
@@ -330,6 +375,7 @@ public class DefaultHighlighter extends LayeredHighlighter
public void paintLayeredHighlights(Graphics g, int p0, int p1,
Shape viewBounds, JTextComponent editor,
View view)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/libjava/classpath/javax/swing/text/FieldView.java b/libjava/classpath/javax/swing/text/FieldView.java
index 2496418..0c2f0fe 100644
--- a/libjava/classpath/javax/swing/text/FieldView.java
+++ b/libjava/classpath/javax/swing/text/FieldView.java
@@ -1,5 +1,5 @@
/* FieldView.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,20 +39,86 @@ exception statement from your version. */
package javax.swing.text;
import java.awt.Component;
-import java.awt.ComponentOrientation;
+import java.awt.Container;
import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Shape;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.BoundedRangeModel;
import javax.swing.JTextField;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
public class FieldView extends PlainView
{
+ BoundedRangeModel horizontalVisibility;
+
+ /** Caches the preferred span of the X axis. It is invalidated by
+ * setting it to -1f. This is done when text in the document
+ * is inserted, removed or changed. The value is corrected as
+ * soon as calculateHorizontalSpan() is called.
+ */
+ float cachedSpan = -1f;
+
public FieldView(Element elem)
{
super(elem);
+
+ }
+
+ /** Checks whether the given container is a JTextField. If so
+ * it retrieves the textfield's horizontalVisibility instance.
+ *
+ * <p>This method should be only called when the view's container
+ * is valid. Naturally that would be the setParent() method however
+ * that method is not overridden in the RI and that is why we chose
+ * paint() instead.</p>
+ */
+ private void checkContainer()
+ {
+ Container c = getContainer();
+
+ if (c instanceof JTextField)
+ {
+ horizontalVisibility = ((JTextField) c).getHorizontalVisibility();
+
+ // Provokes a repaint when the BoundedRangeModel's values change
+ // (which is what the RI does).
+ horizontalVisibility.addChangeListener(new ChangeListener(){
+ public void stateChanged(ChangeEvent event) {
+ getContainer().repaint();
+ };
+ });
+
+ // It turned out that the span calculated at this point is wrong
+ // and needs to be recalculated (e.g. a different font setting is
+ // not taken into account).
+ calculateHorizontalSpan();
+
+ // Initializes the BoundedRangeModel properly.
+ updateVisibility();
+ }
+
+ }
+
+ private void updateVisibility()
+ {
+ JTextField tf = (JTextField) getContainer();
+ Insets insets = tf.getInsets();
+
+ int width = tf.getWidth() - insets.left - insets.right;
+
+ horizontalVisibility.setMaximum(Math.max((int) ((cachedSpan != -1f)
+ ? cachedSpan
+ : calculateHorizontalSpan()),
+ width));
+
+ horizontalVisibility.setExtent(width - 1);
}
protected FontMetrics getFontMetrics()
@@ -72,41 +138,47 @@ public class FieldView extends PlainView
*/
protected Shape adjustAllocation(Shape shape)
{
+ // Return null when the original allocation is null (like the RI).
+ if (shape == null)
+ return null;
+
Rectangle rectIn = shape.getBounds();
// vertical adjustment
int height = (int) getPreferredSpan(Y_AXIS);
int y = rectIn.y + (rectIn.height - height) / 2;
// horizontal adjustment
JTextField textField = (JTextField) getContainer();
- int halign = textField.getHorizontalAlignment();
- int width = (int) getPreferredSpan(X_AXIS);
+ int width = (int) ((cachedSpan != -1f) ? cachedSpan : calculateHorizontalSpan());
int x;
- ComponentOrientation orientation = textField.getComponentOrientation();
- switch (halign)
- {
- case JTextField.CENTER:
- x = rectIn.x + (rectIn.width - width) / 2;
- break;
- case JTextField.RIGHT:
- x = rectIn.x + (rectIn.width - width);
- break;
- case JTextField.TRAILING:
- if (orientation.isLeftToRight())
- x = rectIn.x + (rectIn.width - width);
- else
- x = rectIn.x;
- break;
- case JTextField.LEADING:
- if (orientation.isLeftToRight())
+ if (horizontalVisibility != null && horizontalVisibility.getExtent() < width)
+ x = rectIn.x - horizontalVisibility.getValue();
+ else
+ switch (textField.getHorizontalAlignment())
+ {
+ case JTextField.CENTER:
+ x = rectIn.x + (rectIn.width - width) / 2;
+ break;
+ case JTextField.RIGHT:
+ x = rectIn.x + (rectIn.width - width - 1);
+ break;
+ case JTextField.TRAILING:
+ if (textField.getComponentOrientation().isLeftToRight())
+ x = rectIn.x + (rectIn.width - width - 1);
+ else
+ x = rectIn.x;
+ break;
+ case JTextField.LEADING:
+ if (textField.getComponentOrientation().isLeftToRight())
+ x = rectIn.x;
+ else
+ x = rectIn.x + (rectIn.width - width - 1);
+ break;
+ case JTextField.LEFT:
+ default:
x = rectIn.x;
- else
- x = rectIn.x + (rectIn.width - width);
- break;
- case JTextField.LEFT:
- default:
- x = rectIn.x;
- break;
- }
+ break;
+ }
+
return new Rectangle(x, y, width, height);
}
@@ -115,18 +187,31 @@ public class FieldView extends PlainView
if (axis != X_AXIS && axis != Y_AXIS)
throw new IllegalArgumentException();
- FontMetrics fm = getFontMetrics();
if (axis == Y_AXIS)
return super.getPreferredSpan(axis);
- String text;
+ if (cachedSpan != -1f)
+ return cachedSpan;
+
+ return calculateHorizontalSpan();
+ }
+
+ /** Calculates and sets the horizontal span and stores the value
+ * in cachedSpan.
+ */
+ private float calculateHorizontalSpan()
+ {
+ Segment s = getLineBuffer();
Element elem = getElement();
try
{
- text = elem.getDocument().getText(elem.getStartOffset(),
- elem.getEndOffset());
+ elem.getDocument().getText(elem.getStartOffset(),
+ elem.getEndOffset() - 1,
+ s);
+
+ return cachedSpan = Utilities.getTabbedTextWidth(s, getFontMetrics(), 0, this, s.offset);
}
catch (BadLocationException e)
{
@@ -135,8 +220,6 @@ public class FieldView extends PlainView
ae.initCause(e);
throw ae;
}
-
- return fm.stringWidth(text);
}
public int getResizeWeight(int axis)
@@ -153,19 +236,39 @@ public class FieldView extends PlainView
public void paint(Graphics g, Shape s)
{
+ if (horizontalVisibility == null)
+ checkContainer();
+
Shape newAlloc = adjustAllocation(s);
+
+ // Set a clip to prevent drawing outside of the allocation area.
+ // TODO: Is there a better way to achieve this?
+ Shape clip = g.getClip();
+ g.setClip(s);
super.paint(g, newAlloc);
+ g.setClip(clip);
}
public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
{
+ cachedSpan = -1f;
+
+ if (horizontalVisibility != null)
+ updateVisibility();
+
Shape newAlloc = adjustAllocation(shape);
+
super.insertUpdate(ev, newAlloc, vf);
getContainer().repaint();
}
public void removeUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
{
+ cachedSpan = -1f;
+
+ if (horizontalVisibility != null)
+ updateVisibility();
+
Shape newAlloc = adjustAllocation(shape);
super.removeUpdate(ev, newAlloc, vf);
getContainer().repaint();
@@ -173,14 +276,19 @@ public class FieldView extends PlainView
public void changedUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
{
+ cachedSpan = -1f;
+
+ if (horizontalVisibility != null)
+ updateVisibility();
+
Shape newAlloc = adjustAllocation(shape);
- super.removeUpdate(ev, newAlloc, vf);
+ super.changedUpdate(ev, newAlloc, vf);
getContainer().repaint();
}
public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias)
{
- return super.viewToModel(fx, fy, a, bias);
+ return super.viewToModel(fx, fy, adjustAllocation(a), bias);
}
}
diff --git a/libjava/classpath/javax/swing/text/FlowView.java b/libjava/classpath/javax/swing/text/FlowView.java
index 8be8f41..8ca55d8 100644
--- a/libjava/classpath/javax/swing/text/FlowView.java
+++ b/libjava/classpath/javax/swing/text/FlowView.java
@@ -433,7 +433,7 @@ public abstract class FlowView extends BoxView
/**
* Loads the children of this view. The <code>FlowView</code> does not
* directly load its children. Instead it creates a logical view
- * (@{link #layoutPool}) which is filled by the logical child views.
+ * ({@link #layoutPool}) which is filled by the logical child views.
* The real children are created at layout time and each represent one
* row.
*
diff --git a/libjava/classpath/javax/swing/text/GapContent.java b/libjava/classpath/javax/swing/text/GapContent.java
index 28d1d6e..219accb 100644
--- a/libjava/classpath/javax/swing/text/GapContent.java
+++ b/libjava/classpath/javax/swing/text/GapContent.java
@@ -289,6 +289,7 @@ public class GapContent
*/
public GapContent(int size)
{
+ size = Math.max(size, 2);
buffer = (char[]) allocateArray(size);
gapStart = 1;
gapEnd = size;
@@ -351,7 +352,7 @@ public class GapContent
throw new BadLocationException("The where argument cannot be smaller"
+ " than the zero", where);
- if (where >= length)
+ if (where > length)
throw new BadLocationException("The where argument cannot be greater"
+ " than the content length", where);
@@ -375,14 +376,11 @@ public class GapContent
{
// check arguments
int length = length();
-
- if (where >= length)
- throw new BadLocationException("the where argument cannot be greater"
- + " than the content length", where);
- if ((where + nitems) > length)
+
+ if ((where + nitems) >= length)
throw new BadLocationException("where + nitems cannot be greater"
+ " than the content length", where + nitems);
-
+
String removedText = getString(where, nitems);
replace(where, nitems, null, 0);
@@ -439,6 +437,8 @@ public class GapContent
{
// check arguments
int length = length();
+ if (where < 0)
+ throw new BadLocationException("the where argument may not be below zero", where);
if (where >= length)
throw new BadLocationException("the where argument cannot be greater"
+ " than the content length", where);
@@ -642,6 +642,10 @@ public class GapContent
if (addItems != null)
{
System.arraycopy(addItems, 0, buffer, gapStart, addSize);
+
+
+ resetMarksAtZero();
+
gapStart += addSize;
}
}
diff --git a/libjava/classpath/javax/swing/text/InternationalFormatter.java b/libjava/classpath/javax/swing/text/InternationalFormatter.java
index ba3cffa..8db435c 100644
--- a/libjava/classpath/javax/swing/text/InternationalFormatter.java
+++ b/libjava/classpath/javax/swing/text/InternationalFormatter.java
@@ -350,7 +350,7 @@ public class InternationalFormatter
* There is no such method in the whole API! So we just call
* super.getActions here.
*/
- public Action[] getActions()
+ protected Action[] getActions()
{
return super.getActions();
}
diff --git a/libjava/classpath/javax/swing/text/JTextComponent.java b/libjava/classpath/javax/swing/text/JTextComponent.java
index 6b8348c..1103de9 100644
--- a/libjava/classpath/javax/swing/text/JTextComponent.java
+++ b/libjava/classpath/javax/swing/text/JTextComponent.java
@@ -1138,6 +1138,7 @@ public abstract class JTextComponent extends JComponent
setFocusable(true);
setEditable(true);
enableEvents(AWTEvent.KEY_EVENT_MASK);
+ setOpaque(true);
updateUI();
}
@@ -1190,6 +1191,7 @@ public abstract class JTextComponent extends JComponent
catch (BadLocationException e)
{
// This can never happen.
+ throw (InternalError) new InternalError().initCause(e);
}
}
diff --git a/libjava/classpath/javax/swing/text/PlainView.java b/libjava/classpath/javax/swing/text/PlainView.java
index 4bb3a8e..18818c0 100644
--- a/libjava/classpath/javax/swing/text/PlainView.java
+++ b/libjava/classpath/javax/swing/text/PlainView.java
@@ -59,6 +59,18 @@ public class PlainView extends View implements TabExpander
* The color that is used to draw disabled text fields.
*/
Color disabledColor;
+
+ /**
+ * While painting this is the textcomponent's current start index
+ * of the selection.
+ */
+ int selectionStart;
+
+ /**
+ * While painting this is the textcomponent's current end index
+ * of the selection.
+ */
+ int selectionEnd;
Font font;
@@ -150,12 +162,47 @@ public class PlainView extends View implements TabExpander
{
try
{
- metrics = g.getFontMetrics();
- // FIXME: Selected text are not drawn yet.
Element line = getElement().getElement(lineIndex);
- drawUnselectedText(g, x, y, line.getStartOffset(),
- line.getEndOffset() - 1);
- //drawSelectedText(g, , , , );
+ int startOffset = line.getStartOffset();
+ int endOffset = line.getEndOffset() - 1;
+
+ if (selectionStart <= startOffset)
+ // Selection starts before the line ...
+ if (selectionEnd <= startOffset)
+ {
+ // end ends before the line: Draw completely unselected text.
+ drawUnselectedText(g, x, y, startOffset, endOffset);
+ }
+ else if (selectionEnd <= endOffset)
+ {
+ // and ends within the line: First part is selected,
+ // second is not.
+ x = drawSelectedText(g, x, y, startOffset, selectionEnd);
+ drawUnselectedText(g, x, y, selectionEnd, endOffset);
+ }
+ else
+ // and ends behind the line: Draw completely selected text.
+ drawSelectedText(g, x, y, startOffset, endOffset);
+ else if (selectionStart < endOffset)
+ // Selection starts within the line ..
+ if (selectionEnd < endOffset)
+ {
+ // and ends within it: First part unselected, second part
+ // selected, third part unselected.
+ x = drawUnselectedText(g, x, y, startOffset, selectionStart);
+ x = drawSelectedText(g, x, y, selectionStart, selectionEnd);
+ drawUnselectedText(g, x, y, selectionEnd, endOffset);
+ }
+ else
+ {
+ // and ends behind the line: First part unselected, second
+ // part selected.
+ x = drawUnselectedText(g, x, y, startOffset, selectionStart);
+ drawSelectedText(g, x, y, selectionStart, endOffset);
+ }
+ else
+ // Selection is behind this line: Draw completely unselected text.
+ drawUnselectedText(g, x, y, startOffset, endOffset);
}
catch (BadLocationException e)
{
@@ -171,7 +218,7 @@ public class PlainView extends View implements TabExpander
g.setColor(selectedColor);
Segment segment = getLineBuffer();
getDocument().getText(p0, p1 - p0, segment);
- return Utilities.drawTabbedText(segment, x, y, g, this, 0);
+ return Utilities.drawTabbedText(segment, x, y, g, this, segment.offset);
}
/**
@@ -212,6 +259,8 @@ public class PlainView extends View implements TabExpander
selectedColor = textComponent.getSelectedTextColor();
unselectedColor = textComponent.getForeground();
disabledColor = textComponent.getDisabledTextColor();
+ selectionStart = textComponent.getSelectionStart();
+ selectionEnd = textComponent.getSelectionEnd();
Rectangle rect = s.getBounds();
@@ -219,11 +268,13 @@ public class PlainView extends View implements TabExpander
Document document = textComponent.getDocument();
Element root = document.getDefaultRootElement();
int y = rect.y + metrics.getAscent();
+ int height = metrics.getHeight();
- for (int i = 0; i < root.getElementCount(); i++)
+ int count = root.getElementCount();
+ for (int i = 0; i < count; i++)
{
drawLine(i, g, rect.x, y);
- y += metrics.getHeight();
+ y += height;
}
}
@@ -274,7 +325,7 @@ public class PlainView extends View implements TabExpander
{
Element child = el.getElement(i);
int start = child.getStartOffset();
- int end = child.getEndOffset();
+ int end = child.getEndOffset() - 1;
try
{
el.getDocument().getText(start, end - start, seg);
@@ -386,6 +437,11 @@ public class PlainView extends View implements TabExpander
*/
protected void updateDamage(DocumentEvent changes, Shape a, ViewFactory f)
{
+ // Return early and do no updates if the allocation area is null
+ // (like the RI).
+ if (a == null)
+ return;
+
float oldMaxLineLength = maxLineLength;
Rectangle alloc = a.getBounds();
Element el = getElement();
@@ -467,7 +523,7 @@ public class PlainView extends View implements TabExpander
{
Element child = newElements[i];
int start = child.getStartOffset();
- int end = child.getEndOffset();
+ int end = child.getEndOffset() - 1;
try
{
el.getDocument().getText(start, end - start, seg);
@@ -586,7 +642,7 @@ public class PlainView extends View implements TabExpander
* @returna {@link Segment} object, that can be used to fetch text from
* the document
*/
- protected Segment getLineBuffer()
+ protected final Segment getLineBuffer()
{
if (lineBuffer == null)
lineBuffer = new Segment();
diff --git a/libjava/classpath/javax/swing/text/Position.java b/libjava/classpath/javax/swing/text/Position.java
index a9d3d09..bb1449e 100644
--- a/libjava/classpath/javax/swing/text/Position.java
+++ b/libjava/classpath/javax/swing/text/Position.java
@@ -40,7 +40,7 @@ package javax.swing.text;
public interface Position
{
- static class Bias
+ static final class Bias
{
public static final Bias Backward = new Bias("backward");
public static final Bias Forward = new Bias("forward");
diff --git a/libjava/classpath/javax/swing/text/Segment.java b/libjava/classpath/javax/swing/text/Segment.java
index 875d996..d2364e0 100644
--- a/libjava/classpath/javax/swing/text/Segment.java
+++ b/libjava/classpath/javax/swing/text/Segment.java
@@ -245,7 +245,8 @@ public class Segment implements Cloneable, CharacterIterator
|| position > getEndIndex())
throw new IllegalArgumentException("position: " + position
+ ", beginIndex: " + getBeginIndex()
- + ", endIndex: " + getEndIndex());
+ + ", endIndex: " + getEndIndex()
+ + ", text: " + toString());
current = position;
@@ -264,7 +265,7 @@ public class Segment implements Cloneable, CharacterIterator
*/
public String toString()
{
- return new String(array, offset, count);
+ return (array != null) ? new String(array, offset, count) : "";
}
/**
diff --git a/libjava/classpath/javax/swing/text/StyleContext.java b/libjava/classpath/javax/swing/text/StyleContext.java
index e2643a2..8ef3440 100644
--- a/libjava/classpath/javax/swing/text/StyleContext.java
+++ b/libjava/classpath/javax/swing/text/StyleContext.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.text;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
@@ -711,35 +713,37 @@ public class StyleContext
// have left incomplete; I'm not sure I understand the intent properly.
public static Object getStaticAttribute(Object key)
+ throws NotImplementedException
{
throw new InternalError("not implemented");
}
public static Object getStaticAttributeKey(Object key)
+ throws NotImplementedException
{
throw new InternalError("not implemented");
}
public static void readAttributeSet(ObjectInputStream in, MutableAttributeSet a)
- throws ClassNotFoundException, IOException
+ throws ClassNotFoundException, IOException, NotImplementedException
{
throw new InternalError("not implemented");
}
public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
- throws IOException
+ throws IOException, NotImplementedException
{
throw new InternalError("not implemented");
}
public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
- throws ClassNotFoundException, IOException
+ throws ClassNotFoundException, IOException, NotImplementedException
{
throw new InternalError("not implemented");
}
public void writeAttributes(ObjectOutputStream out, AttributeSet a)
- throws IOException
+ throws IOException, NotImplementedException
{
throw new InternalError("not implemented");
}
diff --git a/libjava/classpath/javax/swing/text/Utilities.java b/libjava/classpath/javax/swing/text/Utilities.java
index d109a4a..f154e55 100644
--- a/libjava/classpath/javax/swing/text/Utilities.java
+++ b/libjava/classpath/javax/swing/text/Utilities.java
@@ -1,5 +1,5 @@
/* Utilities.java --
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,6 +48,7 @@ import java.text.BreakIterator;
* inside this package.
*
* @author Roman Kennke (roman@ontographics.com)
+ * @author Robert Schuster (robertschuster@fsfe.org)
*/
public class Utilities
{
@@ -99,8 +100,10 @@ public class Utilities
int pixelWidth = 0;
int pos = s.offset;
int len = 0;
+
+ int end = s.offset + s.count;
- for (int offset = s.offset; offset < (s.offset + s.count); ++offset)
+ for (int offset = s.offset; offset < end; ++offset)
{
char c = buffer[offset];
if (c == '\t' || c == '\n')
@@ -140,7 +143,7 @@ public class Utilities
if (len > 0)
g.drawChars(buffer, pos, len, pixelX, pixelY + ascent);
- return pixelX;
+ return pixelX + pixelWidth;
}
/**
@@ -236,35 +239,39 @@ public class Utilities
// At the end of the for loop, this holds the requested model location
int pos;
int currentX = x0;
-
+ int width = 0;
+
for (pos = 0; pos < s.count; pos++)
{
char nextChar = s.array[s.offset+pos];
if (nextChar == 0)
- {
- if (! round)
- pos--;
break;
- }
+
if (nextChar != '\t')
- currentX += fm.charWidth(nextChar);
+ width = fm.charWidth(nextChar);
else
{
if (te == null)
- currentX += fm.charWidth(' ');
+ width = fm.charWidth(' ');
else
- currentX = (int) te.nextTabStop(currentX, pos);
+ width = ((int) te.nextTabStop(currentX, pos)) - currentX;
}
- if (currentX > x)
+ if (round)
{
- if (! round)
- pos--;
- break;
+ if (currentX + (width>>1) > x)
+ break;
+ }
+ else
+ {
+ if (currentX + width > x)
+ break;
}
+
+ currentX += width;
}
-
+
return pos + p0;
}
@@ -315,21 +322,31 @@ public class Utilities
String text = c.getText();
BreakIterator wb = BreakIterator.getWordInstance();
wb.setText(text);
+
int last = wb.following(offs);
int current = wb.next();
+ int cp;
+
while (current != BreakIterator.DONE)
{
for (int i = last; i < current; i++)
{
- // FIXME: Should use isLetter(int) and text.codePointAt(int)
- // instead, but isLetter(int) isn't implemented yet
- if (Character.isLetter(text.charAt(i)))
+ cp = text.codePointAt(i);
+
+ // Return the last found bound if there is a letter at the current
+ // location or is not whitespace (meaning it is a number or
+ // punctuation). The first case means that 'last' denotes the
+ // beginning of a word while the second case means it is the start
+ // of some else.
+ if (Character.isLetter(cp)
+ || !Character.isWhitespace(cp))
return last;
}
last = current;
current = wb.next();
}
- return BreakIterator.DONE;
+
+ throw new BadLocationException("no more word", offs);
}
/**
@@ -358,9 +375,7 @@ public class Utilities
{
for (int i = last; i < offs; i++)
{
- // FIXME: Should use isLetter(int) and text.codePointAt(int)
- // instead, but isLetter(int) isn't implemented yet
- if (Character.isLetter(text.charAt(i)))
+ if (Character.isLetter(text.codePointAt(i)))
return last;
}
last = current;
@@ -510,24 +525,28 @@ public class Utilities
int x0, int x, TabExpander e,
int startOffset)
{
- int mark = Utilities.getTabbedTextOffset(s, metrics, x0, x, e, startOffset);
+ int mark = Utilities.getTabbedTextOffset(s, metrics, x0, x, e, startOffset, false);
BreakIterator breaker = BreakIterator.getWordInstance();
breaker.setText(s);
- // If mark is equal to the end of the string, just use that position
- if (mark == s.count + s.offset)
+ // If startOffset and s.offset differ then we need to use
+ // that difference two convert the offset between the two metrics.
+ int shift = startOffset - s.offset;
+
+ // If mark is equal to the end of the string, just use that position.
+ if (mark >= shift + s.count)
return mark;
// Try to find a word boundary previous to the mark at which we
- // can break the text
- int preceding = breaker.preceding(mark + 1);
+ // can break the text.
+ int preceding = breaker.preceding(mark + 1 - shift);
if (preceding != 0)
- return preceding;
- else
- // If preceding is 0 we couldn't find a suitable word-boundary so
- // just break it on the character boundary
- return mark;
+ return preceding + shift;
+
+ // If preceding is 0 we couldn't find a suitable word-boundary so
+ // just break it on the character boundary
+ return mark;
}
/**
@@ -619,8 +638,22 @@ public class Utilities
if(offs == -1)
return -1;
- // Effectively calculates the y value of the previous line.
- Point pt = c.modelToView(offs+1).getLocation();
+ Point pt = null;
+
+ // Note: Some views represent the position after the last
+ // typed character others do not. Converting offset 3 in "a\nb"
+ // in a PlainView will return a valid rectangle while in a
+ // WrappedPlainView this will throw a BadLocationException.
+ // This behavior has been observed in the RI.
+ try
+ {
+ // Effectively calculates the y value of the next line.
+ pt = c.modelToView(offs+1).getLocation();
+ }
+ catch(BadLocationException ble)
+ {
+ return offset;
+ }
pt.x = x;
diff --git a/libjava/classpath/javax/swing/text/View.java b/libjava/classpath/javax/swing/text/View.java
index 2feaf29..d8ad5f5 100644
--- a/libjava/classpath/javax/swing/text/View.java
+++ b/libjava/classpath/javax/swing/text/View.java
@@ -1,5 +1,5 @@
/* View.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -733,23 +733,38 @@ public abstract class View implements SwingConstants
throws BadLocationException
{
int ret = pos;
+ Rectangle r;
+ View parent;
+
switch (d)
{
- case WEST:
- ret = pos - 1;
- break;
case EAST:
- ret = pos + 1;
+ // TODO: take component orientation into account?
+ // Note: If pos is below zero the implementation will return
+ // pos + 1 regardless of whether that value is a correct offset
+ // in the document model. However this is what the RI does.
+ ret = Math.min(pos + 1, getEndOffset());
+ break;
+ case WEST:
+ // TODO: take component orientation into account?
+ ret = Math.max(pos - 1, getStartOffset());
break;
case NORTH:
- // TODO: Implement this
+ // Try to find a suitable offset by examining the area above.
+ parent = getParent();
+ r = parent.modelToView(pos, a, b).getBounds();
+ ret = parent.viewToModel(r.x, r.y - 1, a, biasRet);
break;
case SOUTH:
- // TODO: Implement this
+ // Try to find a suitable offset by examining the area below.
+ parent = getParent();
+ r = parent.modelToView(pos, a, b).getBounds();
+ ret = parent.viewToModel(r.x + r.width, r.y + r.height, a, biasRet);
break;
default:
throw new IllegalArgumentException("Illegal value for d");
}
+
return ret;
}
}
diff --git a/libjava/classpath/javax/swing/text/WrappedPlainView.java b/libjava/classpath/javax/swing/text/WrappedPlainView.java
index e2790a0..a6c369a 100644
--- a/libjava/classpath/javax/swing/text/WrappedPlainView.java
+++ b/libjava/classpath/javax/swing/text/WrappedPlainView.java
@@ -1,5 +1,5 @@
/* WrappedPlainView.java --
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,7 +45,6 @@ import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
-import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.text.Position.Bias;
@@ -64,8 +63,11 @@ public class WrappedPlainView extends BoxView implements TabExpander
/** The color for disabled components **/
Color disabledColor;
- /** Stores the font metrics **/
- protected FontMetrics metrics;
+ /**
+ * Stores the font metrics. This is package private to avoid synthetic
+ * accessor method.
+ */
+ FontMetrics metrics;
/** Whether or not to wrap on word boundaries **/
boolean wordWrap;
@@ -79,6 +81,9 @@ public class WrappedPlainView extends BoxView implements TabExpander
/** The end of the selected text **/
int selectionEnd;
+ /** The height of the line (used while painting) **/
+ int lineHeight;
+
/**
* The instance returned by {@link #getLineBuffer()}.
*/
@@ -270,8 +275,20 @@ public class WrappedPlainView extends BoxView implements TabExpander
protected int calculateBreakPosition(int p0, int p1)
{
Container c = getContainer();
- Rectangle alloc = new Rectangle(0, 0, getWidth(), getHeight());
+
+ int li = getLeftInset();
+ int ti = getTopInset();
+
+ Rectangle alloc = new Rectangle(li, ti,
+ getWidth()-getRightInset()-li,
+ getHeight()-getBottomInset()-ti);
+
+ // Mimic a behavior observed in the RI.
+ if (alloc.isEmpty())
+ return 0;
+
updateMetrics();
+
try
{
getDocument().getText(p0, p1 - p0, getLineBuffer());
@@ -279,18 +296,16 @@ public class WrappedPlainView extends BoxView implements TabExpander
catch (BadLocationException ble)
{
// this shouldn't happen
+ throw new InternalError("Invalid offsets p0: " + p0 + " - p1: " + p1);
}
- // FIXME: Should we account for the insets of the container?
+
if (wordWrap)
- return p0
- + Utilities.getBreakLocation(lineBuffer, metrics, alloc.x,
- alloc.x + alloc.width, this, 0);
+ return Utilities.getBreakLocation(lineBuffer, metrics, alloc.x,
+ alloc.x + alloc.width, this, p0);
else
- {
- return p0
- + Utilities.getTabbedTextOffset(lineBuffer, metrics, alloc.x,
- alloc.x + alloc.width, this, 0);
- }
+ return p0 + Utilities.getTabbedTextOffset(lineBuffer, metrics, alloc.x,
+ alloc.x + alloc.width, this, 0,
+ true);
}
void updateMetrics()
@@ -336,8 +351,8 @@ public class WrappedPlainView extends BoxView implements TabExpander
public void insertUpdate (DocumentEvent e, Shape a, ViewFactory f)
{
super.insertUpdate(e, a, viewFactory);
- // FIXME: could improve performance by repainting only the necessary area
- getContainer().repaint();
+
+ // No repaint needed, as this is done by the WrappedLine instances.
}
/**
@@ -347,8 +362,8 @@ public class WrappedPlainView extends BoxView implements TabExpander
public void removeUpdate (DocumentEvent e, Shape a, ViewFactory f)
{
super.removeUpdate(e, a, viewFactory);
- // FIXME: could improve performance by repainting only the necessary area
- getContainer().repaint();
+
+ // No repaint needed, as this is done by the WrappedLine instances.
}
/**
@@ -359,8 +374,8 @@ public class WrappedPlainView extends BoxView implements TabExpander
public void changedUpdate (DocumentEvent e, Shape a, ViewFactory f)
{
super.changedUpdate(e, a, viewFactory);
- // FIXME: could improve performance by repainting only the necessary area
- getContainer().repaint();
+
+ // No repaint needed, as this is done by the WrappedLine instances.
}
class WrappedLineCreator implements ViewFactory
@@ -383,9 +398,19 @@ public class WrappedPlainView extends BoxView implements TabExpander
public void paint(Graphics g, Shape a)
{
JTextComponent comp = (JTextComponent)getContainer();
+ // Ensure metrics are up-to-date.
+ updateMetrics();
+
selectionStart = comp.getSelectionStart();
selectionEnd = comp.getSelectionEnd();
- updateMetrics();
+
+ selectedColor = comp.getSelectedTextColor();
+ unselectedColor = comp.getForeground();
+ disabledColor = comp.getDisabledTextColor();
+ selectedColor = comp.getSelectedTextColor();
+ lineHeight = metrics.getHeight();
+ g.setFont(comp.getFont());
+
super.paint(g, a);
}
@@ -404,7 +429,7 @@ public class WrappedPlainView extends BoxView implements TabExpander
class WrappedLine extends View
{
/** Used to cache the number of lines for this View **/
- int numLines;
+ int numLines = 1;
public WrappedLine(Element elem)
{
@@ -418,48 +443,47 @@ public class WrappedPlainView extends BoxView implements TabExpander
*/
public void paint(Graphics g, Shape s)
{
- // Ensure metrics are up-to-date.
- updateMetrics();
- JTextComponent textComponent = (JTextComponent) getContainer();
-
- g.setFont(textComponent.getFont());
- selectedColor = textComponent.getSelectedTextColor();
- unselectedColor = textComponent.getForeground();
- disabledColor = textComponent.getDisabledTextColor();
-
- // FIXME: this is a hack, for some reason textComponent.getSelectedColor
- // was returning black, which is not visible against a black background
- selectedColor = Color.WHITE;
-
Rectangle rect = s.getBounds();
- int lineHeight = metrics.getHeight();
int end = getEndOffset();
int currStart = getStartOffset();
- int currEnd;
+ int currEnd;
+ int count = 0;
while (currStart < end)
{
currEnd = calculateBreakPosition(currStart, end);
- drawLine(currStart, currEnd, g, rect.x, rect.y);
+
+ drawLine(currStart, currEnd, g, rect.x, rect.y + metrics.getAscent());
+
rect.y += lineHeight;
if (currEnd == currStart)
currStart ++;
else
- currStart = currEnd;
+ currStart = currEnd;
+
+ count++;
+
}
+
+ if (count != numLines)
+ {
+ numLines = count;
+ preferenceChanged(this, false, true);
+ }
+
}
/**
- * Determines the number of logical lines that the Element
- * needs to be displayed
- * @return the number of lines needed to display the Element
+ * Calculates the number of logical lines that the Element
+ * needs to be displayed and updates the variable numLines
+ * accordingly.
*/
- int determineNumLines()
+ void determineNumLines()
{
numLines = 0;
int end = getEndOffset();
if (end == 0)
- return 0;
+ return;
int breakPoint;
for (int i = getStartOffset(); i < end;)
@@ -468,12 +492,17 @@ public class WrappedPlainView extends BoxView implements TabExpander
// careful: check that there's no off-by-one problem here
// depending on which position calculateBreakPosition returns
breakPoint = calculateBreakPosition(i, end);
+
+ if (breakPoint == 0)
+ return;
+
+ // If breakPoint is equal to the current index no further
+ // line is needed and we can end the loop.
if (breakPoint == i)
- i ++;
+ break;
else
i = breakPoint;
}
- return numLines;
}
/**
@@ -489,7 +518,11 @@ public class WrappedPlainView extends BoxView implements TabExpander
if (axis == X_AXIS)
return getWidth();
else if (axis == Y_AXIS)
- return numLines * metrics.getHeight();
+ {
+ if (metrics == null)
+ updateMetrics();
+ return numLines * metrics.getHeight();
+ }
throw new IllegalArgumentException("Invalid axis for getPreferredSpan: "
+ axis);
@@ -509,9 +542,15 @@ public class WrappedPlainView extends BoxView implements TabExpander
public Shape modelToView(int pos, Shape a, Bias b)
throws BadLocationException
{
+ Rectangle rect = a.getBounds();
+
+ // Throwing a BadLocationException is an observed behavior of the RI.
+ if (rect.isEmpty())
+ throw new BadLocationException("Unable to calculate view coordinates "
+ + "when allocation area is empty.", 5);
+
Segment s = getLineBuffer();
int lineHeight = metrics.getHeight();
- Rectangle rect = a.getBounds();
// Return a rectangle with width 1 and height equal to the height
// of the text
@@ -530,7 +569,7 @@ public class WrappedPlainView extends BoxView implements TabExpander
// If pos is between currLineStart and currLineEnd then just find
// the width of the text from currLineStart to pos and add that
// to rect.x
- if (pos >= currLineStart && pos < currLineEnd || pos == end - 1)
+ if (pos >= currLineStart && pos < currLineEnd)
{
try
{
@@ -574,68 +613,93 @@ public class WrappedPlainView extends BoxView implements TabExpander
Segment s = getLineBuffer();
Rectangle rect = a.getBounds();
int currLineStart = getStartOffset();
+
+ // Although calling modelToView with the last possible offset will
+ // cause a BadLocationException in CompositeView it is allowed
+ // to return that offset in viewToModel.
int end = getEndOffset();
+
int lineHeight = metrics.getHeight();
if (y < rect.y)
return currLineStart;
+
if (y > rect.y + rect.height)
- return end - 1;
+ return end;
+
+ // Note: rect.x and rect.width do not represent the width of painted
+ // text but the area where text *may* be painted. This means the width
+ // is most of the time identical to the component's width.
- while (true)
+ while (currLineStart != end)
{
int currLineEnd = calculateBreakPosition(currLineStart, end);
+
// If we're at the right y-position that means we're on the right
// logical line and we should look for the character
if (y >= rect.y && y < rect.y + lineHeight)
{
- // Check if the x position is to the left or right of the text
- if (x < rect.x)
- return currLineStart;
- if (x > rect.x + rect.width)
- return currLineEnd - 1;
-
try
{
- getDocument().getText(currLineStart, end - currLineStart, s);
+ getDocument().getText(currLineStart, currLineEnd - currLineStart, s);
}
catch (BadLocationException ble)
{
// Shouldn't happen
}
- int mark = Utilities.getTabbedTextOffset(s, metrics, rect.x,
- (int) x,
- WrappedPlainView.this,
- currLineStart);
- return currLineStart + mark;
+
+ int offset = Utilities.getTabbedTextOffset(s, metrics, rect.x,
+ (int) x,
+ WrappedPlainView.this,
+ currLineStart);
+ // If the calculated offset is the end of the line (in the
+ // document (= start of the next line) return the preceding
+ // offset instead. This makes sure that clicking right besides
+ // the last character in a line positions the cursor after the
+ // last character and not in the beginning of the next line.
+ return (offset == currLineEnd) ? offset - 1 : offset;
}
// Increment rect.y so we're checking the next logical line
rect.y += lineHeight;
// Increment currLineStart to the model position of the start
- // of the next logical line
- if (currLineEnd == currLineStart)
- currLineStart = end;
- else
- currLineStart = currLineEnd;
+ // of the next logical line.
+ currLineStart = currLineEnd;
+
}
+
+ return end;
}
/**
- * This method is called from insertUpdate and removeUpdate.
- * If the number of lines in the document has changed, just repaint
+ * <p>This method is called from insertUpdate and removeUpdate.</p>
+ *
+ * <p>If the number of lines in the document has changed, just repaint
* the whole thing (note, could improve performance by not repainting
* anything above the changes). If the number of lines hasn't changed,
- * just repaint the given Rectangle.
+ * just repaint the given Rectangle.</p>
+ *
+ * <p>Note that the <code>Rectangle</code> argument may be <code>null</code>
+ * when the allocation area is empty.</code>
+ *
* @param a the Rectangle to repaint if the number of lines hasn't changed
*/
void updateDamage (Rectangle a)
{
- int newNumLines = determineNumLines();
- if (numLines != newNumLines)
+ // If the allocation area is empty we can't do anything useful.
+ // As determining the number of lines is impossible in that state we
+ // reset it to an invalid value which can then be recalculated at a
+ // later point.
+ if (a == null || a.isEmpty())
{
- numLines = newNumLines;
- getContainer().repaint();
+ numLines = 1;
+ return;
}
+
+ int oldNumLines = numLines;
+ determineNumLines();
+
+ if (numLines != oldNumLines)
+ preferenceChanged(this, false, true);
else
getContainer().repaint(a.x, a.y, a.width, a.height);
}
@@ -663,6 +727,15 @@ public class WrappedPlainView extends BoxView implements TabExpander
*/
public void removeUpdate (DocumentEvent changes, Shape a, ViewFactory f)
{
+ // Note: This method is not called when characters from the
+ // end of the document are removed. The reason for this
+ // can be found in the implementation of View.forwardUpdate:
+ // The document event will denote offsets which do not exist
+ // any more, getViewIndex() will therefore return -1 and this
+ // makes View.forwardUpdate() skip this method call.
+ // However this seems to cause no trouble and as it reduces the
+ // number of method calls it can stay this way.
+
updateDamage((Rectangle)a);
}
}
diff --git a/libjava/classpath/javax/swing/text/html/FormView.java b/libjava/classpath/javax/swing/text/html/FormView.java
index b85c694..d540210 100644
--- a/libjava/classpath/javax/swing/text/html/FormView.java
+++ b/libjava/classpath/javax/swing/text/html/FormView.java
@@ -39,8 +39,11 @@ exception statement from your version. */
package javax.swing.text.html;
import java.awt.Component;
+import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JCheckBox;
@@ -83,6 +86,24 @@ public class FormView
implements ActionListener
{
+ protected class MouseEventListener
+ extends MouseAdapter
+ {
+ /**
+ * Creates a new <code>MouseEventListener</code>.
+ */
+ protected MouseEventListener()
+ {
+ // Nothing to do here.
+ }
+
+ public void mouseReleased(MouseEvent ev)
+ {
+ String data = getImageData(ev.getPoint());
+ imageSubmit(data);
+ }
+ }
+
/**
* If the value attribute of an <code>&lt;input type=&quot;submit&quot;&gt>
* tag is not specified, then this string is used.
@@ -227,4 +248,28 @@ public class FormView
{
// FIXME: Implement this.
}
+
+ /**
+ * Determines the image data that should be submitted in response to a
+ * mouse click on a image. This is either 'x=<p.x>&y=<p.y>' if the name
+ * attribute of the element is null or '' or
+ * <name>.x=<p.x>&<name>.y=<p.y>' when the name attribute is not empty.
+ *
+ * @param p the coordinates of the mouseclick
+ */
+ String getImageData(Point p)
+ {
+ String name = (String) getElement().getAttributes()
+ .getAttribute(HTML.Attribute.NAME);
+ String data;
+ if (name == null || name.equals(""))
+ {
+ data = "x=" + p.x + "&y=" + p.y;
+ }
+ else
+ {
+ data = name + ".x=" + p.x + "&" + name + ".y=" + p.y;
+ }
+ return data;
+ }
}
diff --git a/libjava/classpath/javax/swing/text/html/HTML.java b/libjava/classpath/javax/swing/text/html/HTML.java
index 2b521cd..2c908f6 100644
--- a/libjava/classpath/javax/swing/text/html/HTML.java
+++ b/libjava/classpath/javax/swing/text/html/HTML.java
@@ -292,7 +292,7 @@ public class HTML
/**
* The media attribute
*/
- public static final Attribute MEDIA = new Attribute("media");
+ static final Attribute MEDIA = new Attribute("media");
/**
* The method attribute
@@ -758,7 +758,7 @@ public class HTML
/**
* The &lt;nobr&gt; tag
*/
- public static final Tag NOBR = new Tag("nobr");
+ static final Tag NOBR = new Tag("nobr");
/**
* The &lt;noframes&gt; tag , breaks flow, block tag.
diff --git a/libjava/classpath/javax/swing/text/html/HTMLDocument.java b/libjava/classpath/javax/swing/text/html/HTMLDocument.java
index 2a96953..fba6cad 100644
--- a/libjava/classpath/javax/swing/text/html/HTMLDocument.java
+++ b/libjava/classpath/javax/swing/text/html/HTMLDocument.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.text.html;
+import gnu.classpath.NotImplementedException;
+
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
@@ -667,6 +669,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("FormAction.start not implemented");
@@ -677,6 +680,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("FormAction.end not implemented");
@@ -690,6 +694,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("HiddenAction.start not implemented");
@@ -700,6 +705,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("HiddenAction.end not implemented");
@@ -713,6 +719,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("IsindexAction.start not implemented");
@@ -723,6 +730,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("IsindexAction.end not implemented");
@@ -759,6 +767,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("PreAction.start not implemented");
@@ -769,6 +778,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("PreAction.end not implemented");
@@ -782,6 +792,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("SpecialAction.start not implemented");
@@ -792,6 +803,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("SpecialAction.end not implemented");
@@ -805,6 +817,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("AreaAction.start not implemented");
@@ -815,6 +828,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("AreaAction.end not implemented");
@@ -828,6 +842,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("BaseAction.start not implemented");
@@ -838,6 +853,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("BaseAction.end not implemented");
@@ -851,6 +867,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("HeadAction.start not implemented: "+t);
@@ -862,6 +879,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("HeadAction.end not implemented: "+t);
@@ -876,6 +894,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("LinkAction.start not implemented");
@@ -886,6 +905,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("LinkAction.end not implemented");
@@ -899,6 +919,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("MapAction.start not implemented");
@@ -909,6 +930,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("MapAction.end not implemented");
@@ -922,6 +944,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("MetaAction.start not implemented");
@@ -932,6 +955,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("MetaAction.end not implemented");
@@ -945,6 +969,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("StyleAction.start not implemented");
@@ -955,6 +980,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("StyleAction.end not implemented");
@@ -968,6 +994,7 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("TitleAction.start not implemented");
@@ -978,6 +1005,7 @@ public class HTMLDocument extends DefaultStyledDocument
* with this Action.
*/
public void end(HTML.Tag t)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("TitleAction.end not implemented");
@@ -1253,6 +1281,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @since 1.3
*/
public void handleEndOfLineString(String eol)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("HTMLReader.handleEndOfLineString not implemented yet");
@@ -1265,6 +1294,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @param data the text to add to the textarea
*/
protected void textAreaContent(char[] data)
+ throws NotImplementedException
{
// FIXME: Implement.
print ("HTMLReader.textAreaContent not implemented yet");
@@ -1276,6 +1306,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @param data the text
*/
protected void preContent(char[] data)
+ throws NotImplementedException
{
// FIXME: Implement
print ("HTMLReader.preContent not implemented yet");
@@ -1447,6 +1478,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @param a the attribute set specifying the special content
*/
protected void addSpecialElement(HTML.Tag t, MutableAttributeSet a)
+ throws NotImplementedException
{
// FIXME: Implement
print ("HTMLReader.addSpecialElement not implemented yet");
@@ -1550,7 +1582,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @throws IllegalStateException - if an HTMLEditorKit.Parser has not been set
*/
public void setInnerHTML(Element elem, String htmlText)
- throws BadLocationException, IOException
+ throws BadLocationException, IOException, NotImplementedException
{
if (elem.isLeaf())
throw new IllegalArgumentException("Element is a leaf");
@@ -1574,7 +1606,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @throws IllegalStateException - if parser is not set
*/
public void setOuterHTML(Element elem, String htmlText)
- throws BadLocationException, IOException
+ throws BadLocationException, IOException, NotImplementedException
{
if (parser == null)
throw new IllegalStateException("Parser has not been set");
@@ -1593,7 +1625,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @throws IllegalStateException - if parser has not been set
*/
public void insertBeforeStart(Element elem, String htmlText)
- throws BadLocationException, IOException
+ throws BadLocationException, IOException, NotImplementedException
{
if (parser == null)
throw new IllegalStateException("Parser has not been set");
@@ -1613,7 +1645,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @throws IllegalStateException - if parser is not set
*/
public void insertBeforeEnd(Element elem, String htmlText)
- throws BadLocationException, IOException
+ throws BadLocationException, IOException, NotImplementedException
{
if (parser == null)
throw new IllegalStateException("Parser has not been set");
@@ -1632,7 +1664,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @throws IllegalStateException - if parser is not set
*/
public void insertAfterEnd(Element elem, String htmlText)
- throws BadLocationException, IOException
+ throws BadLocationException, IOException, NotImplementedException
{
if (parser == null)
throw new IllegalStateException("Parser has not been set");
@@ -1651,7 +1683,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @throws IllegalStateException - if parser is not set
*/
public void insertAfterStart(Element elem, String htmlText)
- throws BadLocationException, IOException
+ throws BadLocationException, IOException, NotImplementedException
{
if (parser == null)
throw new IllegalStateException("Parser has not been set");
@@ -1676,6 +1708,7 @@ public class HTMLDocument extends DefaultStyledDocument
*/
public void setParagraphAttributes(int offset, int length, AttributeSet s,
boolean replace)
+ throws NotImplementedException
{
// FIXME: Not implemented.
System.out.println("setParagraphAttributes not implemented");
@@ -1688,6 +1721,7 @@ public class HTMLDocument extends DefaultStyledDocument
* @param e - the Document event
*/
protected void fireChangedUpdate(DocumentEvent e)
+ throws NotImplementedException
{
// FIXME: Not implemented.
System.out.println("fireChangedUpdate not implemented");
diff --git a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
index 2d5d1eb..92d9de9 100644
--- a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
+++ b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package javax.swing.text.html;
+import gnu.classpath.NotImplementedException;
+
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@@ -298,6 +300,7 @@ public class HTMLEditorKit
Element insertElement,
String html, HTML.Tag parentTag,
HTML.Tag addTag)
+ throws NotImplementedException
{
/*
As its name implies, this protected method is used when HTML is inserted at a
diff --git a/libjava/classpath/javax/swing/text/html/ListView.java b/libjava/classpath/javax/swing/text/html/ListView.java
new file mode 100644
index 0000000..c07d359
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/ListView.java
@@ -0,0 +1,131 @@
+/* ListView.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.text.html;
+
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+import javax.swing.text.Element;
+
+/**
+ * A View to render HTML lists, like the <code>&lt;ul&gt;</code> and
+ * <code>&lt;ol&gt;</code> tags.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public class ListView
+ extends BlockView
+{
+
+ /**
+ * The painter used to paint the list items.
+ */
+ private StyleSheet.ListPainter painter;
+
+ /**
+ * Creates a new <code>ListView</code> for the specified element.
+ *
+ * @param el the element to create a list view for
+ */
+ public ListView(Element el)
+ {
+ super(el, Y_AXIS);
+ }
+
+ /**
+ * Returns the alignment of this view along the specified axis.
+ *
+ * This returns <code>0.5</code> unconditionally.
+ *
+ * @param axis the axis
+ *
+ * @return the alignment of this view along the specified axis
+ */
+ public float getAlignment(int axis)
+ {
+ if (axis != X_AXIS && axis != Y_AXIS)
+ throw new IllegalArgumentException("Illegal axis parameter: " + axis);
+
+ return 0.5F;
+ }
+
+ /**
+ * Paints the <code>ListView</code>.
+ *
+ * @param g the graphics context to use for painting
+ * @param allocation the allocation given to this view
+ */
+ public void paint(Graphics g, Shape allocation)
+ {
+ super.paint(g, allocation);
+ // FIXME: Why is this overridden? I think that painting would be done
+ // by the superclass and the stylesheet... Maybe find out when this
+ // stuff is implemented properly.
+ }
+
+ /**
+ * Paints the child with the specified index into the specified allocation.
+ *
+ * This implementation forwards to the list painter fetched from the
+ * {@link StyleSheet} and then calls
+ * <code>super.paintChild(g, a, index)</code>.
+ *
+ * @param g the graphics context to use
+ * @param a the allocation for the child
+ * @param index the child index
+ */
+ protected void paintChild(Graphics g, Rectangle a, int index)
+ {
+ painter.paint(g, a.x, a.y, a.width, a.height, this, index);
+ super.paintChild(g, a, index);
+ }
+
+ /**
+ * Fetches this view's properties from the style attributes of this view's
+ * element.
+ *
+ * This forwards to super and then fetches a {@link StyleSheet.ListPainter}
+ * from the stylesheet suitable for painting the list.
+ */
+ protected void setPropertiesFromAttributes()
+ {
+ super.setPropertiesFromAttributes();
+ painter = getStyleSheet().getListPainter(getAttributes());
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/NullView.java b/libjava/classpath/javax/swing/text/html/NullView.java
index 4b66c5a..86ce0c1 100644
--- a/libjava/classpath/javax/swing/text/html/NullView.java
+++ b/libjava/classpath/javax/swing/text/html/NullView.java
@@ -52,8 +52,8 @@ import javax.swing.text.Position.Bias;
*
* @author Roman Kennke (kennke@aicas.com)
*/
-public class NullView
- extends View
+class NullView
+ extends View
{
/**
diff --git a/libjava/classpath/javax/swing/text/html/parser/Entity.java b/libjava/classpath/javax/swing/text/html/parser/Entity.java
index 766984f..cf294c7 100644
--- a/libjava/classpath/javax/swing/text/html/parser/Entity.java
+++ b/libjava/classpath/javax/swing/text/html/parser/Entity.java
@@ -54,7 +54,7 @@ import java.io.Serializable;
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public final class Entity
- implements DTDConstants, Serializable
+ implements DTDConstants
{
/**
* Package level mapper between type names and they string values.
diff --git a/libjava/classpath/javax/swing/text/rtf/package.html b/libjava/classpath/javax/swing/text/rtf/package.html
new file mode 100644
index 0000000..c695aef
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/rtf/package.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.swing.text.rtf package.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - javax.swing.text.rtf</title></head>
+
+<body>
+<p>Provides support for Rich Text Format (RTF) data to be used with the
+{@link JEditorPane} component.
+</p>
+
+</body>
+</html>