summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/javax/swing/text
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/text')
-rw-r--r--libjava/classpath/javax/swing/text/AbstractDocument.java1236
-rw-r--r--libjava/classpath/javax/swing/text/AttributeSet.java121
-rw-r--r--libjava/classpath/javax/swing/text/BadLocationException.java23
-rw-r--r--libjava/classpath/javax/swing/text/Caret.java168
-rw-r--r--libjava/classpath/javax/swing/text/ComponentView.java18
-rw-r--r--libjava/classpath/javax/swing/text/DateFormatter.java2
-rw-r--r--libjava/classpath/javax/swing/text/DefaultCaret.java293
-rw-r--r--libjava/classpath/javax/swing/text/DefaultEditorKit.java590
-rw-r--r--libjava/classpath/javax/swing/text/DefaultStyledDocument.java307
-rw-r--r--libjava/classpath/javax/swing/text/FieldView.java5
-rw-r--r--libjava/classpath/javax/swing/text/GapContent.java360
-rw-r--r--libjava/classpath/javax/swing/text/InternationalFormatter.java2
-rw-r--r--libjava/classpath/javax/swing/text/JTextComponent.java27
-rw-r--r--libjava/classpath/javax/swing/text/PasswordView.java170
-rw-r--r--libjava/classpath/javax/swing/text/PlainDocument.java16
-rw-r--r--libjava/classpath/javax/swing/text/PlainView.java18
-rw-r--r--libjava/classpath/javax/swing/text/StyledEditorKit.java569
-rw-r--r--libjava/classpath/javax/swing/text/View.java140
-rw-r--r--libjava/classpath/javax/swing/text/html/HTMLEditorKit.java7
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/DTD.java7
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/DTDConstants.java6
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/DocumentParser.java12
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/Element.java2
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/Parser.java12
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java4
25 files changed, 3559 insertions, 556 deletions
diff --git a/libjava/classpath/javax/swing/text/AbstractDocument.java b/libjava/classpath/javax/swing/text/AbstractDocument.java
index c3a3d70ae37..3c9a4d497a5 100644
--- a/libjava/classpath/javax/swing/text/AbstractDocument.java
+++ b/libjava/classpath/javax/swing/text/AbstractDocument.java
@@ -56,70 +56,193 @@ import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CompoundEdit;
import javax.swing.undo.UndoableEdit;
+/**
+ * An abstract base implementation for the {@link Document} interface.
+ * This class provides some common functionality for all <code>Element</code>s,
+ * most notably it implements a locking mechanism to make document modification
+ * thread-safe.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public abstract class AbstractDocument
implements Document, Serializable
{
+ /** The serial version UID for this class as of JDK1.4. */
private static final long serialVersionUID = -116069779446114664L;
-
+
+ /**
+ * Standard error message to indicate a bad location.
+ */
protected static final String BAD_LOCATION = "document location failure";
-
+
+ /**
+ * Standard name for unidirectional <code>Element</code>s.
+ */
public static final String BidiElementName = "bidi level";
+
+ /**
+ * Standard name for content <code>Element</code>s. These are usually
+ * {@link LeafElement}s.
+ */
public static final String ContentElementName = "content";
+
+ /**
+ * Standard name for paragraph <code>Element</code>s. These are usually
+ * {@link BranchElement}s.
+ */
public static final String ParagraphElementName = "paragraph";
+
+ /**
+ * Standard name for section <code>Element</code>s. These are usually
+ * {@link DefaultStyledDocument.SectionElement}s.
+ */
public static final String SectionElementName = "section";
+
+ /**
+ * Attribute key for storing the element name.
+ */
public static final String ElementNameAttribute = "$ename";
+ /**
+ * The actual content model of this <code>Document</code>.
+ */
Content content;
+
+ /**
+ * The AttributeContext for this <code>Document</code>.
+ */
AttributeContext context;
+
+ /**
+ * The currently installed <code>DocumentFilter</code>.
+ */
DocumentFilter documentFilter;
- /** The documents properties. */
+ /**
+ * The documents properties.
+ */
Dictionary properties;
+ /**
+ * Manages event listeners for this <code>Document</code>.
+ */
protected EventListenerList listenerList = new EventListenerList();
+ /**
+ * Creates a new <code>AbstractDocument</code> with the specified
+ * {@link Content} model.
+ *
+ * @param doc the <code>Content</code> model to be used in this
+ * <code>Document<code>
+ *
+ * @see GapContent
+ * @see StringContent
+ */
protected AbstractDocument(Content doc)
{
this(doc, StyleContext.getDefaultStyleContext());
}
+ /**
+ * Creates a new <code>AbstractDocument</code> with the specified
+ * {@link Content} model and {@link AttributeContext}.
+ *
+ * @param doc the <code>Content</code> model to be used in this
+ * <code>Document<code>
+ * @param ctx the <code>AttributeContext</code> to use
+ *
+ * @see GapContent
+ * @see StringContent
+ */
protected AbstractDocument(Content doc, AttributeContext ctx)
{
content = doc;
context = ctx;
}
- // These still need to be implemented by a derived class:
+ /**
+ * Returns the paragraph {@link Element} that holds the specified position.
+ *
+ * @param pos the position for which to get the paragraph element
+ *
+ * @return the paragraph {@link Element} that holds the specified position
+ */
public abstract Element getParagraphElement(int pos);
+ /**
+ * Returns the default root {@link Element} of this <code>Document</code>.
+ * Usual <code>Document</code>s only have one root element and return this.
+ * However, there may be <code>Document</code> implementations that
+ * support multiple root elements, they have to return a default root element
+ * here.
+ *
+ * @return the default root {@link Element} of this <code>Document</code>
+ */
public abstract Element getDefaultRootElement();
+ /**
+ * Creates and returns a branch element with the specified
+ * <code>parent</code> and <code>attributes</code>. Note that the new
+ * <code>Element</code> is linked to the parent <code>Element</code>
+ * through {@link Element#getParentElement}, but it is not yet added
+ * to the parent <code>Element</code> as child.
+ *
+ * @param parent the parent <code>Element</code> for the new branch element
+ * @param attributes the text attributes to be installed in the new element
+ *
+ * @return the new branch <code>Element</code>
+ *
+ * @see BranchElement
+ */
protected Element createBranchElement(Element parent,
AttributeSet attributes)
{
return new BranchElement(parent, attributes);
}
+ /**
+ * Creates and returns a leaf element with the specified
+ * <code>parent</code> and <code>attributes</code>. Note that the new
+ * <code>Element</code> is linked to the parent <code>Element</code>
+ * through {@link Element#getParentElement}, but it is not yet added
+ * to the parent <code>Element</code> as child.
+ *
+ * @param parent the parent <code>Element</code> for the new branch element
+ * @param attributes the text attributes to be installed in the new element
+ *
+ * @return the new branch <code>Element</code>
+ *
+ * @see LeafElement
+ */
protected Element createLeafElement(Element parent, AttributeSet attributes,
int start, int end)
{
return new LeafElement(parent, attributes, start, end);
}
+ /**
+ * Creates a {@link Position} that keeps track of the location at the
+ * specified <code>offset</code>.
+ *
+ * @param offset the location in the document to keep track by the new
+ * <code>Position</code>
+ *
+ * @return the newly created <code>Position</code>
+ *
+ * @throws BadLocationException if <code>offset</code> is not a valid
+ * location in the documents content model
+ */
public Position createPosition(final int offset) throws BadLocationException
{
- if (offset < 0 || offset > getLength())
- throw new BadLocationException(getText(0, getLength()), offset);
-
- return new Position()
- {
- public int getOffset()
- {
- return offset;
- }
- };
+ return content.createPosition(offset);
}
+ /**
+ * Notifies all registered listeners when the document model changes.
+ *
+ * @param event the <code>DocumentEvent</code> to be fired
+ */
protected void fireChangedUpdate(DocumentEvent event)
{
DocumentListener[] listeners = getDocumentListeners();
@@ -128,6 +251,12 @@ public abstract class AbstractDocument
listeners[index].changedUpdate(event);
}
+ /**
+ * Notifies all registered listeners when content is inserted in the document
+ * model.
+ *
+ * @param event the <code>DocumentEvent</code> to be fired
+ */
protected void fireInsertUpdate(DocumentEvent event)
{
DocumentListener[] listeners = getDocumentListeners();
@@ -136,6 +265,12 @@ public abstract class AbstractDocument
listeners[index].insertUpdate(event);
}
+ /**
+ * Notifies all registered listeners when content is removed from the
+ * document model.
+ *
+ * @param event the <code>DocumentEvent</code> to be fired
+ */
protected void fireRemoveUpdate(DocumentEvent event)
{
DocumentListener[] listeners = getDocumentListeners();
@@ -144,6 +279,12 @@ public abstract class AbstractDocument
listeners[index].removeUpdate(event);
}
+ /**
+ * Notifies all registered listeners when an <code>UndoableEdit</code> has
+ * been performed on this <code>Document</code>.
+ *
+ * @param event the <code>UndoableEditEvent</code> to be fired
+ */
protected void fireUndoableEditUpdate(UndoableEditEvent event)
{
UndoableEditListener[] listeners = getUndoableEditListeners();
@@ -152,31 +293,70 @@ public abstract class AbstractDocument
listeners[index].undoableEditHappened(event);
}
+ /**
+ * Returns the asynchronous loading priority. Returns <code>-1</code> if this
+ * document should not be loaded asynchronously.
+ *
+ * @return the asynchronous loading priority
+ */
public int getAsynchronousLoadPriority()
{
return 0;
}
+ /**
+ * Returns the {@link AttributeContext} used in this <code>Document</code>.
+ *
+ * @return the {@link AttributeContext} used in this <code>Document</code>
+ */
protected AttributeContext getAttributeContext()
{
return context;
}
+ /**
+ * Returns the root element for bidirectional content.
+ *
+ * @return the root element for bidirectional content
+ */
public Element getBidiRootElement()
{
return null;
}
+ /**
+ * Returns the {@link Content} model for this <code>Document</code>
+ *
+ * @return the {@link Content} model for this <code>Document</code>
+ *
+ * @see GapContent
+ * @see StringContent
+ */
protected Content getContent()
{
return content;
}
+ /**
+ * Returns the thread that currently modifies this <code>Document</code>
+ * if there is one, otherwise <code>null</code>. This can be used to
+ * distinguish between a method call that is part of an ongoing modification
+ * or if it is a separate modification for which a new lock must be aquired.
+ *
+ * @return the thread that currently modifies this <code>Document</code>
+ * if there is one, otherwise <code>null</code>
+ */
protected Thread getCurrentWriter()
{
+ // FIXME: Implement locking!
return null;
}
+ /**
+ * Returns the properties of this <code>Document</code>.
+ *
+ * @return the properties of this <code>Document</code>
+ */
public Dictionary getDocumentProperties()
{
// FIXME: make me thread-safe
@@ -186,8 +366,16 @@ public abstract class AbstractDocument
return properties;
}
+ /**
+ * Returns a {@link Position} which will always mark the end of the
+ * <code>Document</code>.
+ *
+ * @return a {@link Position} which will always mark the end of the
+ * <code>Document</code>
+ */
public Position getEndPosition()
{
+ // FIXME: Properly implement this by calling Content.createPosition().
return new Position()
{
public int getOffset()
@@ -197,16 +385,39 @@ public abstract class AbstractDocument
};
}
+ /**
+ * Returns the length of this <code>Document</code>'s content.
+ *
+ * @return the length of this <code>Document</code>'s content
+ */
public int getLength()
{
+ // We return Content.getLength() -1 here because there is always an
+ // implicit \n at the end of the Content which does count in Content
+ // but not in Document.
return content.length() - 1;
}
+ /**
+ * Returns all registered listeners of a given listener type.
+ *
+ * @param listenerType the type of the listeners to be queried
+ *
+ * @return all registered listeners of the specified type
+ */
public EventListener[] getListeners(Class listenerType)
{
return listenerList.getListeners(listenerType);
}
+ /**
+ * Returns a property from this <code>Document</code>'s property list.
+ *
+ * @param key the key of the property to be fetched
+ *
+ * @return the property for <code>key</code> or <code>null</code> if there
+ * is no such property stored
+ */
public Object getProperty(Object key)
{
// FIXME: make me thread-safe
@@ -217,6 +428,15 @@ public abstract class AbstractDocument
return value;
}
+ /**
+ * Returns all root elements of this <code>Document</code>. By default
+ * this just returns the single root element returned by
+ * {@link #getDefaultRootElement()}. <code>Document</code> implementations
+ * that support multiple roots must override this method and return all roots
+ * here.
+ *
+ * @return all root elements of this <code>Document</code>
+ */
public Element[] getRootElements()
{
Element[] elements = new Element[1];
@@ -224,8 +444,16 @@ public abstract class AbstractDocument
return elements;
}
+ /**
+ * Returns a {@link Position} which will always mark the beginning of the
+ * <code>Document</code>.
+ *
+ * @return a {@link Position} which will always mark the beginning of the
+ * <code>Document</code>
+ */
public Position getStartPosition()
{
+ // FIXME: Properly implement this using Content.createPosition().
return new Position()
{
public int getOffset()
@@ -235,17 +463,53 @@ public abstract class AbstractDocument
};
}
+ /**
+ * Returns a piece of this <code>Document</code>'s content.
+ *
+ * @param offset the start offset of the content
+ * @param length the length of the content
+ *
+ * @return the piece of content specified by <code>offset</code> and
+ * <code>length</code>
+ *
+ * @throws BadLocationException if <code>offset</code> or <code>offset +
+ * length</code> are invalid locations with this
+ * <code>Document</code>
+ */
public String getText(int offset, int length) throws BadLocationException
{
return content.getString(offset, length);
}
+ /**
+ * Fetches a piece of this <code>Document</code>'s content and stores
+ * it in the given {@link Segment}.
+ *
+ * @param offset the start offset of the content
+ * @param length the length of the content
+ * @param segment the <code>Segment</code> to store the content in
+ *
+ * @throws BadLocationException if <code>offset</code> or <code>offset +
+ * length</code> are invalid locations with this
+ * <code>Document</code>
+ */
public void getText(int offset, int length, Segment segment)
throws BadLocationException
{
content.getChars(offset, length, segment);
}
+ /**
+ * Inserts a String into this <code>Document</code> at the specified
+ * position and assigning the specified attributes to it.
+ *
+ * @param offset the location at which the string should be inserted
+ * @param text the content to be inserted
+ * @param attributes the text attributes to be assigned to that string
+ *
+ * @throws BadLocationException if <code>offset</code> is not a valid
+ * location in this <code>Document</code>
+ */
public void insertString(int offset, String text, AttributeSet attributes)
throws BadLocationException
{
@@ -261,14 +525,37 @@ public abstract class AbstractDocument
fireInsertUpdate(event);
}
+ /**
+ * Called to indicate that text has been inserted into this
+ * <code>Document</code>. The default implementation does nothing.
+ * This method is executed within a write lock.
+ *
+ * @param chng the <code>DefaultDocumentEvent</code> describing the change
+ * @param attr the attributes of the changed content
+ */
protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr)
{
+ // Do nothing here. Subclasses may want to override this.
}
+ /**
+ * Called after some content has been removed from this
+ * <code>Document</code>. The default implementation does nothing.
+ * This method is executed within a write lock.
+ *
+ * @param chng the <code>DefaultDocumentEvent</code> describing the change
+ */
protected void postRemoveUpdate(DefaultDocumentEvent chng)
{
+ // Do nothing here. Subclasses may want to override this.
}
+ /**
+ * Stores a property in this <code>Document</code>'s property list.
+ *
+ * @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)
{
// FIXME: make me thread-safe
@@ -278,14 +565,31 @@ public abstract class AbstractDocument
properties.put(key, value);
}
+ /**
+ * Blocks until a read lock can be obtained.
+ */
public void readLock()
{
}
+ /**
+ * Releases the read lock. If this was the only reader on this
+ * <code>Document</code>, writing may begin now.
+ */
public void readUnlock()
{
}
+ /**
+ * Removes a piece of content from this <code>Document</code>.
+ *
+ * @param offset the start offset of the fragment to be removed
+ * @param length the length of the fragment to be removed
+ *
+ * @throws BadLocationException if <code>offset</code> or
+ * <code>offset + length</code> or invalid locations within this
+ * document
+ */
public void remove(int offset, int length) throws BadLocationException
{
DefaultDocumentEvent event =
@@ -298,7 +602,17 @@ public abstract class AbstractDocument
}
/**
- * Replaces some text in the document.
+ * Replaces a piece of content in this <code>Document</code> with
+ * another piece of content.
+ *
+ * @param offset the start offset of the fragment to be removed
+ * @param length the length of the fragment to be removed
+ * @param text the text to replace the content with
+ * @param attributes the text attributes to assign to the new content
+ *
+ * @throws BadLocationException if <code>offset</code> or
+ * <code>offset + length</code> or invalid locations within this
+ * document
*
* @since 1.4
*/
@@ -331,9 +645,9 @@ public abstract class AbstractDocument
}
/**
- * Returns add added <code>DocumentListener</code> objects.
+ * Returns all registered <code>DocumentListener</code>s.
*
- * @return an array of listeners
+ * @return all registered <code>DocumentListener</code>s
*/
public DocumentListener[] getDocumentListeners()
{
@@ -341,7 +655,7 @@ public abstract class AbstractDocument
}
/**
- * Adds a <code>UndoableEditListener</code> object to this document.
+ * Adds an {@link UndoableEditListener} to this <code>Document</code>.
*
* @param listener the listener to add
*/
@@ -351,7 +665,7 @@ public abstract class AbstractDocument
}
/**
- * Removes a <code>UndoableEditListener</code> object from this document.
+ * Removes an {@link UndoableEditListener} from this <code>Document</code>.
*
* @param listener the listener to remove
*/
@@ -361,42 +675,93 @@ public abstract class AbstractDocument
}
/**
- * Returns add added <code>UndoableEditListener</code> objects.
+ * Returns all registered {@link UndoableEditListener}s.
*
- * @return an array of listeners
+ * @return all registered {@link UndoableEditListener}s
*/
public UndoableEditListener[] getUndoableEditListeners()
{
return (UndoableEditListener[]) getListeners(UndoableEditListener.class);
}
+ /**
+ * Called before some content gets removed from this <code>Document</code>.
+ * The default implementation does nothing but may be overridden by
+ * subclasses to modify the <code>Document</code> structure in response
+ * to a remove request. The method is executed within a write lock.
+ *
+ * @param chng the <code>DefaultDocumentEvent</code> describing the change
+ */
protected void removeUpdate(DefaultDocumentEvent chng)
{
+ // Do nothing here. Subclasses may wish to override this.
}
- public void render(Runnable r)
+ /**
+ * Called to render this <code>Document</code> visually. It obtains a read
+ * lock, ensuring that no changes will be made to the <code>document</code>
+ * during the rendering process. It then calls the {@link Runnable#run()}
+ * method on <code>runnable</code>. This method <em>must not</em> attempt
+ * to modifiy the <code>Document</code>, since a deadlock will occur if it
+ * tries to obtain a write lock. When the {@link Runnable#run()} method
+ * completes (either naturally or by throwing an exception), the read lock
+ * is released. Note that there is nothing in this method related to
+ * the actual rendering. It could be used to execute arbitrary code within
+ * a read lock.
+ *
+ * @param runnable the {@link Runnable} to execute
+ */
+ public void render(Runnable runnable)
{
+ // FIXME: Implement me!
}
+ /**
+ * Sets the asynchronous loading priority for this <code>Document</code>.
+ * A value of <code>-1</code> indicates that this <code>Document</code>
+ * should be loaded synchronously.
+ *
+ * @param p the asynchronous loading priority to set
+ */
public void setAsynchronousLoadPriority(int p)
{
}
- public void setDocumentProperties(Dictionary x)
+ /**
+ * Sets the properties of this <code>Document</code>.
+ *
+ * @param p the document properties to set
+ */
+ public void setDocumentProperties(Dictionary p)
{
// FIXME: make me thread-safe
- properties = x;
+ properties = p;
}
+ /**
+ * Blocks until a write lock can be obtained.
+ */
protected void writeLock()
{
+ // FIXME: Implement me.
}
+ /**
+ * Releases the write lock. This allows waiting readers or writers to
+ * obtain the lock.
+ */
protected void writeUnlock()
{
+ // FIXME: Implement me.
}
/**
+ * Returns the currently installed {@link DocumentFilter} for this
+ * <code>Document</code>.
+ *
+ * @return the currently installed {@link DocumentFilter} for this
+ * <code>Document</code>
+ *
* @since 1.4
*/
public DocumentFilter getDocumentFilter()
@@ -405,6 +770,10 @@ public abstract class AbstractDocument
}
/**
+ * Sets the {@link DocumentFilter} for this <code>Document</code>.
+ *
+ * @param filter the <code>DocumentFilter</code> to set
+ *
* @since 1.4
*/
public void setDocumentFilter(DocumentFilter filter)
@@ -412,209 +781,592 @@ public abstract class AbstractDocument
this.documentFilter = filter;
}
+ /**
+ * Dumps diagnostic information to the specified <code>PrintStream</code>.
+ *
+ * @param out the stream to write the diagnostic information to
+ */
public void dump(PrintStream out)
{
((AbstractElement) getDefaultRootElement()).dump(out, 0);
}
+ /**
+ * Defines a set of methods for managing text attributes for one or more
+ * <code>Document</code>s.
+ *
+ * Replicating {@link AttributeSet}s throughout a <code>Document</code> can
+ * be very expensive. Implementations of this interface are intended to
+ * provide intelligent management of <code>AttributeSet</code>s, eliminating
+ * costly duplication.
+ *
+ * @see StyleContext
+ */
public interface AttributeContext
{
+ /**
+ * Returns an {@link AttributeSet} that contains the attributes
+ * of <code>old</code> plus the new attribute specified by
+ * <code>name</code> and <code>value</code>.
+ *
+ * @param old the attribute set to be merged with the new attribute
+ * @param name the name of the attribute to be added
+ * @param value the value of the attribute to be added
+ *
+ * @return the old attributes plus the new attribute
+ */
AttributeSet addAttribute(AttributeSet old, Object name, Object value);
+ /**
+ * Returns an {@link AttributeSet} that contains the attributes
+ * of <code>old</code> plus the new attributes in <code>attributes</code>.
+ *
+ * @param old the set of attributes where to add the new attributes
+ * @param attributes the attributes to be added
+ *
+ * @return an {@link AttributeSet} that contains the attributes
+ * of <code>old</code> plus the new attributes in
+ * <code>attributes</code>
+ */
AttributeSet addAttributes(AttributeSet old, AttributeSet attributes);
+ /**
+ * Returns an empty {@link AttributeSet}.
+ *
+ * @return an empty {@link AttributeSet}
+ */
AttributeSet getEmptySet();
+ /**
+ * Called to indicate that the attributes in <code>attributes</code> are
+ * no longer used.
+ *
+ * @param attributes the attributes are no longer used
+ */
void reclaim(AttributeSet attributes);
+ /**
+ * Returns a {@link AttributeSet} that has the attribute with the specified
+ * <code>name</code> removed from <code>old</code>.
+ *
+ * @param old the attribute set from which an attribute is removed
+ * @param name the name of the attribute to be removed
+ *
+ * @return the attributes of <code>old</code> minus the attribute
+ * specified by <code>name</code>
+ */
AttributeSet removeAttribute(AttributeSet old, Object name);
+ /**
+ * Removes all attributes in <code>attributes</code> from <code>old</code>
+ * and returns the resulting <code>AttributeSet</code>.
+ *
+ * @param old the set of attributes from which to remove attributes
+ * @param attributes the attributes to be removed from <code>old</code>
+ *
+ * @return the attributes of <code>old</code> minus the attributes in
+ * <code>attributes</code>
+ */
AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes);
+ /**
+ * Removes all attributes specified by <code>names</code> from
+ * <code>old</code> and returns the resulting <code>AttributeSet</code>.
+ *
+ * @param old the set of attributes from which to remove attributes
+ * @param names the names of the attributes to be removed from
+ * <code>old</code>
+ *
+ * @return the attributes of <code>old</code> minus the attributes in
+ * <code>attributes</code>
+ */
AttributeSet removeAttributes(AttributeSet old, Enumeration names);
}
+ /**
+ * A sequence of data that can be edited. This is were the actual content
+ * in <code>AbstractDocument</code>'s is stored.
+ */
public interface Content
{
+ /**
+ * Creates a {@link Position} that keeps track of the location at
+ * <code>offset</code>.
+ *
+ * @return a {@link Position} that keeps track of the location at
+ * <code>offset</code>.
+ *
+ * @throw BadLocationException if <code>offset</code> is not a valid
+ * location in this <code>Content</code> model
+ */
Position createPosition(int offset) throws BadLocationException;
+ /**
+ * Returns the length of the content.
+ *
+ * @return the length of the content
+ */
int length();
+ /**
+ * Inserts a string into the content model.
+ *
+ * @param where the offset at which to insert the string
+ * @param str the string to be inserted
+ *
+ * @return an <code>UndoableEdit</code> or <code>null</code> if undo is
+ * not supported by this <code>Content</code> model
+ *
+ * @throws BadLocationException if <code>where</code> is not a valid
+ * location in this <code>Content</code> model
+ */
UndoableEdit insertString(int where, String str)
throws BadLocationException;
+ /**
+ * Removes a piece of content from the content model.
+ *
+ * @param where the offset at which to remove content
+ * @param nitems the number of characters to be removed
+ *
+ * @return an <code>UndoableEdit</code> or <code>null</code> if undo is
+ * not supported by this <code>Content</code> model
+ *
+ * @throws BadLocationException if <code>where</code> is not a valid
+ * location in this <code>Content</code> model
+ */
UndoableEdit remove(int where, int nitems) throws BadLocationException;
+ /**
+ * Returns a piece of content.
+ *
+ * @param where the start offset of the requested fragment
+ * @param len the length of the requested fragment
+ *
+ * @return the requested fragment
+ * @throws BadLocationException if <code>offset</code> or
+ * <code>offset + len</code>is not a valid
+ * location in this <code>Content</code> model
+ */
String getString(int where, int len) throws BadLocationException;
+ /**
+ * Fetches a piece of content and stores it in <code>txt</code>.
+ *
+ * @param where the start offset of the requested fragment
+ * @param len the length of the requested fragment
+ * @param txt the <code>Segment</code> where to fragment is stored into
+ *
+ * @throws BadLocationException if <code>offset</code> or
+ * <code>offset + len</code>is not a valid
+ * location in this <code>Content</code> model
+ */
void getChars(int where, int len, Segment txt) throws BadLocationException;
}
+ /**
+ * An abstract base implementation of the {@link Element} interface.
+ */
public abstract class AbstractElement
implements Element, MutableAttributeSet, TreeNode, Serializable
{
+ /** The serial version UID for AbstractElement. */
private static final long serialVersionUID = 1265312733007397733L;
+
+ /** The number of characters that this Element spans. */
int count;
+
+ /** The starting offset of this Element. */
int offset;
+ /** The attributes of this Element. */
AttributeSet attributes;
+ /** The parent element. */
Element element_parent;
+ /** The parent in the TreeNode interface. */
TreeNode tree_parent;
+
+ /** The children of this element. */
Vector tree_children;
+ /**
+ * Creates a new instance of <code>AbstractElement</code> with a
+ * specified parent <code>Element</code> and <code>AttributeSet</code>.
+ *
+ * @param p the parent of this <code>AbstractElement</code>
+ * @param s the attributes to be assigned to this
+ * <code>AbstractElement</code>
+ */
public AbstractElement(Element p, AttributeSet s)
{
element_parent = p;
- attributes = s;
+ AttributeContext ctx = getAttributeContext();
+ attributes = ctx.getEmptySet();
+ if (s != null)
+ attributes = ctx.addAttributes(attributes, s);
}
- // TreeNode implementation
-
+ /**
+ * Returns the child nodes of this <code>Element</code> as an
+ * <code>Enumeration</code> of {@link TreeNode}s.
+ *
+ * @return the child nodes of this <code>Element</code> as an
+ * <code>Enumeration</code> of {@link TreeNode}s
+ */
public abstract Enumeration children();
-
+
+ /**
+ * Returns <code>true</code> if this <code>AbstractElement</code>
+ * allows children.
+ *
+ * @return <code>true</code> if this <code>AbstractElement</code>
+ * allows children
+ */
public abstract boolean getAllowsChildren();
-
+
+ /**
+ * Returns the child of this <code>AbstractElement</code> at
+ * <code>index</code>.
+ *
+ * @param index the position in the child list of the child element to
+ * be returned
+ *
+ * @return the child of this <code>AbstractElement</code> at
+ * <code>index</code>
+ */
public TreeNode getChildAt(int index)
{
return (TreeNode) tree_children.get(index);
}
-
+
+ /**
+ * Returns the number of children of this <code>AbstractElement</code>.
+ *
+ * @return the number of children of this <code>AbstractElement</code>
+ */
public int getChildCount()
{
return tree_children.size();
}
-
+
+ /**
+ * Returns the index of a given child <code>TreeNode</code> or
+ * <code>-1</code> if <code>node</code> is not a child of this
+ * <code>AbstractElement</code>.
+ *
+ * @param node the node for which the index is requested
+ *
+ * @return the index of a given child <code>TreeNode</code> or
+ * <code>-1</code> if <code>node</code> is not a child of this
+ * <code>AbstractElement</code>
+ */
public int getIndex(TreeNode node)
{
return tree_children.indexOf(node);
}
+ /**
+ * Returns the parent <code>TreeNode</code> of this
+ * <code>AbstractElement</code> or <code>null</code> if this element
+ * has no parent.
+ *
+ * @return the parent <code>TreeNode</code> of this
+ * <code>AbstractElement</code> or <code>null</code> if this
+ * element has no parent
+ */
public TreeNode getParent()
{
return tree_parent;
}
+ /**
+ * Returns <code>true</code> if this <code>AbstractElement</code> is a
+ * leaf element, <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if this <code>AbstractElement</code> is a
+ * leaf element, <code>false</code> otherwise
+ */
public abstract boolean isLeaf();
-
- // MutableAttributeSet support
-
+ /**
+ * Adds an attribute to this element.
+ *
+ * @param name the name of the attribute to be added
+ * @param value the value of the attribute to be added
+ */
public void addAttribute(Object name, Object value)
{
attributes = getAttributeContext().addAttribute(attributes, name, value);
}
+ /**
+ * Adds a set of attributes to this element.
+ *
+ * @param attrs the attributes to be added to this element
+ */
public void addAttributes(AttributeSet attrs)
{
attributes = getAttributeContext().addAttributes(attributes, attrs);
}
+ /**
+ * Removes an attribute from this element.
+ *
+ * @param name the name of the attribute to be removed
+ */
public void removeAttribute(Object name)
{
attributes = getAttributeContext().removeAttribute(attributes, name);
}
+ /**
+ * Removes a set of attributes from this element.
+ *
+ * @param attrs the attributes to be removed
+ */
public void removeAttributes(AttributeSet attrs)
{
attributes = getAttributeContext().removeAttributes(attributes, attrs);
}
+ /**
+ * Removes a set of attribute from this element.
+ *
+ * @param names the names of the attributes to be removed
+ */
public void removeAttributes(Enumeration names)
{
attributes = getAttributeContext().removeAttributes(attributes, names);
}
+ /**
+ * Sets the parent attribute set against which the element can resolve
+ * attributes that are not defined in itself.
+ *
+ * @param parent the resolve parent to set
+ */
public void setResolveParent(AttributeSet parent)
{
- attributes = getAttributeContext().addAttribute(attributes, ResolveAttribute, parent);
+ attributes = getAttributeContext().addAttribute(attributes,
+ ResolveAttribute,
+ parent);
}
-
- // AttributeSet interface support
-
+ /**
+ * Returns <code>true</code> if this element contains the specified
+ * attribute.
+ *
+ * @param name the name of the attribute to check
+ * @param value the value of the attribute to check
+ *
+ * @return <code>true</code> if this element contains the specified
+ * attribute
+ */
public boolean containsAttribute(Object name, Object value)
{
return attributes.containsAttribute(name, value);
}
+ /**
+ * Returns <code>true</code> if this element contains all of the
+ * specified attributes.
+ *
+ * @param attrs the attributes to check
+ *
+ * @return <code>true</code> if this element contains all of the
+ * specified attributes
+ */
public boolean containsAttributes(AttributeSet attrs)
{
return attributes.containsAttributes(attrs);
}
+ /**
+ * Returns a copy of the attributes of this element.
+ *
+ * @return a copy of the attributes of this element
+ */
public AttributeSet copyAttributes()
{
return attributes.copyAttributes();
}
+ /**
+ * Returns the attribute value with the specified key. If this attribute
+ * is not defined in this element and this element has a resolving
+ * parent, the search goes upward to the resolve parent chain.
+ *
+ * @param key the key of the requested attribute
+ *
+ * @return the attribute value for <code>key</code> of <code>null</code>
+ * if <code>key</code> is not found locally and cannot be resolved
+ * in this element's resolve parents
+ */
public Object getAttribute(Object key)
{
return attributes.getAttribute(key);
}
+ /**
+ * Returns the number of defined attributes in this element.
+ *
+ * @return the number of defined attributes in this element
+ */
public int getAttributeCount()
{
return attributes.getAttributeCount();
}
-
+
+ /**
+ * Returns the names of the attributes of this element.
+ *
+ * @return the names of the attributes of this element
+ */
public Enumeration getAttributeNames()
{
return attributes.getAttributeNames();
}
-
+
+ /**
+ * Returns the resolve parent of this element.
+ *
+ * @return the resolve parent of this element
+ *
+ * @see #setResolveParent(AttributeSet)
+ */
public AttributeSet getResolveParent()
{
return attributes.getResolveParent();
}
+ /**
+ * Returns <code>true</code> if an attribute with the specified name
+ * is defined in this element, <code>false</code> otherwise.
+ *
+ * @param attrName the name of the requested attributes
+ *
+ * @return <code>true</code> if an attribute with the specified name
+ * is defined in this element, <code>false</code> otherwise
+ */
public boolean isDefined(Object attrName)
{
return attributes.isDefined(attrName);
}
-
+
+ /**
+ * Returns <code>true</code> if the specified <code>AttributeSet</code>
+ * is equal to this element's <code>AttributeSet</code>, <code>false</code>
+ * otherwise.
+ *
+ * @param attrs the attributes to compare this element to
+ *
+ * @return <code>true</code> if the specified <code>AttributeSet</code>
+ * is equal to this element's <code>AttributeSet</code>,
+ * <code>false</code> otherwise
+ */
public boolean isEqual(AttributeSet attrs)
{
return attributes.isEqual(attrs);
}
- // Element interface support
-
+ /**
+ * Returns the attributes of this element.
+ *
+ * @return the attributes of this element
+ */
public AttributeSet getAttributes()
{
- return attributes;
+ return this;
}
+ /**
+ * Returns the {@link Document} to which this element belongs.
+ *
+ * @return the {@link Document} to which this element belongs
+ */
public Document getDocument()
{
return AbstractDocument.this;
}
-
+
+ /**
+ * Returns the child element at the specified <code>index</code>.
+ *
+ * @param index the index of the requested child element
+ *
+ * @return the requested element
+ */
public abstract Element getElement(int index);
-
+
+ /**
+ * Returns the name of this element.
+ *
+ * @return the name of this element
+ */
public String getName()
{
return (String) getAttribute(NameAttribute);
}
-
+
+ /**
+ * Returns the parent element of this element.
+ *
+ * @return the parent element of this element
+ */
public Element getParentElement()
{
return element_parent;
}
-
+
+ /**
+ * Returns the offset inside the document model that is after the last
+ * character of this element.
+ *
+ * @return the offset inside the document model that is after the last
+ * character of this element
+ */
public abstract int getEndOffset();
-
+
+ /**
+ * Returns the number of child elements of this element.
+ *
+ * @return the number of child elements of this element
+ */
public abstract int getElementCount();
-
+
+ /**
+ * Returns the index of the child element that spans the specified
+ * offset in the document model.
+ *
+ * @param offset the offset for which the responsible element is searched
+ *
+ * @return the index of the child element that spans the specified
+ * offset in the document model
+ */
public abstract int getElementIndex(int offset);
-
+
+ /**
+ * Returns the start offset if this element inside the document model.
+ *
+ * @return the start offset if this element inside the document model
+ */
public abstract int getStartOffset();
- private void dumpElement(PrintStream stream, String indent, Element element)
+ /**
+ * Prints diagnostic information to the specified stream.
+ *
+ * @param stream the stream to dump to
+ * @param indent the indentation level
+ * @param element the element to be dumped
+ */
+ private void dumpElement(PrintStream stream, String indent,
+ Element element)
{
+ // FIXME: Should the method be removed?
System.out.println(indent + "<" + element.getName() +">");
-
+
if (element.isLeaf())
{
int start = element.getStartOffset();
@@ -626,6 +1378,12 @@ public abstract class AbstractDocument
}
catch (BadLocationException e)
{
+ AssertionError error =
+ new AssertionError("BadLocationException should not be "
+ + "thrown here. start = " + start
+ + ", end = " + end);
+ error.initCause(e);
+ throw error;
}
System.out.println(indent + " ["
+ start + ","
@@ -638,7 +1396,13 @@ public abstract class AbstractDocument
dumpElement(stream, indent + " ", element.getElement(i));
}
}
-
+
+ /**
+ * Prints diagnostic output to the specified stream.
+ *
+ * @param stream the stream to write to
+ * @param indent the indentation level
+ */
public void dump(PrintStream stream, int indent)
{
String indentStr = "";
@@ -648,17 +1412,36 @@ public abstract class AbstractDocument
}
}
+ /**
+ * An implementation of {@link Element} to represent composite
+ * <code>Element</code>s that contain other <code>Element</code>s.
+ */
public class BranchElement extends AbstractElement
{
+ /** The serial version UID for BranchElement. */
private static final long serialVersionUID = -8595176318868717313L;
-
+
+ /** The child elements of this BranchElement. */
private Element[] children = new Element[0];
+ /**
+ * Creates a new <code>BranchElement</code> with the specified
+ * parent and attributes.
+ *
+ * @param parent the parent element of this <code>BranchElement</code>
+ * @param attributes the attributes to set on this
+ * <code>BranchElement</code>
+ */
public BranchElement(Element parent, AttributeSet attributes)
{
super(parent, attributes);
}
+ /**
+ * Returns the children of this <code>BranchElement</code>.
+ *
+ * @return the children of this <code>BranchElement</code>
+ */
public Enumeration children()
{
if (children.length == 0)
@@ -672,11 +1455,25 @@ public abstract class AbstractDocument
return tmp.elements();
}
+ /**
+ * Returns <code>true</code> since <code>BranchElements</code> allow
+ * child elements.
+ *
+ * @return <code>true</code> since <code>BranchElements</code> allow
+ * child elements
+ */
public boolean getAllowsChildren()
{
return true;
}
+ /**
+ * Returns the child element at the specified <code>index</code>.
+ *
+ * @param index the index of the requested child element
+ *
+ * @return the requested element
+ */
public Element getElement(int index)
{
if (index < 0 || index >= children.length)
@@ -685,47 +1482,113 @@ public abstract class AbstractDocument
return children[index];
}
+ /**
+ * Returns the number of child elements of this element.
+ *
+ * @return the number of child elements of this element
+ */
public int getElementCount()
{
return children.length;
}
+ /**
+ * Returns the index of the child element that spans the specified
+ * offset in the document model.
+ *
+ * @param offset the offset for which the responsible element is searched
+ *
+ * @return the index of the child element that spans the specified
+ * offset in the document model
+ */
public int getElementIndex(int offset)
{
+ // If we have no children, return -1.
+ if (getElementCount() == 0)
+ return - 1;
+
// XXX: There is surely a better algorithm
// as beginning from first element each time.
for (int index = 0; index < children.length; ++index)
{
- Element elem = children[index];
+ Element elem = children[index];
- if ((elem.getStartOffset() <= offset)
- && (offset < elem.getEndOffset()))
- return index;
+ if ((elem.getStartOffset() <= offset)
+ && (offset < elem.getEndOffset()))
+ return index;
}
- return 0;
+ // If offset is greater than the index of the last element, return
+ // the index of the last element.
+ return getElementCount() - 1;
}
+ /**
+ * Returns the offset inside the document model that is after the last
+ * character of this element.
+ * This is the end offset of the last child element. If this element
+ * has no children, this method throws a <code>NullPointerException</code>.
+ *
+ * @return the offset inside the document model that is after the last
+ * character of this element
+ *
+ * @throws NullPointerException if this branch element has no children
+ */
public int getEndOffset()
{
+ if (getElementCount() == 0)
+ throw new NullPointerException("This BranchElement has no children.");
return children[children.length - 1].getEndOffset();
}
+ /**
+ * Returns the name of this element. This is {@link #ParagraphElementName}
+ * in this case.
+ *
+ * @return the name of this element
+ */
public String getName()
{
return ParagraphElementName;
}
+ /**
+ * Returns the start offset of this element inside the document model.
+ * This is the start offset of the first child element. If this element
+ * has no children, this method throws a <code>NullPointerException</code>.
+ *
+ * @return the start offset of this element inside the document model
+ *
+ * @throws NullPointerException if this branch element has no children
+ */
public int getStartOffset()
{
+ if (getElementCount() == 0)
+ throw new NullPointerException("This BranchElement has no children.");
return children[0].getStartOffset();
}
+ /**
+ * Returns <code>false</code> since <code>BranchElement</code> are no
+ * leafes.
+ *
+ * @return <code>false</code> since <code>BranchElement</code> are no
+ * leafes
+ */
public boolean isLeaf()
{
return false;
}
+ /**
+ * Returns the <code>Element</code> at the specified <code>Document</code>
+ * offset.
+ *
+ * @return the <code>Element</code> at the specified <code>Document</code>
+ * offset
+ *
+ * @see #getElementIndex(int)
+ */
public Element positionToElement(int position)
{
// XXX: There is surely a better algorithm
@@ -742,6 +1605,13 @@ public abstract class AbstractDocument
return null;
}
+ /**
+ * Replaces a set of child elements with a new set of child elemens.
+ *
+ * @param offset the start index of the elements to be removed
+ * @param length the number of elements to be removed
+ * @param elements the new elements to be inserted
+ */
public void replace(int offset, int length, Element[] elements)
{
Element[] target = new Element[children.length - length
@@ -754,6 +1624,11 @@ public abstract class AbstractDocument
children = target;
}
+ /**
+ * Returns a string representation of this element.
+ *
+ * @return a string representation of this element
+ */
public String toString()
{
return ("BranchElement(" + getName() + ") "
@@ -761,59 +1636,157 @@ public abstract class AbstractDocument
}
}
+ /**
+ * Stores the changes when a <code>Document</code> is beeing modified.
+ */
public class DefaultDocumentEvent extends CompoundEdit
implements DocumentEvent
{
+ /** The serial version UID of DefaultDocumentEvent. */
private static final long serialVersionUID = -7406103236022413522L;
-
+
+ /** The starting offset of the change. */
private int offset;
+
+ /** The length of the change. */
private int length;
+
+ /** The type of change. */
private DocumentEvent.EventType type;
+ /**
+ * Maps <code>Element</code> to their change records.
+ */
+ Hashtable changes;
+
+ /**
+ * Creates a new <code>DefaultDocumentEvent</code>.
+ *
+ * @param offset the starting offset of the change
+ * @param length the length of the change
+ * @param type the type of change
+ */
public DefaultDocumentEvent(int offset, int length,
DocumentEvent.EventType type)
{
this.offset = offset;
this.length = length;
this.type = type;
+ changes = new Hashtable();
}
+ /**
+ * Adds an UndoableEdit to this <code>DocumentEvent</code>. If this
+ * edit is an instance of {@link ElementEdit}, then this record can
+ * later be fetched by calling {@link #getChange}.
+ *
+ * @param edit the undoable edit to add
+ */
+ public boolean addEdit(UndoableEdit edit)
+ {
+ // XXX - Fully qualify ElementChange to work around gcj bug #2499.
+ if (edit instanceof DocumentEvent.ElementChange)
+ {
+ DocumentEvent.ElementChange elEdit =
+ (DocumentEvent.ElementChange) edit;
+ changes.put(elEdit.getElement(), elEdit);
+ }
+ return super.addEdit(edit);
+ }
+
+ /**
+ * Returns the document that has been modified.
+ *
+ * @return the document that has been modified
+ */
public Document getDocument()
{
return AbstractDocument.this;
}
+ /**
+ * Returns the length of the modification.
+ *
+ * @return the length of the modification
+ */
public int getLength()
{
return length;
}
+ /**
+ * Returns the start offset of the modification.
+ *
+ * @return the start offset of the modification
+ */
public int getOffset()
{
return offset;
}
+ /**
+ * Returns the type of the modification.
+ *
+ * @return the type of the modification
+ */
public DocumentEvent.EventType getType()
{
return type;
}
+ /**
+ * Returns the changes for an element.
+ *
+ * @param elem the element for which the changes are requested
+ *
+ * @return the changes for <code>elem</code> or <code>null</code> if
+ * <code>elem</code> has not been changed
+ */
public DocumentEvent.ElementChange getChange(Element elem)
{
- return null;
+ // XXX - Fully qualify ElementChange to work around gcj bug #2499.
+ return (DocumentEvent.ElementChange) changes.get(elem);
}
}
+ /**
+ * An implementation of {@link DocumentEvent.ElementChange} to be added
+ * to {@link DefaultDocumentEvent}s.
+ */
public static class ElementEdit extends AbstractUndoableEdit
implements DocumentEvent.ElementChange
{
+ /** The serial version UID of ElementEdit. */
private static final long serialVersionUID = -1216620962142928304L;
+ /**
+ * The changed element.
+ */
private Element elem;
+
+ /**
+ * The index of the change.
+ */
private int index;
+
+ /**
+ * The removed elements.
+ */
private Element[] removed;
+
+ /**
+ * The added elements.
+ */
private Element[] added;
+ /**
+ * Creates a new <code>ElementEdit</code>.
+ *
+ * @param elem the changed element
+ * @param index the index of the change
+ * @param removed the removed elements
+ * @param added the added elements
+ */
public ElementEdit(Element elem, int index,
Element[] removed, Element[] added)
{
@@ -823,86 +1796,211 @@ public abstract class AbstractDocument
this.added = added;
}
+ /**
+ * Returns the added elements.
+ *
+ * @return the added elements
+ */
public Element[] getChildrenAdded()
{
return added;
}
-
+
+ /**
+ * Returns the removed elements.
+ *
+ * @return the removed elements
+ */
public Element[] getChildrenRemoved()
{
return removed;
}
+ /**
+ * Returns the changed element.
+ *
+ * @return the changed element
+ */
public Element getElement()
{
return elem;
}
+ /**
+ * Returns the index of the change.
+ *
+ * @return the index of the change
+ */
public int getIndex()
{
return index;
}
}
+ /**
+ * An implementation of {@link Element} that represents a leaf in the
+ * document structure. This is used to actually store content.
+ */
public class LeafElement extends AbstractElement
{
+ /** The serial version UID of LeafElement. */
private static final long serialVersionUID = 5115368706941283802L;
- int start;
- int end;
+ /** Manages the start offset of this element. */
+ Position startPos;
+
+ /** Manages the end offset of this element. */
+ Position endPos;
+
+ /**
+ * Creates a new <code>LeafElement</code>.
+ *
+ * @param parent the parent of this <code>LeafElement</code>
+ * @param attributes the attributes to be set
+ * @param start the start index of this element inside the document model
+ * @param end the end index of this element inside the document model
+ */
public LeafElement(Element parent, AttributeSet attributes, int start,
int end)
{
super(parent, attributes);
- this.start = start;
- this.end = end;
+ {
+ try
+ {
+ if (parent != null)
+ {
+ startPos = parent.getDocument().createPosition(start);
+ endPos = parent.getDocument().createPosition(end);
+ }
+ else
+ {
+ startPos = createPosition(start);
+ endPos = createPosition(end);
+ }
+ }
+ catch (BadLocationException ex)
+ {
+ AssertionError as;
+ as = new AssertionError("BadLocationException thrown "
+ + "here. start=" + start
+ + ", end=" + end
+ + ", length=" + getLength());
+ as.initCause(ex);
+ throw as;
+ }
+ }
}
+ /**
+ * Returns <code>null</code> since <code>LeafElement</code>s cannot have
+ * children.
+ *
+ * @return <code>null</code> since <code>LeafElement</code>s cannot have
+ * children
+ */
public Enumeration children()
{
return null;
}
+ /**
+ * Returns <code>false</code> since <code>LeafElement</code>s cannot have
+ * children.
+ *
+ * @return <code>false</code> since <code>LeafElement</code>s cannot have
+ * children
+ */
public boolean getAllowsChildren()
{
return false;
}
+ /**
+ * Returns <code>null</code> since <code>LeafElement</code>s cannot have
+ * children.
+ *
+ * @return <code>null</code> since <code>LeafElement</code>s cannot have
+ * children
+ */
public Element getElement(int index)
{
return null;
}
+ /**
+ * Returns <code>0</code> since <code>LeafElement</code>s cannot have
+ * children.
+ *
+ * @return <code>0</code> since <code>LeafElement</code>s cannot have
+ * children
+ */
public int getElementCount()
{
return 0;
}
+ /**
+ * Returns <code>-1</code> since <code>LeafElement</code>s cannot have
+ * children.
+ *
+ * @return <code>-1</code> since <code>LeafElement</code>s cannot have
+ * children
+ */
public int getElementIndex(int offset)
{
return -1;
}
+ /**
+ * Returns the end offset of this <code>Element</code> inside the
+ * document.
+ *
+ * @return the end offset of this <code>Element</code> inside the
+ * document
+ */
public int getEndOffset()
{
- return end;
+ return endPos.getOffset();
}
+ /**
+ * Returns the name of this <code>Element</code>. This is
+ * {@link #ContentElementName} in this case.
+ *
+ * @return the name of this <code>Element</code>
+ */
public String getName()
{
return ContentElementName;
}
+ /**
+ * Returns the start offset of this <code>Element</code> inside the
+ * document.
+ *
+ * @return the start offset of this <code>Element</code> inside the
+ * document
+ */
public int getStartOffset()
{
- return start;
+ return startPos.getOffset();
}
+ /**
+ * Returns <code>true</code>.
+ *
+ * @return <code>true</code>
+ */
public boolean isLeaf()
{
return true;
}
+ /**
+ * Returns a string representation of this <code>Element</code>.
+ *
+ * @return a string representation of this <code>Element</code>
+ */
public String toString()
{
return ("LeafElement(" + getName() + ") "
diff --git a/libjava/classpath/javax/swing/text/AttributeSet.java b/libjava/classpath/javax/swing/text/AttributeSet.java
index 87e7b98af22..2f1f1890bae 100644
--- a/libjava/classpath/javax/swing/text/AttributeSet.java
+++ b/libjava/classpath/javax/swing/text/AttributeSet.java
@@ -1,5 +1,5 @@
/* AttributeSet.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,34 +39,153 @@ package javax.swing.text;
import java.util.Enumeration;
+/**
+ * A set of attributes. An attribute has a key and a value. They typically
+ * describe features of a piece of text that make up its graphical
+ * representation.
+ *
+ * An <code>AttributeSet</code> may have a resolving parent,
+ * that is another <code>AttributeSet</code> that is searched for attribute
+ * keys that are not stored locally in this <code>AttributeSet</code>.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public interface AttributeSet
{
+ /**
+ * Used as keys to identify character-run attributes.
+ */
static interface CharacterAttribute
{
}
+ /**
+ * Used as keys to identify color attributes.
+ */
static interface ColorAttribute
{
}
+ /**
+ * Used as keys to identify font attributes.
+ */
static interface FontAttribute
{
}
+ /**
+ * Used as keys to identify paragraph level attributes.
+ */
static interface ParagraphAttribute
{
}
+ /**
+ * Key of the attribute that is used to describe the name of an
+ * <code>AttributeSet</code>.
+ */
Object NameAttribute = StyleConstants.NameAttribute;
+
+ /**
+ * Key of the attribute that is used to identify the resolving parent of
+ * an <code>AttributeSet</code>.
+ */
Object ResolveAttribute = StyleConstants.ResolveAttribute;
+ /**
+ * Returns <code>true</code> if this <code>AttributeSet</code> contains
+ * an attribute with the specified <code>name</code> and <code>value</code>,
+ * <code>false</code> otherwise.
+ *
+ * @param name the name of the requested attribute
+ * @param the value of the requested attribute
+ *
+ * @return <code>true</code> if this <code>AttributeSet</code> contains
+ * an attribute with the specified <code>name</code> and
+ * <code>value</code>, <code>false</code> otherwise
+ */
boolean containsAttribute(Object name, Object value);
+
+ /**
+ * Returns <code>true</code> of this <code>AttributeSet</code> contains all
+ * of the specified <code>attributes</code>.
+ *
+ * @param attributes the requested attributes
+ *
+ * @return <code>true</code> of this <code>AttributeSet</code> contains all
+ * of the specified <code>attributes</code>
+ */
boolean containsAttributes(AttributeSet attributes);
+
+ /**
+ * Creates and returns a copy of this <code>AttributeSet</code>.
+ *
+ * @return a copy of this <code>AttributeSet</code>
+ */
AttributeSet copyAttributes();
+
+ /**
+ * Returns the attribute with the specified <code>key</code> or
+ * <code>null</code> if no such attribute is defined in this
+ * <code>AttributeSet</code> and its resolving parents.
+ *
+ * @param key the key of the attribute that is looked up
+ *
+ * @return the attribute with the specified <code>key</code> or
+ * <code>null</code> if no such attribute is defined in this
+ * <code>AttributeSet</code> and its resolving parents
+ */
Object getAttribute(Object key);
+
+ /**
+ * Returns the number of attributes that are stored locally in this
+ * <code>AttributeSet</code>.
+ *
+ * @return the number of attributes that are stored locally in this
+ * <code>AttributeSet</code>
+ */
int getAttributeCount();
+
+ /**
+ * Returns the names of the attributes that are stored in this
+ * <code>AttributeSet</code>.
+ *
+ * @return the names of the attributes that are stored in this
+ * <code>AttributeSet</code>
+ */
Enumeration getAttributeNames();
+
+ /**
+ * Returns the resolving parent of this <code>AttributeSet</code>.
+ * If a key is not stored locally, then a {@link #getAttribute(Object)}
+ * request is resolved up in the resolving parent of this
+ * <code>AttributeSet</code>.
+ *
+ * @return the resolving parent of this <code>AttributeSet</code>
+ */
AttributeSet getResolveParent();
+
+ /**
+ * Returns <code>true</code> if an attribute with the specified name is
+ * defined locally in this <code>AttributeSet</code>, without resolving
+ * through the resolving parents.
+ *
+ * @return <code>true</code> if an attribute with the specified name is
+ * defined locally in this <code>AttributeSet</code>
+ */
boolean isDefined(Object attrName);
+
+ /**
+ * Returns <code>true</code> if all of the attributes in <code>attr</code>
+ * are equal to the attributes in this <code>AttributeSet</code>,
+ * <code>false</code> otherwise.
+ *
+ * @param attr the attributes to be compared to <code>this</code>
+ *
+ * @return <code>true</code> if all of the attributes in <code>attr</code>
+ * are equal to the attributes in this <code>AttributeSet</code>,
+ * <code>false</code> otherwise
+ */
boolean isEqual(AttributeSet attr);
}
diff --git a/libjava/classpath/javax/swing/text/BadLocationException.java b/libjava/classpath/javax/swing/text/BadLocationException.java
index e1a2ebcc604..70591402cac 100644
--- a/libjava/classpath/javax/swing/text/BadLocationException.java
+++ b/libjava/classpath/javax/swing/text/BadLocationException.java
@@ -1,5 +1,5 @@
/* BadLocationException.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,17 +37,28 @@ exception statement from your version. */
package javax.swing.text;
+/**
+ * Indicates that an invalid location within a <code>Document</code> has been
+ * accessed.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public class BadLocationException extends Exception
{
+ /** The serial version UID for BadLocationException. */
private static final long serialVersionUID = -7712259886815656766L;
-
+
+ /**
+ * The invalid location.
+ */
int offset;
/**
* Constructs a <code>BadLocationException</code>
*
- * @param str A string indicating what was wrong with the arguments
- * @param offset Offset within the document that was requested &gt;= 0
+ * @param str a string indicating what was wrong with the arguments
+ * @param offset offset within the document that was requested &gt;= 0
*/
public BadLocationException(String str, int offset)
{
@@ -56,7 +67,9 @@ public class BadLocationException extends Exception
}
/**
- * Returns the offset into the document that was not legal
+ * Returns the offset into the document that was not legal.
+ *
+ * @return the offset into the document that was not legal
*/
public int offsetRequested()
{
diff --git a/libjava/classpath/javax/swing/text/Caret.java b/libjava/classpath/javax/swing/text/Caret.java
index 46072ef19c5..d6411905dda 100644
--- a/libjava/classpath/javax/swing/text/Caret.java
+++ b/libjava/classpath/javax/swing/text/Caret.java
@@ -1,5 +1,5 @@
/* Caret.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,39 +43,165 @@ import java.awt.Point;
import javax.swing.event.ChangeListener;
+/**
+ * Defines the method to be implemented by a caret that can be used in Swing
+ * text components.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public interface Caret
{
+ /**
+ * Registers a {@link ChangeListener} that is notified whenever that state
+ * of this <code>Caret</code> changes.
+ *
+ * @param l the listener to register to this caret
+ */
void addChangeListener(ChangeListener l);
+
+ /**
+ * Removes a {@link ChangeListener} from the list of registered listeners.
+ *
+ * @param l the listener to remove
+ */
+ void removeChangeListener(ChangeListener l);
+
+ /**
+ * Installs this <code>Caret</code> on the specified text component. This
+ * usually involves setting up listeners.
+ *
+ * This method is called by {@link JTextComponent#setCaret(Caret)} after
+ * this caret has been set on the text component.
+ *
+ * @param c the text component to install this caret to
+ */
+ void install(JTextComponent c);
+ /**
+ * Deinstalls this <code>Caret</code> from the specified text component.
+ * This usually involves removing listeners from the text component.
+ *
+ * This method is called by {@link JTextComponent#setCaret(Caret)} before
+ * this caret is removed from the text component.
+ *
+ * @param c the text component to deinstall this caret from
+ */
void deinstall(JTextComponent c);
-
+
+ /**
+ * Returns the blink rate of this <code>Caret</code> in milliseconds.
+ * A value of <code>0</code> means that the caret does not blink.
+ *
+ * @return the blink rate of this <code>Caret</code> or <code>0</code> if
+ * this caret does not blink
+ */
int getBlinkRate();
+
+ /**
+ * Sets the blink rate of this <code>Caret</code> in milliseconds.
+ * A value of <code>0</code> means that the caret does not blink.
+ *
+ * @param rate the new blink rate to set
+ */
+ void setBlinkRate(int rate);
+ /**
+ * Returns the current position of this <code>Caret</code> within the
+ * <code>Document</code>.
+ *
+ * @return the current position of this <code>Caret</code> within the
+ * <code>Document</code>
+ */
int getDot();
+
+ /**
+ * Sets the current position of this <code>Caret</code> within the
+ * <code>Document</code>. This also sets the <code>mark</code> to the
+ * new location.
+ *
+ * @param dot the new position to be set
+ *
+ * @see #moveDot(int)
+ */
+ void setDot(int dot);
- Point getMagicCaretPosition();
-
- int getMark();
-
- void install(JTextComponent c);
-
- boolean isSelectionVisible();
-
- boolean isVisible();
-
+ /**
+ * Moves the <code>dot</code> location without touching the
+ * <code>mark</code>. This is used when making a selection.
+ *
+ * @param dot the location where to move the dot
+ *
+ * @see #setDot(int)
+ */
void moveDot(int dot);
- void paint(Graphics g);
-
- void removeChangeListener(ChangeListener l);
-
- void setBlinkRate(int rate);
-
- void setDot(int dot);
+ /**
+ * Returns the current position of the <code>mark</code>. The
+ * <code>mark</code> marks the location in the <code>Document</code> that
+ * is the end of a selection. If there is no selection, the <code>mark</code>
+ * is the same as the <code>dot</code>.
+ *
+ * @return the current position of the mark
+ */
+ int getMark();
+ /**
+ * Returns the current visual position of this <code>Caret</code>.
+ *
+ * @return the current visual position of this <code>Caret</code>
+ *
+ * @see #setMagicCaretPosition
+ */
+ Point getMagicCaretPosition();
+
+ /**
+ * Sets the current visual position of this <code>Caret</code>.
+ *
+ * @param p the Point to use for the saved location. May be <code>null</code>
+ * to indicate that there is no visual location
+ */
void setMagicCaretPosition(Point p);
-
+
+ /**
+ * Returns <code>true</code> if the selection is currently visible,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the selection is currently visible,
+ * <code>false</code> otherwise
+ */
+ boolean isSelectionVisible();
+
+ /**
+ * Sets the visiblity state of the selection.
+ *
+ * @param v <code>true</code> if the selection should be visible,
+ * <code>false</code> otherwise
+ */
void setSelectionVisible(boolean v);
-
+
+ /**
+ * Returns <code>true</code> if this <code>Caret</code> is currently visible,
+ * and <code>false</code> if it is not.
+ *
+ * @return <code>true</code> if this <code>Caret</code> is currently visible,
+ * and <code>false</code> if it is not
+ */
+ boolean isVisible();
+
+ /**
+ * Sets the visibility state of the caret. <code>true</code> shows the
+ * <code>Caret</code>, <code>false</code> hides it.
+ *
+ * @param v the visibility to set
+ */
void setVisible(boolean v);
+
+ /**
+ * Paints this <code>Caret</code> to the specified <code>Graphics</code>
+ * context.
+ *
+ * @param g the graphics context to render to
+ */
+ void paint(Graphics g);
}
diff --git a/libjava/classpath/javax/swing/text/ComponentView.java b/libjava/classpath/javax/swing/text/ComponentView.java
index 744d537aec6..f6feda21513 100644
--- a/libjava/classpath/javax/swing/text/ComponentView.java
+++ b/libjava/classpath/javax/swing/text/ComponentView.java
@@ -100,4 +100,22 @@ public class ComponentView extends View
{
return 0;
}
+
+ /**
+ * Maps coordinates from the <code>View</code>'s space into a position
+ * in the document model.
+ *
+ * @param x the x coordinate in the view space
+ * @param y the y coordinate in the view space
+ * @param a the allocation of this <code>View</code>
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates <code>x, y</code>
+ */
+ public int viewToModel(float x, float y, Shape a, Position.Bias b)
+ {
+ // FIXME: Implement this properly.
+ return 0;
+ }
}
diff --git a/libjava/classpath/javax/swing/text/DateFormatter.java b/libjava/classpath/javax/swing/text/DateFormatter.java
index 0e20b771b45..869f9a0900f 100644
--- a/libjava/classpath/javax/swing/text/DateFormatter.java
+++ b/libjava/classpath/javax/swing/text/DateFormatter.java
@@ -54,7 +54,7 @@ public class DateFormatter extends InternationalFormatter
/**
* Creates a new instance using the default {@link DateFormat} object
- * returned by {@link DateFormat#getDateInstance}.
+ * returned by {@link DateFormat#getDateInstance()}.
*/
public DateFormatter()
{
diff --git a/libjava/classpath/javax/swing/text/DefaultCaret.java b/libjava/classpath/javax/swing/text/DefaultCaret.java
index b57b3656384..33c3ae3bf28 100644
--- a/libjava/classpath/javax/swing/text/DefaultCaret.java
+++ b/libjava/classpath/javax/swing/text/DefaultCaret.java
@@ -1,5 +1,5 @@
/* DefaultCaret.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -51,69 +51,203 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
-
+/**
+ * The default implementation of the {@link Caret} interface.
+ *
+ * @author orgininal author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public class DefaultCaret extends Rectangle
implements Caret, FocusListener, MouseListener, MouseMotionListener
{
+ /**
+ * The serial version UID for DefaultCaret.
+ */
private static final long serialVersionUID = 228155774675466193L;
-
+
+ /**
+ * The <code>ChangeEvent</code> that is fired by {@link #fireStateChanged()}.
+ */
protected ChangeEvent changeEvent = new ChangeEvent(this);
+
+ /**
+ * Stores all registered event listeners.
+ */
protected EventListenerList listenerList = new EventListenerList();
-
+
+ /**
+ * The text component in which this caret is installed.
+ */
private JTextComponent textComponent;
-
+
+ /**
+ * Indicates if the selection should be visible or not.
+ */
private boolean selectionVisible = true;
+
+ /**
+ * The blink rate of this <code>Caret</code>.
+ */
private int blinkRate = 500;
+
+ /**
+ * The current dot position.
+ */
private int dot = 0;
+
+ /**
+ * The current mark position.
+ */
private int mark = 0;
+
+ /**
+ * The current visual caret position.
+ */
private Point magicCaretPosition = null;
+
+ /**
+ * Indicates if this <code>Caret</code> is currently visible or not.
+ */
private boolean visible = true;
+
+ /**
+ * The current highlight entry.
+ */
private Object highlightEntry;
+ /**
+ * Moves the caret position when the mouse is dragged over the text
+ * component, modifying the selection accordingly.
+ *
+ * @param event the <code>MouseEvent</code> describing the drag operation
+ */
public void mouseDragged(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Indicates a mouse movement over the text component. Does nothing here.
+ *
+ * @param event the <code>MouseEvent</code> describing the mouse operation
+ */
public void mouseMoved(MouseEvent event)
{
- }
-
+ // Nothing to do here.
+ }
+
+ /**
+ * When the click is received from Button 1 then the following actions
+ * are performed here:
+ *
+ * <ul>
+ * <li>If we receive a double click, the caret position (dot) is set
+ * to the position associated to the mouse click and the word at
+ * this location is selected.</li>
+ * <li>If we receive a triple click, the caret position (dot) is set
+ * to the position associated to the mouse click and the line at
+ * this location is selected.</li>
+ * </ul>
+ *
+ * @param event the <code>MouseEvent</code> describing the click operation
+ */
public void mouseClicked(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Indicates that the mouse has entered the text component. Nothing is done
+ * here.
+ *
+ * @param event the <code>MouseEvent</code> describing the mouse operation
+ */
public void mouseEntered(MouseEvent event)
{
+ // Nothing to do here.
}
+ /**
+ * Indicates that the mouse has exited the text component. Nothing is done
+ * here.
+ *
+ * @param event the <code>MouseEvent</code> describing the mouse operation
+ */
public void mouseExited(MouseEvent event)
{
}
+ /**
+ * If the button 1 is pressed, the caret position is updated to the
+ * position of the mouse click and the text component requests the input
+ * focus if it is enabled. If the SHIFT key is held down, the caret will
+ * be moved, which might select the text between the old and new location.
+ *
+ * @param event the <code>MouseEvent</code> describing the press operation
+ */
public void mousePressed(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Indicates that a mouse button has been released on the text component.
+ * Nothing is done here.
+ *
+ * @param event the <code>MouseEvent</code> describing the mouse operation
+ */
public void mouseReleased(MouseEvent event)
{
+ // Nothing to do here.
}
+ /**
+ * Sets the caret to <code>visible</code> if the text component is editable.
+ *
+ * @param event the <code>FocusEvent</code>
+ */
public void focusGained(FocusEvent event)
{
}
+ /**
+ * Sets the caret to <code>invisible</code>.
+ *
+ * @param event the <code>FocusEvent</code>
+ */
public void focusLost(FocusEvent event)
{
}
+ /**
+ * Moves the caret to the position specified in the <code>MouseEvent</code>.
+ * This will cause a selection if the dot and mark are different.
+ *
+ * @param event the <code>MouseEvent</code> from which to fetch the position
+ */
protected void moveCaret(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Repositions the caret to the position specified in the
+ * <code>MouseEvent</code>.
+ *
+ * @param event the <code>MouseEvent</code> from which to fetch the position
+ */
protected void positionCaret(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Deinstalls this <code>Caret</code> from the specified
+ * <code>JTextComponent</code>. This removes any listeners that have been
+ * registered by this <code>Caret</code>.
+ *
+ * @param c the text component from which to install this caret
+ */
public void deinstall(JTextComponent c)
{
textComponent.removeFocusListener(this);
@@ -122,6 +256,13 @@ public class DefaultCaret extends Rectangle
textComponent = null;
}
+ /**
+ * Installs this <code>Caret</code> on the specified
+ * <code>JTextComponent</code>. This registers a couple of listeners
+ * on the text component.
+ *
+ * @param c the text component on which to install this caret
+ */
public void install(JTextComponent c)
{
textComponent = c;
@@ -131,16 +272,37 @@ public class DefaultCaret extends Rectangle
repaint();
}
+ /**
+ * Sets the current visual position of this <code>Caret</code>.
+ *
+ * @param p the Point to use for the saved location. May be <code>null</code>
+ * to indicate that there is no visual location
+ */
public void setMagicCaretPosition(Point p)
{
magicCaretPosition = p;
}
+ /**
+ * Returns the current visual position of this <code>Caret</code>.
+ *
+ * @return the current visual position of this <code>Caret</code>
+ *
+ * @see #setMagicCaretPosition
+ */
public Point getMagicCaretPosition()
{
return magicCaretPosition;
}
+ /**
+ * Returns the current position of the <code>mark</code>. The
+ * <code>mark</code> marks the location in the <code>Document</code> that
+ * is the end of a selection. If there is no selection, the <code>mark</code>
+ * is the same as the <code>dot</code>.
+ *
+ * @return the current position of the mark
+ */
public int getMark()
{
return mark;
@@ -181,6 +343,12 @@ public class DefaultCaret extends Rectangle
}
}
+ /**
+ * Sets the visiblity state of the selection.
+ *
+ * @param v <code>true</code> if the selection should be visible,
+ * <code>false</code> otherwise
+ */
public void setSelectionVisible(boolean v)
{
if (selectionVisible == v)
@@ -191,17 +359,35 @@ public class DefaultCaret extends Rectangle
repaint();
}
+ /**
+ * Returns <code>true</code> if the selection is currently visible,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the selection is currently visible,
+ * <code>false</code> otherwise
+ */
public boolean isSelectionVisible()
{
return selectionVisible;
}
+ /**
+ * Causes the <code>Caret</code> to repaint itself.
+ */
protected final void repaint()
{
+ // FIXME: Is this good? This possibly causes alot of the component
+ // hierarchy to be repainted on every caret blink.
if (textComponent != null)
textComponent.repaint();
}
+ /**
+ * Paints this <code>Caret</code> using the specified <code>Graphics</code>
+ * context.
+ *
+ * @param g the graphics context to use
+ */
public void paint(Graphics g)
{
if (textComponent == null)
@@ -234,26 +420,53 @@ public class DefaultCaret extends Rectangle
}
}
+ /**
+ * Returns all registered event listeners of the specified type.
+ *
+ * @param listenerType the type of listener to return
+ *
+ * @return all registered event listeners of the specified type
+ */
public EventListener[] getListeners(Class listenerType)
{
return listenerList.getListeners(listenerType);
}
+ /**
+ * Registers a {@link ChangeListener} that is notified whenever that state
+ * of this <code>Caret</code> changes.
+ *
+ * @param listener the listener to register to this caret
+ */
public void addChangeListener(ChangeListener listener)
{
listenerList.add(ChangeListener.class, listener);
}
+ /**
+ * Removes a {@link ChangeListener} from the list of registered listeners.
+ *
+ * @param listener the listener to remove
+ */
public void removeChangeListener(ChangeListener listener)
{
listenerList.remove(ChangeListener.class, listener);
}
+ /**
+ * Returns all registered {@link ChangeListener}s of this <code>Caret</code>.
+ *
+ * @return all registered {@link ChangeListener}s of this <code>Caret</code>
+ */
public ChangeListener[] getChangeListeners()
{
return (ChangeListener[]) getListeners(ChangeListener.class);
}
+ /**
+ * Notifies all registered {@link ChangeListener}s that the state
+ * of this <code>Caret</code> has changed.
+ */
protected void fireStateChanged()
{
ChangeListener[] listeners = getChangeListeners();
@@ -262,26 +475,61 @@ public class DefaultCaret extends Rectangle
listeners[index].stateChanged(changeEvent);
}
+ /**
+ * Returns the <code>JTextComponent</code> on which this <code>Caret</code>
+ * is installed.
+ *
+ * @return the <code>JTextComponent</code> on which this <code>Caret</code>
+ * is installed
+ */
protected final JTextComponent getComponent()
{
return textComponent;
}
-
+
+ /**
+ * Returns the blink rate of this <code>Caret</code> in milliseconds.
+ * A value of <code>0</code> means that the caret does not blink.
+ *
+ * @return the blink rate of this <code>Caret</code> or <code>0</code> if
+ * this caret does not blink
+ */
public int getBlinkRate()
{
return blinkRate;
}
+ /**
+ * Sets the blink rate of this <code>Caret</code> in milliseconds.
+ * A value of <code>0</code> means that the caret does not blink.
+ *
+ * @param rate the new blink rate to set
+ */
public void setBlinkRate(int rate)
{
blinkRate = rate;
}
+ /**
+ * Returns the current position of this <code>Caret</code> within the
+ * <code>Document</code>.
+ *
+ * @return the current position of this <code>Caret</code> within the
+ * <code>Document</code>
+ */
public int getDot()
{
return dot;
}
+ /**
+ * Moves the <code>dot</code> location without touching the
+ * <code>mark</code>. This is used when making a selection.
+ *
+ * @param dot the location where to move the dot
+ *
+ * @see #setDot(int)
+ */
public void moveDot(int dot)
{
this.dot = dot;
@@ -289,6 +537,15 @@ public class DefaultCaret extends Rectangle
repaint();
}
+ /**
+ * Sets the current position of this <code>Caret</code> within the
+ * <code>Document</code>. This also sets the <code>mark</code> to the
+ * new location.
+ *
+ * @param dot the new position to be set
+ *
+ * @see #moveDot(int)
+ */
public void setDot(int dot)
{
this.dot = dot;
@@ -297,17 +554,37 @@ public class DefaultCaret extends Rectangle
repaint();
}
+ /**
+ * Returns <code>true</code> if this <code>Caret</code> is currently visible,
+ * and <code>false</code> if it is not.
+ *
+ * @return <code>true</code> if this <code>Caret</code> is currently visible,
+ * and <code>false</code> if it is not
+ */
public boolean isVisible()
{
return visible;
}
+ /**
+ * Sets the visibility state of the caret. <code>true</code> shows the
+ * <code>Caret</code>, <code>false</code> hides it.
+ *
+ * @param v the visibility to set
+ */
public void setVisible(boolean v)
{
visible = v;
repaint();
}
+ /**
+ * Returns the {@link Highlighter.HighlightPainter} that should be used
+ * to paint the selection.
+ *
+ * @return the {@link Highlighter.HighlightPainter} that should be used
+ * to paint the selection
+ */
protected Highlighter.HighlightPainter getSelectionPainter()
{
return DefaultHighlighter.DefaultPainter;
diff --git a/libjava/classpath/javax/swing/text/DefaultEditorKit.java b/libjava/classpath/javax/swing/text/DefaultEditorKit.java
index aa2fbe8509a..a14f3ff4fe0 100644
--- a/libjava/classpath/javax/swing/text/DefaultEditorKit.java
+++ b/libjava/classpath/javax/swing/text/DefaultEditorKit.java
@@ -51,44 +51,135 @@ import java.io.Writer;
import javax.swing.Action;
+/**
+ * The default implementation of {@link EditorKit}. This <code>EditorKit</code>
+ * a plain text <code>Document</code> and several commands that together
+ * make up a basic editor, like cut / copy + paste.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public class DefaultEditorKit extends EditorKit
{
+ /**
+ * Creates a beep on the PC speaker.
+ *
+ * @see Toolkit#beep()
+ */
public static class BeepAction
extends TextAction
{
+ /**
+ * Creates a new <code>BeepAction</code>.
+ */
public BeepAction()
{
super(beepAction);
}
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
Toolkit.getDefaultToolkit().beep();
}
}
+ /**
+ * Copies the selected content into the system clipboard.
+ *
+ * @see Toolkit#getSystemClipboard()
+ * @see CutAction
+ * @see PasteAction
+ */
public static class CopyAction
extends TextAction
{
+
+ /**
+ * Create a new <code>CopyAction</code>.
+ */
public CopyAction()
{
super(copyAction);
}
+
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
+ // FIXME: Implement me. Tookit.getSystemClipboard should be used
+ // for that.
}
}
+
+ /**
+ * Copies the selected content into the system clipboard and deletes the
+ * selection.
+ *
+ * @see Toolkit#getSystemClipboard()
+ * @see CopyAction
+ * @see PasteAction
+ */
public static class CutAction
extends TextAction
{
+
+ /**
+ * Create a new <code>CutAction</code>.
+ */
public CutAction()
{
super(cutAction);
}
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
+ // FIXME: Implement me. Tookit.getSystemClipboard should be used
+ // for that.
+ }
+ }
+
+ /**
+ * Copies content from the system clipboard into the editor.
+ *
+ * @see Toolkit#getSystemClipboard()
+ * @see CopyAction
+ * @see CutAction
+ */
+ public static class PasteAction
+ extends TextAction
+ {
+
+ /**
+ * Create a new <code>PasteAction</code>.
+ */
+ public PasteAction()
+ {
+ super(pasteAction);
+ }
+
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @param event the action event describing the user action
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ // FIXME: Implement me. Tookit.getSystemClipboard should be used
+ // for that.
}
}
@@ -99,17 +190,26 @@ public class DefaultEditorKit extends EditorKit
* the control characters and characters with the ALT-modifier.
*
* If an event does not get filtered, it is inserted into the document
- * of the text component. If there is some text selected in the text component,
- * this text will be replaced.
+ * of the text component. If there is some text selected in the text
+ * component, this text will be replaced.
*/
public static class DefaultKeyTypedAction
extends TextAction
{
+
+ /**
+ * Creates a new <code>DefaultKeyTypedAction</code>.
+ */
public DefaultKeyTypedAction()
{
super(defaultKeyTypedAction);
}
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
// first we filter the following events:
@@ -124,9 +224,11 @@ public class DefaultEditorKit extends EditorKit
{
try
{
- t.getDocument().insertString(t.getCaret().getDot(), event.getActionCommand(), null);
+ t.getDocument().insertString(t.getCaret().getDot(),
+ event.getActionCommand(), null);
t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
- t.getDocument().getEndPosition().getOffset()));
+ t.getDocument().getEndPosition()
+ .getOffset()));
}
catch (BadLocationException be)
{
@@ -144,11 +246,20 @@ public class DefaultEditorKit extends EditorKit
public static class InsertBreakAction
extends TextAction
{
+
+ /**
+ * Creates a new <code>InsertBreakAction</code>.
+ */
public InsertBreakAction()
{
super(insertBreakAction);
}
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
JTextComponent t = getTextComponent(event);
@@ -156,101 +267,446 @@ public class DefaultEditorKit extends EditorKit
}
}
+ /**
+ * Places content into the associated editor. If there currently is a
+ * selection, this selection is replaced.
+ */
+ // FIXME: Figure out what this Action is supposed to do. Obviously text
+ // that is entered by the user is inserted through DefaultKeyTypedAction.
public static class InsertContentAction
extends TextAction
{
+
+ /**
+ * Creates a new <code>InsertContentAction</code>.
+ */
public InsertContentAction()
{
super(insertContentAction);
}
+
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
}
}
+ /**
+ * Inserts a TAB character into the text editor.
+ */
public static class InsertTabAction
extends TextAction
{
+
+ /**
+ * Creates a new <code>TabAction</code>.
+ */
public InsertTabAction()
{
super(insertTabAction);
}
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
+ // FIXME: Implement this.
}
}
- public static class PasteAction
- extends TextAction
- {
- public PasteAction()
- {
- super(pasteAction);
- }
-
- public void actionPerformed(ActionEvent event)
- {
- }
- }
-
+ /**
+ * The serial version of DefaultEditorKit.
+ */
private static final long serialVersionUID = 9017245433028523428L;
-
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one character
+ * backwards.
+ *
+ * @see #getActions()
+ */
public static final String backwardAction = "caret-backward";
+
+ /**
+ * The name of the <code>Action</code> that creates a beep in the speaker.
+ *
+ * @see #getActions()
+ */
public static final String beepAction = "beep";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the <code>Document</code>.
+ *
+ * @see #getActions()
+ */
public static final String beginAction = "caret-begin";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the current line.
+ *
+ * @see #getActions()
+ */
public static final String beginLineAction = "caret-begin-line";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the current paragraph.
+ *
+ * @see #getActions()
+ */
public static final String beginParagraphAction = "caret-begin-paragraph";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the current word.
+ *
+ * @see #getActions()
+ */
public static final String beginWordAction = "caret-begin-word";
+
+ /**
+ * The name of the <code>Action</code> that copies the selected content
+ * into the system clipboard.
+ *
+ * @see #getActions()
+ */
public static final String copyAction = "copy-to-clipboard";
+
+ /**
+ * The name of the <code>Action</code> that copies the selected content
+ * into the system clipboard and removes the selection.
+ *
+ * @see #getActions()
+ */
public static final String cutAction = "cut-to-clipboard";
+
+ /**
+ * The name of the <code>Action</code> that is performed by default if
+ * a key is typed and there is no keymap entry.
+ *
+ * @see #getActions()
+ */
public static final String defaultKeyTypedAction = "default-typed";
+
+ /**
+ * The name of the <code>Action</code> that deletes the character that
+ * follows the current caret position.
+ *
+ * @see #getActions()
+ */
public static final String deleteNextCharAction = "delete-next";
+
+ /**
+ * The name of the <code>Action</code> that deletes the character that
+ * precedes the current caret position.
+ *
+ * @see #getActions()
+ */
public static final String deletePrevCharAction = "delete-previous";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one line down.
+ *
+ * @see #getActions()
+ */
public static final String downAction = "caret-down";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the end
+ * of the <code>Document</code>.
+ *
+ * @see #getActions()
+ */
public static final String endAction = "caret-end";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the end
+ * of the current line.
+ *
+ * @see #getActions()
+ */
public static final String endLineAction = "caret-end-line";
+
+ /**
+ * When a document is read and an CRLF is encountered, then we add a property
+ * with this name and a value of &quot;\r\n&quot;.
+ */
public static final String EndOfLineStringProperty = "__EndOfLine__";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the end
+ * of the current paragraph.
+ *
+ * @see #getActions()
+ */
public static final String endParagraphAction = "caret-end-paragraph";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the end
+ * of the current word.
+ *
+ * @see #getActions()
+ */
public static final String endWordAction = "caret-end-word";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one character
+ * forward.
+ *
+ * @see #getActions()
+ */
public static final String forwardAction = "caret-forward";
+
+ /**
+ * The name of the <code>Action</code> that inserts a line break.
+ *
+ * @see #getActions()
+ */
public static final String insertBreakAction = "insert-break";
+
+ /**
+ * The name of the <code>Action</code> that inserts some content.
+ *
+ * @see #getActions()
+ */
public static final String insertContentAction = "insert-content";
+
+ /**
+ * The name of the <code>Action</code> that inserts a TAB.
+ *
+ * @see #getActions()
+ */
public static final String insertTabAction = "insert-tab";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the next word.
+ *
+ * @see #getActions()
+ */
public static final String nextWordAction = "caret-next-word";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one page down.
+ *
+ * @see #getActions()
+ */
public static final String pageDownAction = "page-down";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one page up.
+ *
+ * @see #getActions()
+ */
public static final String pageUpAction = "page-up";
+
+ /**
+ * The name of the <code>Action</code> that copies content from the system
+ * clipboard into the document.
+ *
+ * @see #getActions()
+ */
public static final String pasteAction = "paste-from-clipboard";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the previous word.
+ *
+ * @see #getActions()
+ */
public static final String previousWordAction = "caret-previous-word";
+
+ /**
+ * The name of the <code>Action</code> that sets the editor in read only
+ * mode.
+ *
+ * @see #getActions()
+ */
public static final String readOnlyAction = "set-read-only";
+
+ /**
+ * The name of the <code>Action</code> that selects the whole document.
+ *
+ * @see #getActions()
+ */
public static final String selectAllAction = "select-all";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one character
+ * backwards, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionBackwardAction = "selection-backward";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the document, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionBeginAction = "selection-begin";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the current line, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionBeginLineAction = "selection-begin-line";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the current paragraph, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionBeginParagraphAction =
"selection-begin-paragraph";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the current word, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionBeginWordAction = "selection-begin-word";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one line down,
+ * possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionDownAction = "selection-down";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the end
+ * of the document, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionEndAction = "selection-end";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the end
+ * of the current line, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionEndLineAction = "selection-end-line";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the end
+ * of the current paragraph, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionEndParagraphAction =
"selection-end-paragraph";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the end
+ * of the current word, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionEndWordAction = "selection-end-word";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one character
+ * forwards, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionForwardAction = "selection-forward";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the next word, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionNextWordAction = "selection-next-word";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the previous word, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionPreviousWordAction =
"selection-previous-word";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one line up,
+ * possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionUpAction = "selection-up";
+
+ /**
+ * The name of the <code>Action</code> that selects the line around the
+ * caret.
+ *
+ * @see #getActions()
+ */
public static final String selectLineAction = "select-line";
+
+ /**
+ * The name of the <code>Action</code> that selects the paragraph around the
+ * caret.
+ *
+ * @see #getActions()
+ */
public static final String selectParagraphAction = "select-paragraph";
+
+ /**
+ * The name of the <code>Action</code> that selects the word around the
+ * caret.
+ *
+ * @see #getActions()
+ */
public static final String selectWordAction = "select-word";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one line up.
+ *
+ * @see #getActions()
+ */
public static final String upAction = "caret-up";
+
+ /**
+ * The name of the <code>Action</code> that sets the editor in read-write
+ * mode.
+ *
+ * @see #getActions()
+ */
public static final String writableAction = "set-writable";
+ /**
+ * Creates a new <code>DefaultEditorKit</code>.
+ */
public DefaultEditorKit()
{
}
+ /**
+ * The <code>Action</code>s that are supported by the
+ * <code>DefaultEditorKit</code>.
+ */
+ // TODO: All these inner classes look ugly. Maybe work out a better way
+ // to handle this.
private static Action[] defaultActions =
new Action[] {
new BeepAction(),
@@ -356,37 +812,98 @@ public class DefaultEditorKit extends EditorKit
},
};
+ /**
+ * Creates the <code>Caret</code> for this <code>EditorKit</code>. This
+ * returns a {@link DefaultCaret} in this case.
+ *
+ * @return the <code>Caret</code> for this <code>EditorKit</code>
+ */
public Caret createCaret()
{
return new DefaultCaret();
}
+ /**
+ * Creates the default {@link Document} that this <code>EditorKit</code>
+ * supports. This is a {@link PlainDocument} in this case.
+ *
+ * @return the default {@link Document} that this <code>EditorKit</code>
+ * supports
+ */
public Document createDefaultDocument()
{
return new PlainDocument();
}
-
+
+ /**
+ * Returns the <code>Action</code>s supported by this <code>EditorKit</code>.
+ *
+ * @return the <code>Action</code>s supported by this <code>EditorKit</code>
+ */
public Action[] getActions()
{
return defaultActions;
}
+ /**
+ * Returns the content type that this <code>EditorKit</code> supports.
+ * The <code>DefaultEditorKit</code> supports the content type
+ * <code>text/plain</code>.
+ *
+ * @return the content type that this <code>EditorKit</code> supports
+ */
public String getContentType()
{
return "text/plain";
}
-
+
+ /**
+ * Returns a {@link ViewFactory} that is able to create {@link View}s for
+ * the <code>Element</code>s that are used in this <code>EditorKit</code>'s
+ * model. This returns null which lets the UI of the text component supply
+ * <code>View</code>s.
+ *
+ * @return a {@link ViewFactory} that is able to create {@link View}s for
+ * the <code>Element</code>s that are used in this
+ * <code>EditorKit</code>'s model
+ */
public ViewFactory getViewFactory()
{
return null;
}
+ /**
+ * Reads a document of the supported content type from an {@link InputStream}
+ * into the actual {@link Document} object.
+ *
+ * @param in the stream from which to read the document
+ * @param document the document model into which the content is read
+ * @param offset the offset inside to document where the content is inserted
+ *
+ * @throws BadLocationException if <code>offset</code> is an invalid location
+ * inside <code>document</code>
+ * @throws IOException if something goes wrong while reading from
+ * <code>in</code>
+ */
public void read(InputStream in, Document document, int offset)
throws BadLocationException, IOException
{
read(new InputStreamReader(in), document, offset);
}
+ /**
+ * Reads a document of the supported content type from a {@link Reader}
+ * into the actual {@link Document} object.
+ *
+ * @param in the reader from which to read the document
+ * @param document the document model into which the content is read
+ * @param offset the offset inside to document where the content is inserted
+ *
+ * @throws BadLocationException if <code>offset</code> is an invalid location
+ * inside <code>document</code>
+ * @throws IOException if something goes wrong while reading from
+ * <code>in</code>
+ */
public void read(Reader in, Document document, int offset)
throws BadLocationException, IOException
{
@@ -405,14 +922,47 @@ public class DefaultEditorKit extends EditorKit
SimpleAttributeSet.EMPTY);
}
+ /**
+ * Writes the <code>Document</code> (or a fragment of the
+ * <code>Document</code>) to an {@link OutputStream} in the
+ * supported content type format.
+ *
+ * @param out the stream to write to
+ * @param document the document that should be written out
+ * @param offset the beginning offset from where to write
+ * @param len the length of the fragment to write
+ *
+ * @throws BadLocationException if <code>offset</code> or
+ * <code>offset + len</code>is an invalid location inside
+ * <code>document</code>
+ * @throws IOException if something goes wrong while writing to
+ * <code>out</code>
+ */
public void write(OutputStream out, Document document, int offset, int len)
throws BadLocationException, IOException
{
write(new OutputStreamWriter(out), document, offset, len);
}
+ /**
+ * Writes the <code>Document</code> (or a fragment of the
+ * <code>Document</code>) to a {@link Writer} in the
+ * supported content type format.
+ *
+ * @param out the writer to write to
+ * @param document the document that should be written out
+ * @param offset the beginning offset from where to write
+ * @param len the length of the fragment to write
+ *
+ * @throws BadLocationException if <code>offset</code> or
+ * <code>offset + len</code>is an invalid location inside
+ * <code>document</code>
+ * @throws IOException if something goes wrong while writing to
+ * <code>out</code>
+ */
public void write(Writer out, Document document, int offset, int len)
throws BadLocationException, IOException
{
+ // TODO: Implement this properly.
}
}
diff --git a/libjava/classpath/javax/swing/text/DefaultStyledDocument.java b/libjava/classpath/javax/swing/text/DefaultStyledDocument.java
index 6fe206a8453..3545e52c453 100644
--- a/libjava/classpath/javax/swing/text/DefaultStyledDocument.java
+++ b/libjava/classpath/javax/swing/text/DefaultStyledDocument.java
@@ -42,42 +42,174 @@ import java.awt.Color;
import java.awt.Font;
import java.io.Serializable;
+import javax.swing.event.DocumentEvent;
+
/**
+ * The default implementation of {@link StyledDocument}.
+ *
+ * The document is modeled as an {@link Element} tree, which has
+ * a {@link SectionElement} as single root, which has one or more
+ * {@link AbstractDocument.BranchElement}s as paragraph nodes
+ * and each paragraph node having one or more
+ * {@link AbstractDocument.LeafElement}s as content nodes.
+ *
* @author Michael Koch (konqueror@gmx.de)
+ * @author Roman Kennke (roman@kennke.org)
*/
public class DefaultStyledDocument extends AbstractDocument
implements StyledDocument
{
+ /**
+ * Performs all <em>structural</code> changes to the <code>Element</code>
+ * hierarchy.
+ */
public class ElementBuffer
implements Serializable
{
+ /** The root element of the hierarchy. */
private Element root;
-
+
+ /** Holds the offset for structural changes. */
+ private int offset;
+
+ /** Holds the length of structural changes. */
+ private int length;
+
+ /**
+ * Creates a new <code>ElementBuffer</code> for the specified
+ * <code>root</code> element.
+ *
+ * @param root the root element for this <code>ElementBuffer</code>
+ */
public ElementBuffer(Element root)
{
this.root = root;
}
+ /**
+ * Returns the root element of this <code>ElementBuffer</code>.
+ *
+ * @return the root element of this <code>ElementBuffer</code>
+ */
public Element getRootElement()
{
return root;
}
+
+ /**
+ * Modifies the element structure so that the specified interval starts
+ * and ends at an element boundary. Content and paragraph elements
+ * are split and created as necessary.
+ *
+ * This also updates the <code>DefaultDocumentEvent</code> to reflect the
+ * structural changes.
+ *
+ * The bulk work is delegated to {@link #changeUpdate()}.
+ *
+ * @param offset the start index of the interval to be changed
+ * @param length the length of the interval to be changed
+ * @param ev the <code>DefaultDocumentEvent</code> describing the change
+ */
+ public void change(int offset, int length, DefaultDocumentEvent ev)
+ {
+ this.offset = offset;
+ this.length = length;
+ changeUpdate();
+ }
+
+ /**
+ * Performs the actual work for {@link #change}.
+ * The elements at the interval boundaries are split up (if necessary)
+ * so that the interval boundaries are located at element boundaries.
+ */
+ protected void changeUpdate()
+ {
+ // Split up the element at the start offset if necessary.
+ Element el = getCharacterElement(offset);
+ split(el, offset);
+
+ int endOffset = offset + length;
+ el = getCharacterElement(endOffset);
+ split(el, endOffset);
+ }
+
+ /**
+ * Splits an element if <code>offset</code> is not alread at its boundary.
+ *
+ * @param el the Element to possibly split
+ * @param offset the offset at which to possibly split
+ */
+ void split(Element el, int offset)
+ {
+ if (el instanceof AbstractElement)
+ {
+ AbstractElement ael = (AbstractElement) el;
+ int startOffset = ael.getStartOffset();
+ int endOffset = ael.getEndOffset();
+ int len = endOffset - startOffset;
+ if (startOffset != offset && endOffset != offset)
+ {
+ Element paragraph = ael.getParentElement();
+ if (paragraph instanceof BranchElement)
+ {
+ BranchElement par = (BranchElement) paragraph;
+ Element child1 = createLeafElement(par, ael, startOffset,
+ offset);
+ Element child2 = createLeafElement(par, ael, offset,
+ endOffset);
+ int index = par.getElementIndex(startOffset);
+ par.replace(index, 1, new Element[]{ child1, child2 });
+ }
+ else
+ throw new AssertionError("paragraph elements are expected to "
+ + "be instances of "
+ + "javax.swing.text.AbstractDocument.BranchElement");
+ }
+ }
+ else
+ throw new AssertionError("content elements are expected to be "
+ + "instances of "
+ + "javax.swing.text.AbstractDocument.AbstractElement");
+ }
}
-
+
+ /**
+ * The default size to use for new content buffers.
+ */
public static final int BUFFER_SIZE_DEFAULT = 4096;
+ /**
+ * The <code>EditorBuffer</code> that is used to manage to
+ * <code>Element</code> hierarchy.
+ */
protected DefaultStyledDocument.ElementBuffer buffer;
-
+
+ /**
+ * Creates a new <code>DefaultStyledDocument</code>.
+ */
public DefaultStyledDocument()
{
this(new GapContent(BUFFER_SIZE_DEFAULT), new StyleContext());
}
+ /**
+ * Creates a new <code>DefaultStyledDocument</code> that uses the
+ * specified {@link StyleContext}.
+ *
+ * @param context the <code>StyleContext</code> to use
+ */
public DefaultStyledDocument(StyleContext context)
{
this(new GapContent(BUFFER_SIZE_DEFAULT), context);
}
+ /**
+ * Creates a new <code>DefaultStyledDocument</code> that uses the
+ * specified {@link StyleContext} and {@link Content} buffer.
+ *
+ * @param content the <code>Content</code> buffer to use
+ * @param context the <code>StyleContext</code> to use
+ */
public DefaultStyledDocument(AbstractDocument.Content content,
StyleContext context)
{
@@ -86,15 +218,38 @@ public class DefaultStyledDocument extends AbstractDocument
setLogicalStyle(0, context.getStyle(StyleContext.DEFAULT_STYLE));
}
+ /**
+ * Adds a style into the style hierarchy. Unspecified style attributes
+ * can be resolved in the <code>parent</code> style, if one is specified.
+ *
+ * While it is legal to add nameless styles (<code>nm == null</code),
+ * you must be aware that the client application is then responsible
+ * for managing the style hierarchy, since unnamed styles cannot be
+ * looked up by their name.
+ *
+ * @param nm the name of the style or <code>null</code> if the style should
+ * be unnamed
+ * @param parent the parent in which unspecified style attributes are
+ * resolved, or <code>null</code> if that is not necessary
+ *
+ * @return the newly created <code>Style</code>
+ */
public Style addStyle(String nm, Style parent)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.addStyle(nm, parent);
}
-
+
+ /**
+ * Create the default root element for this kind of <code>Document</code>.
+ *
+ * @return the default root element for this kind of <code>Document</code>
+ */
protected AbstractDocument.AbstractElement createDefaultRoot()
{
Element[] tmp;
+ // FIXME: Create a SecionElement here instead of a BranchElement.
+ // Use createBranchElement() and createLeafElement instead.
BranchElement section = new BranchElement(null, null);
BranchElement paragraph = new BranchElement(section, null);
@@ -109,7 +264,17 @@ public class DefaultStyledDocument extends AbstractDocument
return section;
}
-
+
+ /**
+ * Returns the <code>Element</code> that corresponds to the character
+ * at the specified position.
+ *
+ * @param position the position of which we query the corresponding
+ * <code>Element</code>
+ *
+ * @return the <code>Element</code> that corresponds to the character
+ * at the specified position
+ */
public Element getCharacterElement(int position)
{
Element element = getDefaultRootElement();
@@ -122,63 +287,172 @@ public class DefaultStyledDocument extends AbstractDocument
return element;
}
-
+
+ /**
+ * Extracts a background color from a set of attributes.
+ *
+ * @param attributes the attributes from which to get a background color
+ *
+ * @return the background color that correspond to the attributes
+ */
public Color getBackground(AttributeSet attributes)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.getBackground(attributes);
}
-
+
+ /**
+ * Returns the default root element.
+ *
+ * @return the default root element
+ */
public Element getDefaultRootElement()
{
return buffer.getRootElement();
}
-
+
+ /**
+ * Extracts a font from a set of attributes.
+ *
+ * @param attributes the attributes from which to get a font
+ *
+ * @return the font that correspond to the attributes
+ */
public Font getFont(AttributeSet attributes)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.getFont(attributes);
}
+ /**
+ * Extracts a foreground color from a set of attributes.
+ *
+ * @param attributes the attributes from which to get a foreground color
+ *
+ * @return the foreground color that correspond to the attributes
+ */
public Color getForeground(AttributeSet attributes)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.getForeground(attributes);
}
-
+
+ /**
+ * Returns the logical <code>Style</code> for the specified position.
+ *
+ * @param position the position from which to query to logical style
+ *
+ * @return the logical <code>Style</code> for the specified position
+ */
public Style getLogicalStyle(int position)
{
Element paragraph = getParagraphElement(position);
AttributeSet attributes = paragraph.getAttributes();
return (Style) attributes.getResolveParent();
}
-
+
+ /**
+ * Returns the paragraph element for the specified position.
+ *
+ * @param position the position for which to query the paragraph element
+ *
+ * @return the paragraph element for the specified position
+ */
public Element getParagraphElement(int position)
{
Element element = getCharacterElement(position);
return element.getParentElement();
}
+ /**
+ * Looks up and returns a named <code>Style</code>.
+ *
+ * @param nm the name of the <code>Style</code>
+ *
+ * @return the found <code>Style</code> of <code>null</code> if no such
+ * <code>Style</code> exists
+ */
public Style getStyle(String nm)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.getStyle(nm);
}
+ /**
+ * Removes a named <code>Style</code> from the style hierarchy.
+ *
+ * @param nm the name of the <code>Style</code> to be removed
+ */
public void removeStyle(String nm)
{
StyleContext context = (StyleContext) getAttributeContext();
context.removeStyle(nm);
}
+ /**
+ * Sets text attributes for the fragment specified by <code>offset</code>
+ * and <code>length</code>.
+ *
+ * @param offset the start offset of the fragment
+ * @param length the length of the fragment
+ * @param attributes the text attributes to set
+ * @param replace if <code>true</code>, the attributes of the current
+ * selection are overridden, otherwise they are merged
+ */
public void setCharacterAttributes(int offset, int length,
AttributeSet attributes,
boolean replace)
{
- // FIXME: Implement me.
- throw new Error("not implemented");
+ DefaultDocumentEvent ev =
+ new DefaultDocumentEvent(offset, length,
+ DocumentEvent.EventType.CHANGE);
+
+ // Modify the element structure so that the interval begins at an element
+ // start and ends at an element end.
+ buffer.change(offset, length, ev);
+
+ Element root = getDefaultRootElement();
+ // Visit all paragraph elements within the specified interval
+ int paragraphCount = root.getElementCount();
+ for (int pindex = 0; pindex < paragraphCount; pindex++)
+ {
+ Element paragraph = root.getElement(pindex);
+ // Skip paragraphs that lie outside the interval.
+ if ((paragraph.getStartOffset() > offset + length)
+ || (paragraph.getEndOffset() < offset))
+ continue;
+
+ // Visit content elements within this paragraph
+ int contentCount = paragraph.getElementCount();
+ for (int cindex = 0; cindex < contentCount; cindex++)
+ {
+ Element content = paragraph.getElement(cindex);
+ // Skip content that lies outside the interval.
+ if ((content.getStartOffset() > offset + length)
+ || (content.getEndOffset() < offset))
+ continue;
+
+ if (content instanceof AbstractElement)
+ {
+ AbstractElement el = (AbstractElement) content;
+ if (replace)
+ el.removeAttributes(el);
+ el.addAttributes(attributes);
+ }
+ else
+ throw new AssertionError("content elements are expected to be"
+ + "instances of "
+ + "javax.swing.text.AbstractDocument.AbstractElement");
+ }
+ }
}
+ /**
+ * Sets the logical style for the paragraph at the specified position.
+ *
+ * @param position the position at which the logical style is added
+ * @param style the style to set for the current paragraph
+ */
public void setLogicalStyle(int position, Style style)
{
Element el = getParagraphElement(position);
@@ -192,6 +466,15 @@ public class DefaultStyledDocument extends AbstractDocument
+ "instances of javax.swing.text.AbstractDocument.AbstractElement");
}
+ /**
+ * Sets text attributes for the paragraph at the specified fragment.
+ *
+ * @param offset the beginning of the fragment
+ * @param length the length of the fragment
+ * @param attributes the text attributes to set
+ * @param replace if <code>true</code>, the attributes of the current
+ * selection are overridden, otherwise they are merged
+ */
public void setParagraphAttributes(int offset, int length,
AttributeSet attributes,
boolean replace)
diff --git a/libjava/classpath/javax/swing/text/FieldView.java b/libjava/classpath/javax/swing/text/FieldView.java
index 4d5c51cebb4..e2e04d7c495 100644
--- a/libjava/classpath/javax/swing/text/FieldView.java
+++ b/libjava/classpath/javax/swing/text/FieldView.java
@@ -173,4 +173,9 @@ public class FieldView extends PlainView
super.removeUpdate(ev, newAlloc, vf);
}
+ public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias)
+ {
+ return super.viewToModel(fx, fy, a, bias);
+ }
+
}
diff --git a/libjava/classpath/javax/swing/text/GapContent.java b/libjava/classpath/javax/swing/text/GapContent.java
index 1bbef8f93d6..1dd46c4b0f4 100644
--- a/libjava/classpath/javax/swing/text/GapContent.java
+++ b/libjava/classpath/javax/swing/text/GapContent.java
@@ -39,29 +39,93 @@ exception statement from your version. */
package javax.swing.text;
import java.io.Serializable;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.ListIterator;
import javax.swing.undo.UndoableEdit;
/**
- * This implementation of {@link AbstractDocument.Content} uses a gapped
- * buffer. This takes advantage of the fact that text area content is
- * mostly inserted sequentially. The buffer is a char array that maintains
- * a gap at the current insertion point. If characters a inserted at
- * gap boundaries, the cost is minimal (simple array access). The array only
- * has to be shifted around when the insertion point moves (then the gap also
- * moves and one array copy is necessary) or when the gap is filled up and
- * the buffer has to be enlarged.
- *
+ * This implementation of {@link AbstractDocument.Content} uses a gapped buffer.
+ * This takes advantage of the fact that text area content is mostly inserted
+ * sequentially. The buffer is a char array that maintains a gap at the current
+ * insertion point. If characters a inserted at gap boundaries, the cost is
+ * minimal (simple array access). The array only has to be shifted around when
+ * the insertion point moves (then the gap also moves and one array copy is
+ * necessary) or when the gap is filled up and the buffer has to be enlarged.
+ *
* TODO: Implement UndoableEdit support stuff
*/
public class GapContent
- implements AbstractDocument.Content, Serializable
+ implements AbstractDocument.Content, Serializable
{
+
+ /**
+ * A {@link Position} implementation for <code>GapContent</code>.
+ */
+ class GapContentPosition
+ implements Position, Comparable
+ {
+
+ /** The index within the buffer array. */
+ int mark;
+
+ /**
+ * Creates a new GapContentPosition object.
+ *
+ * @param mark the mark of this Position
+ */
+ GapContentPosition(int mark)
+ {
+ this.mark = mark;
+ }
+
+ /**
+ * Comparable interface implementation. This is used to store all
+ * positions in an ordered fashion.
+ *
+ * @param o the object to be compared to this
+ *
+ * @return a negative integer if this is less than <code>o</code>, zero
+ * if both are equal or a positive integer if this is greater than
+ * <code>o</code>
+ *
+ * @throws ClassCastException if <code>o</code> is not a
+ * GapContentPosition or Integer object
+ */
+ public int compareTo(Object o)
+ {
+ if (o instanceof Integer)
+ {
+ int otherMark = ((Integer) o).intValue();
+ return mark - otherMark;
+ }
+ else
+ {
+ GapContentPosition other = (GapContentPosition) o;
+ return mark - other.mark;
+ }
+ }
+
+ /**
+ * Returns the current offset of this Position within the content.
+ *
+ * @return the current offset of this Position within the content.
+ */
+ public int getOffset()
+ {
+ if (mark <= gapStart)
+ return mark;
+ else
+ return mark - (gapEnd - gapStart);
+ }
+ }
+
private static final long serialVersionUID = 8374645204155842629L;
/**
- * This is the default buffer size and the amount of bytes that
- * a buffer is extended if it is full.
+ * This is the default buffer size and the amount of bytes that a buffer is
+ * extended if it is full.
*/
static final int DEFAULT_BUFSIZE = 64;
@@ -81,6 +145,12 @@ public class GapContent
int gapEnd;
/**
+ * The positions generated by this GapContent. They are kept in an ordered
+ * fashion, so they can be looked up easily.
+ */
+ LinkedList positions;
+
+ /**
* Creates a new GapContent object.
*/
public GapContent()
@@ -90,7 +160,7 @@ public class GapContent
/**
* Creates a new GapContent object with a specified initial size.
- *
+ *
* @param size the initial size of the buffer
*/
public GapContent(int size)
@@ -99,14 +169,15 @@ public class GapContent
gapStart = 0;
gapEnd = size - 1;
buffer[size - 1] = '\n';
+ positions = new LinkedList();
}
/**
* Allocates an array of the specified length that can then be used as
* buffer.
- *
+ *
* @param size the size of the array to be allocated
- *
+ *
* @return the allocated array
*/
protected Object allocateArray(int size)
@@ -116,7 +187,7 @@ public class GapContent
/**
* Returns the length of the allocated buffer array.
- *
+ *
* @return the length of the allocated buffer array
*/
protected int getArrayLength()
@@ -126,7 +197,7 @@ public class GapContent
/**
* Returns the length of the content.
- *
+ *
* @return the length of the content
*/
public int length()
@@ -136,18 +207,18 @@ public class GapContent
/**
* Inserts a string at the specified position.
- *
+ *
* @param where the position where the string is inserted
* @param str the string that is to be inserted
- *
+ *
* @return an UndoableEdit object (currently not supported, so
* <code>null</code> is returned)
- *
- * @throws BadLocationException if <code>where</code> is not a valid location
- * in the buffer
+ *
+ * @throws BadLocationException if <code>where</code> is not a valid
+ * location in the buffer
*/
public UndoableEdit insertString(int where, String str)
- throws BadLocationException
+ throws BadLocationException
{
// check arguments
int length = length();
@@ -155,190 +226,230 @@ public class GapContent
if (where >= length)
throw new BadLocationException("the where argument cannot be greater"
- + " than the content length", where);
-
- // check if the gap is big enough to hold the string
- if ((gapEnd - gapStart) < strLen)
- // make room for this string and some more
- shiftEnd(strLen + DEFAULT_BUFSIZE);
+ + " than the content length", where);
- // are we at the gap boundary?
- if (where != gapStart)
- shiftGap(where);
+ replace(where, 0, str.toCharArray(), str.length());
- // now we can simple copy the string into the gap and adjust the
- // gap boundaries
- System.arraycopy(str.toCharArray(), 0, buffer, gapStart, strLen);
- gapStart += strLen;
return null;
}
/**
* Removes a piece of content at th specified position.
- *
+ *
* @param where the position where the content is to be removed
* @param nitems number of characters to be removed
- *
+ *
* @return an UndoableEdit object (currently not supported, so
* <code>null</code> is returned)
- *
- * @throws BadLocationException if <code>where</code> is not a valid location
- * in the buffer
+ *
+ * @throws BadLocationException if <code>where</code> is not a valid
+ * location in the buffer
*/
- public UndoableEdit remove(int where, int nitems)
- throws BadLocationException
+ public UndoableEdit remove(int where, int nitems) throws BadLocationException
{
// check arguments
int length = length();
if (where >= length)
throw new BadLocationException("the where argument cannot be greater"
- + " than the content length", where);
+ + " than the content length", where);
if ((where + nitems) > length)
throw new BadLocationException("where + nitems cannot be greater"
- + " than the content length",
- where + nitems);
+ + " than the content length", where + nitems);
- // check if we are at the gap boundary
- if (where != gapStart)
- shiftGap(where);
+ replace(where, nitems, null, 0);
- // now we simply have to enlarge the gap
- gapEnd += nitems;
return null;
}
/**
* Returns a piece of content as String.
- *
+ *
* @param where the start location of the fragment
* @param len the length of the fragment
- *
+ *
* @throws BadLocationException if <code>where</code> or
* <code>where + len</code> are no valid locations in the buffer
*/
public String getString(int where, int len) throws BadLocationException
{
Segment seg = new Segment();
- getChars(where, len, seg);
- return new String(seg.array, seg.offset, seg.count);
+ try
+ {
+ getChars(where, len, seg);
+ return new String(seg.array, seg.offset, seg.count);
+ }
+ catch (StringIndexOutOfBoundsException ex)
+ {
+ int invalid = 0;
+ if (seg.offset < 0 || seg.offset >= seg.array.length)
+ invalid = seg.offset;
+ else
+ invalid = seg.offset + seg.count;
+ throw new BadLocationException("Illegal location: array.length = "
+ + seg.array.length + ", offset = "
+ + seg.offset + ", count = "
+ + seg.count, invalid);
+ }
}
/**
* Fetches a piece of content and stores it in a {@link Segment} object.
- *
- * If the requested piece of text spans the gap, the content is copied
- * into a new array. If it doesn't then it is contiguous and the
- * actual content store is returned.
- *
+ *
+ * If the requested piece of text spans the gap, the content is copied into a
+ * new array. If it doesn't then it is contiguous and the actual content
+ * store is returned.
+ *
* @param where the start location of the fragment
* @param len the length of the fragment
* @param txt the Segment object to store the fragment in
- *
+ *
* @throws BadLocationException if <code>where</code> or
* <code>where + len</code> are no valid locations in the buffer
*/
public void getChars(int where, int len, Segment txt)
- throws BadLocationException
+ throws BadLocationException
{
// check arguments
int length = length();
if (where >= length)
throw new BadLocationException("the where argument cannot be greater"
- + " than the content length", where);
+ + " than the content length", where);
if ((where + len) > length)
throw new BadLocationException("len plus where cannot be greater"
- + " than the content length",
- len + where);
+ + " than the content length", len + where);
// check if requested segment is contiguous
if ((where < gapStart) && ((gapStart - where) < len))
- {
- // requested segment is not contiguous -> copy the pieces together
- char[] copy = new char[len];
- int lenFirst = gapStart - where; // the length of the first segment
- System.arraycopy(buffer, where, copy, 0, lenFirst);
- System.arraycopy(buffer, gapEnd, copy, lenFirst, len - lenFirst);
- txt.array = copy;
- txt.offset = 0;
- txt.count = len;
- }
+ {
+ // requested segment is not contiguous -> copy the pieces together
+ char[] copy = new char[len];
+ int lenFirst = gapStart - where; // the length of the first segment
+ System.arraycopy(buffer, where, copy, 0, lenFirst);
+ System.arraycopy(buffer, gapEnd, copy, lenFirst, len - lenFirst);
+ txt.array = copy;
+ txt.offset = 0;
+ txt.count = len;
+ }
else
- {
- // requested segment is contiguous -> we can simply return the
- // actual content
- txt.array = buffer;
- if (where < gapStart)
- txt.offset = where;
- else
- txt.offset = where + (gapEnd - gapStart);
- txt.count = len;
- }
+ {
+ // requested segment is contiguous -> we can simply return the
+ // actual content
+ txt.array = buffer;
+ if (where < gapStart)
+ txt.offset = where;
+ else
+ txt.offset = where + (gapEnd - gapStart);
+ txt.count = len;
+ }
}
/**
* Creates and returns a mark at the specified position.
- *
+ *
* @param offset the position at which to create the mark
- *
+ *
* @return the create Position object for the mark
- *
- * @throws BadLocationException if the offset is not a valid position in
- * the buffer
+ *
+ * @throws BadLocationException if the offset is not a valid position in the
+ * buffer
*/
public Position createPosition(final int offset) throws BadLocationException
{
- return new Position()
- {
- int off = offset;
-
- public int getOffset()
- {
- return off;
- }
- };
+ if (offset < 0 || offset > length())
+ throw new BadLocationException("The offset was out of the bounds of this"
+ + " buffer", offset);
+
+ // We store the actual array index in the GapContentPosition. The real
+ // offset is then calculated in the GapContentPosition.
+ int mark = offset;
+ if (offset > gapStart)
+ mark += gapEnd - gapStart;
+ GapContentPosition pos = new GapContentPosition(mark);
+
+ // Add this into our list in a sorted fashion.
+ int index = Collections.binarySearch(positions, pos);
+ if (index < 0)
+ index = -(index + 1);
+ positions.add(index, pos);
+
+ return pos;
}
/**
* Enlarges the gap. This allocates a new bigger buffer array, copy the
- * segment before the gap as it is and the segment after the gap at
- * the end of the new buffer array. This does change the gapEnd mark
- * but not the gapStart mark.
- *
+ * segment before the gap as it is and the segment after the gap at the end
+ * of the new buffer array. This does change the gapEnd mark but not the
+ * gapStart mark.
+ *
* @param newSize the new size of the gap
*/
protected void shiftEnd(int newSize)
{
+ int delta = (gapEnd - gapStart) - newSize;
char[] newBuf = (char[]) allocateArray(length() + newSize);
System.arraycopy(buffer, 0, newBuf, 0, gapStart);
- System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize,
- buffer.length - gapEnd);
+ System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize, buffer.length
+ - gapEnd);
gapEnd = gapStart + newSize;
buffer = newBuf;
+
+ // Update the marks after the gapEnd.
+ int index = Collections.binarySearch(positions, new GapContentPosition(
+ gapEnd));
+ if (index < 0)
+ {
+ index = -(index + 1);
+ }
+ for (ListIterator i = positions.listIterator(index); i.hasNext();)
+ {
+ GapContentPosition p = (GapContentPosition) i.next();
+ p.mark += delta;
+ }
}
/**
* Shifts the gap to the specified position.
- *
+ *
* @param newGapStart the new start position of the gap
*/
protected void shiftGap(int newGapStart)
{
int newGapEnd = newGapStart + (gapEnd - gapStart);
+ // Update the positions between newGapEnd and (old) gapEnd. The marks
+ // must be shifted by (gapEnd - newGapEnd).
+ int index1 = Collections.binarySearch(positions,
+ new GapContentPosition(gapEnd));
+ int index2 = Collections.binarySearch(positions,
+ new GapContentPosition(newGapEnd));
+ if (index1 > 0 && index2 > 0)
+ {
+ int i1 = Math.min(index1, index2);
+ int i2 = Math.max(index1, index2);
+ for (ListIterator i = positions.listIterator(i1); i.hasNext();)
+ {
+ if (i.nextIndex() > i2)
+ break;
+
+ GapContentPosition p = (GapContentPosition) i.next();
+ p.mark += gapEnd - newGapEnd;
+ }
+ }
+
if (newGapStart == gapStart)
return;
else if (newGapStart < gapStart)
{
- System.arraycopy(buffer, newGapStart, buffer, newGapEnd,
- gapStart - newGapStart);
+ System.arraycopy(buffer, newGapStart, buffer, newGapEnd, gapStart
+ - newGapStart);
gapStart = newGapStart;
gapEnd = newGapEnd;
}
else
{
- System.arraycopy(buffer, gapEnd, buffer, gapStart,
- newGapStart - gapStart);
+ System.arraycopy(buffer, gapEnd, buffer, gapStart, newGapStart
+ - gapStart);
gapStart = newGapStart;
gapEnd = newGapEnd;
}
@@ -346,11 +457,38 @@ public class GapContent
/**
* Returns the allocated buffer array.
- *
+ *
* @return the allocated buffer array
*/
protected Object getArray()
{
return buffer;
}
+
+ /**
+ * Replaces a portion of the storage with the specified items.
+ *
+ * @param position the position at which to remove items
+ * @param rmSize the number of items to remove
+ * @param addItems the items to add at location
+ * @param addSize the number of items to add
+ */
+ protected void replace(int position, int rmSize, Object addItems,
+ int addSize)
+ {
+ // Remove content
+ shiftGap(position);
+ gapEnd += rmSize;
+
+ // If gap is too small, enlarge the gap.
+ if ((gapEnd - gapStart) < addSize)
+ shiftEnd(addSize);
+
+ // Add new items to the buffer.
+ if (addItems != null)
+ {
+ System.arraycopy(addItems, 0, buffer, gapStart, addSize);
+ gapStart += addSize;
+ }
+ }
}
diff --git a/libjava/classpath/javax/swing/text/InternationalFormatter.java b/libjava/classpath/javax/swing/text/InternationalFormatter.java
index 531a4c1aa10..cedaf59feeb 100644
--- a/libjava/classpath/javax/swing/text/InternationalFormatter.java
+++ b/libjava/classpath/javax/swing/text/InternationalFormatter.java
@@ -214,7 +214,7 @@ public class InternationalFormatter
/**
* Converts a value object into a String. This is done by invoking
- * {@link Format#format} on the specified <code>Format</code> object.
+ * {@link Format#format(Object)} on the specified <code>Format</code> object.
* If no format is set, then {@link DefaultFormatter#valueToString(Object)}
* is called as a fallback.
*
diff --git a/libjava/classpath/javax/swing/text/JTextComponent.java b/libjava/classpath/javax/swing/text/JTextComponent.java
index f2ef4d77ffe..b3fad79124c 100644
--- a/libjava/classpath/javax/swing/text/JTextComponent.java
+++ b/libjava/classpath/javax/swing/text/JTextComponent.java
@@ -96,7 +96,6 @@ public abstract class JTextComponent extends JComponent
/**
* Constructor AccessibleJTextComponent
- * @param component TODO
*/
public AccessibleJTextComponent()
{
@@ -712,8 +711,8 @@ public abstract class JTextComponent extends JComponent
* @return A Keymap associated with the provided name, or
* <code>null</code> if no such Keymap exists
*
- * @see #addKeymap()
- * @see #removeKeymap()
+ * @see #addKeymap
+ * @see #removeKeymap
* @see #keymaps
*/
public static Keymap getKeymap(String n)
@@ -728,7 +727,7 @@ public abstract class JTextComponent extends JComponent
*
* @return The keymap removed from the global table
*
- * @see #addKeymap()
+ * @see #addKeymap
* @see #getKeymap()
* @see #keymaps
*/
@@ -751,7 +750,7 @@ public abstract class JTextComponent extends JComponent
*
* @return The newly created Keymap
*
- * @see #removeKeymap()
+ * @see #removeKeymap
* @see #getKeymap()
* @see #keymaps
*/
@@ -769,7 +768,7 @@ public abstract class JTextComponent extends JComponent
*
* @return The component's current Keymap
*
- * @see #setKeymap()
+ * @see #setKeymap
* @see #keymap
*/
public Keymap getKeymap()
@@ -901,8 +900,8 @@ public abstract class JTextComponent extends JComponent
* @param actions The set of actions to resolve binding names against
*
* @see Action#NAME
- * @see Action#getValue()
- * @see KeyBinding#ActionName
+ * @see Action#getValue
+ * @see KeyBinding#actionName
*/
public static void loadKeymap(Keymap map,
JTextComponent.KeyBinding[] bindings,
@@ -921,12 +920,12 @@ public abstract class JTextComponent extends JComponent
* editor can run. Equivalent to calling
* <code>getUI().getEditorKit().getActions()</code>. This set of Actions
* is a reasonable value to provide as a parameter to {@link
- * #loadKeymap()}, when resolving a set of {@link #KeyBinding} objects
+ * #loadKeymap}, when resolving a set of {@link KeyBinding} objects
* against this component.
*
* @return The set of available Actions on this component's {@link EditorKit}
*
- * @see TextUI#getEditorKit()
+ * @see TextUI#getEditorKit
* @see EditorKit#getActions()
*/
public Action[] getActions()
@@ -1122,7 +1121,7 @@ public abstract class JTextComponent extends JComponent
/**
* This method sets the label's UI delegate.
*
- * @param ui The label's UI delegate.
+ * @param newUI The label's UI delegate.
*/
public void setUI(TextUI newUI)
{
@@ -1360,7 +1359,7 @@ public abstract class JTextComponent extends JComponent
/**
* Selects the text from the given postion to the selection end position.
*
- * @param end the start positon of the selected text.
+ * @param start the start positon of the selected text.
*/
public void setSelectionStart(int start)
{
@@ -1391,7 +1390,7 @@ public abstract class JTextComponent extends JComponent
* Selects a part of the content of the text component.
*
* @param start the start position of the selected text
- * @param ent the end position of the selected text
+ * @param end the end position of the selected text
*/
public void select(int start, int end)
{
@@ -1635,7 +1634,7 @@ public abstract class JTextComponent extends JComponent
*
* @throws IOException if the reader throws it.
*
- * @see getDocument()
+ * @see #getDocument()
* @see Document#getProperty(Object)
*/
public void read(Reader input, Object streamDescription)
diff --git a/libjava/classpath/javax/swing/text/PasswordView.java b/libjava/classpath/javax/swing/text/PasswordView.java
index 229fd2b508d..c3aa66cbe17 100644
--- a/libjava/classpath/javax/swing/text/PasswordView.java
+++ b/libjava/classpath/javax/swing/text/PasswordView.java
@@ -1,56 +1,59 @@
/* PasswordView.java --
- Copyright (C) 2004 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. */
+ Copyright (C) 2004 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;
import java.awt.Color;
+import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Shape;
import javax.swing.JPasswordField;
-public class PasswordView extends FieldView
+public class PasswordView
+ extends FieldView
{
/**
* Buffer for putting the echo char into it and
* then using it to draw it into the view.
*/
private char[] oneCharBuffer = new char[1];
-
+
public PasswordView(Element elem)
{
super(elem);
@@ -70,7 +73,7 @@ public class PasswordView extends FieldView
{
// Update font metrics.
updateMetrics();
-
+
// Draw character.
oneCharBuffer[0] = ch;
g.drawChars(oneCharBuffer, 0, 1, x, y);
@@ -82,7 +85,7 @@ public class PasswordView extends FieldView
private char getEchoChar()
{
char ch = ((JPasswordField) getContainer()).getEchoChar();
-
+
if (ch == 0)
ch = '*';
@@ -107,10 +110,10 @@ public class PasswordView extends FieldView
// Update font metrics.
updateMetrics();
-
+
// Get echo character.
char ch = getEchoChar();
-
+
// Set color for selected text.
g.setColor(selectedColor);
g.setColor(Color.BLACK);
@@ -120,7 +123,7 @@ public class PasswordView extends FieldView
char[] buffer = new char[len];
for (int index = 0; index < len; ++index)
buffer[index] = ch;
-
+
// Draw echo charaters.
g.drawChars(buffer, 0, len, x, y);
@@ -146,25 +149,96 @@ public class PasswordView extends FieldView
// Update font metrics.
updateMetrics();
-
+
// Get echo character.
char ch = getEchoChar();
-
+ Segment segment = new Segment();
+
// Set color for unselected text.
g.setColor(unselectedColor);
g.setColor(Color.BLACK);
// Initialize buffer for faster drawing of all characters.
- int len = p1 - p0;
+ p1--;
+ getDocument().getText(p0, p1 - p0, segment);
+ int len = segment.toString().length();
+
char[] buffer = new char[len];
for (int index = 0; index < len; ++index)
buffer[index] = ch;
+ y += getPreferredSpan(Y_AXIS)/2;
+
// Draw echo charaters.
g.drawChars(buffer, 0, len, x, y);
-
+
// Return new x position right of all drawn characters.
- return x + len * metrics.charWidth(ch);
+ return x + (len * metrics.charWidth(ch));
+ }
+
+ /**
+ * Determines the preferred span for this view along an axis.
+ *
+ * @param axis to get the preferred span of
+ * @return the preferred span of the axis
+ */
+ public float getPreferredSpan(int axis)
+ {
+ if (axis != X_AXIS && axis != Y_AXIS)
+ throw new IllegalArgumentException();
+
+ FontMetrics fm = getFontMetrics();
+
+ if (axis == Y_AXIS)
+ return fm.getHeight();
+
+ String text;
+ Element elem = getElement();
+
+ try
+ {
+ text = elem.getDocument().getText(elem.getStartOffset(),
+ elem.getEndOffset());
+ }
+ catch (BadLocationException e)
+ {
+ // This should never happen.
+ text = "";
+ }
+ return fm.stringWidth(text);
}
-}
+ /**
+ * Provides a mapping from the document model coordinate space to the
+ * coordinate space of the view mapped to it.
+ *
+ * @param pos - the position to convert >= 0
+ * @param a - the allocated region to render into
+ * @param b - typesafe enumeration to indicate bias to a position in the model.
+ * @return the bounding box of the given position
+ * @throws BadLocationException if the given position does not
+ * represent a valid location in the associated document
+ */
+ public Shape modelToView(int pos, Shape a, Position.Bias b)
+ throws BadLocationException
+ {
+ return super.modelToView(pos, a, b);
+ }
+
+ /**
+ * Provides a mapping from the view coordinate space to the logical
+ * coordinate space of the model.
+ *
+ * @param fx - the X coordinate >= 0.0f
+ * @param fy - the Y coordinate >= 0.0f
+ * @param a - the allocated region to render into
+ * @param bias - typesafe enumeration to indicate bias to a position in the model.
+ * @return the location within the model that best represents
+ * the given point in the view
+ *
+ */
+ public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias)
+ {
+ return super.viewToModel(fx, fy, a, bias);
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/PlainDocument.java b/libjava/classpath/javax/swing/text/PlainDocument.java
index c3f59e436cb..71070e92da7 100644
--- a/libjava/classpath/javax/swing/text/PlainDocument.java
+++ b/libjava/classpath/javax/swing/text/PlainDocument.java
@@ -135,22 +135,6 @@ public class PlainDocument extends AbstractDocument
start, end - len);
rootElement.replace(i1, i2 - i1, new Element[]{ newEl });
}
- else
- {
- // otherwise only adjust indices of the element
- LeafElement el1 = (LeafElement) rootElement.getElement(i1);
- el1.end -= len;
- }
-
- // reindex remaining elements
- for (int i = rootElement.getElementIndex(p0) + 1;
- i < rootElement.getElementCount(); i++)
- {
- LeafElement el = (LeafElement) rootElement.getElement(i);
- el.start -= len;
- el.end -= len;
- }
-
}
public Element getDefaultRootElement()
diff --git a/libjava/classpath/javax/swing/text/PlainView.java b/libjava/classpath/javax/swing/text/PlainView.java
index 5d1fab00032..91d7547e77c 100644
--- a/libjava/classpath/javax/swing/text/PlainView.java
+++ b/libjava/classpath/javax/swing/text/PlainView.java
@@ -237,5 +237,23 @@ public class PlainView extends View
return span;
}
+
+ /**
+ * Maps coordinates from the <code>View</code>'s space into a position
+ * in the document model.
+ *
+ * @param x the x coordinate in the view space
+ * @param y the y coordinate in the view space
+ * @param a the allocation of this <code>View</code>
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates <code>x, y</code>
+ */
+ public int viewToModel(float x, float y, Shape a, Position.Bias[] b)
+ {
+ // FIXME: not implemented
+ return 0;
+ }
}
diff --git a/libjava/classpath/javax/swing/text/StyledEditorKit.java b/libjava/classpath/javax/swing/text/StyledEditorKit.java
index 459f2438679..89c4cf18ee4 100644
--- a/libjava/classpath/javax/swing/text/StyledEditorKit.java
+++ b/libjava/classpath/javax/swing/text/StyledEditorKit.java
@@ -46,458 +46,663 @@ import java.io.Serializable;
import javax.swing.Action;
import javax.swing.JEditorPane;
+import javax.swing.JTextPane;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
/**
- * StyledEditorKit
+ * An {@link EditorKit} that supports editing styled text.
*
* @author Andrew Selkirk
+ * @author Roman Kennke (roman@kennke.org)
*/
public class StyledEditorKit extends DefaultEditorKit
{
+ /** The serialVersionUID. */
private static final long serialVersionUID = 7002391892985555948L;
/**
- * UnderlineAction
+ * Toggles the underline attribute for the selected text.
*/
public static class UnderlineAction extends StyledEditorKit.StyledTextAction
{
/**
- * Constructor UnderlineAction
+ * Creates an instance of <code>UnderlineAction</code>.
*/
public UnderlineAction()
{
- super("TODO");
- // TODO
+ super("TODO"); // TODO: Figure out name for this action.
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the <code>ActionEvent</code> that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ JEditorPane editor = getEditor(event);
+ StyledDocument doc = getStyledDocument(editor);
+ Element el = doc.getCharacterElement(editor.getSelectionStart());
+ boolean isUnderline = StyleConstants.isUnderline(el.getAttributes());
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setUnderline(atts, ! isUnderline);
+ setCharacterAttributes(editor, atts, false);
}
}
/**
- * ItalicAction
+ * Toggles the italic attribute for the selected text.
*/
public static class ItalicAction extends StyledEditorKit.StyledTextAction
{
/**
- * Constructor ItalicAction
+ * Creates an instance of <code>ItalicAction</code>.
*/
public ItalicAction()
{
- super("TODO");
- // TODO
+ super("TODO"); // TODO: Figure out correct name of this Action.
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the <code>ActionEvent</code> that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ JEditorPane editor = getEditor(event);
+ StyledDocument doc = getStyledDocument(editor);
+ Element el = doc.getCharacterElement(editor.getSelectionStart());
+ boolean isItalic = StyleConstants.isItalic(el.getAttributes());
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setItalic(atts, ! isItalic);
+ setCharacterAttributes(editor, atts, false);
}
}
/**
- * BoldAction
+ * Toggles the bold attribute for the selected text.
*/
public static class BoldAction extends StyledEditorKit.StyledTextAction
{
/**
- * Constructor BoldAction
+ * Creates an instance of <code>BoldAction</code>.
*/
public BoldAction()
{
- super("TODO");
- // TODO
+ super("TODO"); // TODO: Figure out correct name of this Action.
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the <code>ActionEvent</code> that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ JEditorPane editor = getEditor(event);
+ StyledDocument doc = getStyledDocument(editor);
+ Element el = doc.getCharacterElement(editor.getSelectionStart());
+ boolean isBold = StyleConstants.isBold(el.getAttributes());
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setItalic(atts, ! isBold);
+ setCharacterAttributes(editor, atts, false);
}
}
/**
- * AlignmentAction
+ * Sets the alignment attribute on the selected text.
*/
public static class AlignmentAction extends StyledEditorKit.StyledTextAction
{
/**
- * a
+ * The aligment to set.
*/
private int a;
/**
- * Constructor AlignmentAction
- * @param nm TODO
- * @param a TODO
+ * Creates a new instance of <code>AlignmentAction</code> to set the
+ * alignment to <code>a</code>.
+ *
+ * @param nm the name of the Action
+ * @param a the alignment to set
*/
public AlignmentAction(String nm, int a)
{
- super("TODO");
- // TODO
+ super(nm);
+ this.a = a;
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the <code>ActionEvent</code> that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setAlignment(atts, a);
+ setParagraphAttributes(getEditor(event), atts, false);
}
}
/**
- * ForegroundAction
+ * Sets the foreground color attribute on the selected text.
*/
public static class ForegroundAction extends StyledEditorKit.StyledTextAction
{
/**
- * fg
+ * The foreground color to set.
*/
private Color fg;
/**
- * Constructor ForegroundAction
- * @param nm TODO
- * @param fg TODO
+ * Creates a new instance of <code>ForegroundAction</code> to set the
+ * foreground color to <code>fg</code>.
+ *
+ * @param nm the name of the Action
+ * @param fg the foreground color to set
*/
public ForegroundAction(String nm, Color fg)
{
- super("TODO");
- // TODO
+ super(nm);
+ this.fg = fg;
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the <code>ActionEvent</code> that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setForeground(atts, fg);
+ setCharacterAttributes(getEditor(event), atts, false);
}
}
/**
- * FontSizeAction
+ * Sets the font size attribute on the selected text.
*/
public static class FontSizeAction extends StyledEditorKit.StyledTextAction
{
/**
- * size
+ * The font size to set.
*/
private int size;
/**
- * Constructor FontSizeAction
- * @param nm TODO
- * @param size TODO
+ * Creates a new instance of <code>FontSizeAction</code> to set the
+ * font size to <code>size</code>.
+ *
+ * @param nm the name of the Action
+ * @param size the font size to set
*/
public FontSizeAction(String nm, int size)
{
- super("TODO");
- // TODO
+ super(nm);
+ this.size = size;
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the <code>ActionEvent</code> that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setFontSize(atts, size);
+ setCharacterAttributes(getEditor(event), atts, false);
}
}
/**
- * FontFamilyAction
+ * Sets the font family attribute on the selected text.
*/
public static class FontFamilyAction extends StyledEditorKit.StyledTextAction
{
/**
- * family
+ * The font family to set.
*/
private String family;
/**
- * Constructor FontFamilyAction
- * @param nm TODO
- * @param family TODO
+ * Creates a new instance of <code>FontFamilyAction</code> to set the
+ * font family to <code>family</code>.
+ *
+ * @param nm the name of the Action
+ * @param family the font family to set
*/
public FontFamilyAction(String nm, String family)
{
- super("TODO");
- // TODO
+ super(nm);
+ this.family = family;
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the <code>ActionEvent</code> that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setFontFamily(atts, family);
+ setCharacterAttributes(getEditor(event), atts, false);
}
}
/**
- * StyledTextAction
+ * The abstract superclass of all styled TextActions. This class
+ * provides some useful methods to manipulate the text attributes.
*/
public abstract static class StyledTextAction extends TextAction
{
/**
- * Constructor StyledTextAction
- * @param nm TODO
+ * Creates a new instance of <code>StyledTextAction</code>.
+ *
+ * @param nm the name of the <code>StyledTextAction</code>
*/
public StyledTextAction(String nm)
{
super(nm);
- // TODO
}
/**
- * getEditor
- * @param event TODO
- * @returns JEditorPane
+ * Returns the <code>JEditorPane</code> component from which the
+ * <code>ActionEvent</code> originated.
+ *
+ * @param event the <code>ActionEvent</code>
+ * @return the <code>JEditorPane</code> component from which the
+ * <code>ActionEvent</code> originated
*/
protected final JEditorPane getEditor(ActionEvent event)
{
- return null; // TODO
+ return (JEditorPane) getTextComponent(event);
}
/**
- * setCharacterAttributes
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
+ * Sets the specified character attributes on the currently selected
+ * text of <code>editor</code>. If <code>editor</code> does not have
+ * a selection, then the attributes are used as input attributes
+ * for newly inserted content.
+ *
+ * @param editor the <code>JEditorPane</code> component
+ * @param atts the text attributes to set
+ * @param replace if <code>true</code> the current attributes of the
+ * selection are replaces, otherwise they are merged
*/
- protected final void setCharacterAttributes(JEditorPane value0,
- AttributeSet value1,
- boolean value2)
+ protected final void setCharacterAttributes(JEditorPane editor,
+ AttributeSet atts,
+ boolean replace)
{
- // TODO
+ Document doc = editor.getDocument();
+ if (doc instanceof StyledDocument)
+ {
+ StyledDocument styleDoc = (StyledDocument) editor.getDocument();
+ EditorKit kit = editor.getEditorKit();
+ if (!(kit instanceof StyledEditorKit))
+ {
+ StyledEditorKit styleKit = (StyledEditorKit) kit;
+ int start = editor.getSelectionStart();
+ int end = editor.getSelectionEnd();
+ int dot = editor.getCaret().getDot();
+ if (start == dot && end == dot)
+ {
+ // If there is no selection, then we only update the
+ // input attributes.
+ MutableAttributeSet inputAttributes =
+ styleKit.getInputAttributes();
+ inputAttributes.addAttributes(atts);
+ }
+ else
+ styleDoc.setCharacterAttributes(start, end, atts, replace);
+ }
+ else
+ throw new AssertionError("The EditorKit for StyledTextActions "
+ + "is expected to be a StyledEditorKit");
+ }
+ else
+ throw new AssertionError("The Document for StyledTextActions is "
+ + "expected to be a StyledDocument.");
}
/**
- * getStyledDocument
- * @param value0 TODO
- * @returns StyledDocument
+ * Returns the {@link StyledDocument} that is used by <code>editor</code>.
+ *
+ * @param editor the <code>JEditorPane</code> from which to get the
+ * <code>StyledDocument</code>
+ *
+ * @return the {@link StyledDocument} that is used by <code>editor</code>
*/
- protected final StyledDocument getStyledDocument(JEditorPane value0)
+ protected final StyledDocument getStyledDocument(JEditorPane editor)
{
- return null; // TODO
+ Document doc = editor.getDocument();
+ if (!(doc instanceof StyledDocument))
+ throw new AssertionError("The Document for StyledEditorKits is "
+ + "expected to be a StyledDocument.");
+
+ return (StyledDocument) doc;
}
/**
- * getStyledEditorKit
- * @param value0 TODO
- * @returns StyledEditorKit
+ * Returns the {@link StyledEditorKit} that is used by <code>editor</code>.
+ *
+ * @param editor the <code>JEditorPane</code> from which to get the
+ * <code>StyledEditorKit</code>
+ *
+ * @return the {@link StyledEditorKit} that is used by <code>editor</code>
*/
- protected final StyledEditorKit getStyledEditorKit(JEditorPane value0)
+ protected final StyledEditorKit getStyledEditorKit(JEditorPane editor)
{
- return null; // TODO
+ EditorKit kit = editor.getEditorKit();
+ if (!(kit instanceof StyledEditorKit))
+ throw new AssertionError("The EditorKit for StyledDocuments is "
+ + "expected to be a StyledEditorKit.");
+
+ return (StyledEditorKit) kit;
}
/**
- * setParagraphAttributes
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
+ * Sets the specified character attributes on the paragraph that
+ * contains the currently selected
+ * text of <code>editor</code>. If <code>editor</code> does not have
+ * a selection, then the attributes are set on the paragraph that
+ * contains the current caret position.
+ *
+ * @param editor the <code>JEditorPane</code> component
+ * @param atts the text attributes to set
+ * @param replace if <code>true</code> the current attributes of the
+ * selection are replaces, otherwise they are merged
*/
- protected final void setParagraphAttributes(JEditorPane value0,
- AttributeSet value1,
- boolean value2)
+ protected final void setParagraphAttributes(JEditorPane editor,
+ AttributeSet atts,
+ boolean replace)
{
- // TODO
+ Document doc = editor.getDocument();
+ if (doc instanceof StyledDocument)
+ {
+ StyledDocument styleDoc = (StyledDocument) editor.getDocument();
+ EditorKit kit = editor.getEditorKit();
+ if (!(kit instanceof StyledEditorKit))
+ {
+ StyledEditorKit styleKit = (StyledEditorKit) kit;
+ int start = editor.getSelectionStart();
+ int end = editor.getSelectionEnd();
+ int dot = editor.getCaret().getDot();
+ if (start == dot && end == dot)
+ {
+ // If there is no selection, then we only update the
+ // input attributes.
+ MutableAttributeSet inputAttributes =
+ styleKit.getInputAttributes();
+ inputAttributes.addAttributes(atts);
+ }
+ else
+ styleDoc.setParagraphAttributes(start, end, atts, replace);
+ }
+ else
+ throw new AssertionError("The EditorKit for StyledTextActions "
+ + "is expected to be a StyledEditorKit");
+ }
+ else
+ throw new AssertionError("The Document for StyledTextActions is "
+ + "expected to be a StyledDocument.");
}
}
/**
- * StyledViewFactory
+ * A {@link ViewFactory} that is able to create {@link View}s for
+ * the <code>Element</code>s that are supported by
+ * <code>StyledEditorKit</code>, namely the following types of Elements:
+ *
+ * <ul>
+ * <li>{@link AbstractDocument.ContentElementName}</li>
+ * <li>{@link AbstractDocument.ParagraphElementName}</li>
+ * <li>{@link AbstractDocument.SectionElementName}</li>
+ * <li>{@link StyleContext.ComponentElementName}</li>
+ * <li>{@link StyleContext.IconElementName}</li>
+ * </ul>
*/
static class StyledViewFactory
implements ViewFactory
{
/**
- * Constructor StyledViewFactory
- */
- StyledViewFactory()
- {
- // TODO
- }
-
- /**
- * create
- * @param value0 TODO
- * @returns View
+ * Creates a {@link View} for the specified <code>Element</code>.
+ *
+ * @param element the <code>Element</code> to create a <code>View</code>
+ * for
+ * @return the <code>View</code> for the specified <code>Element</code>
+ * or <code>null</code> if the type of <code>element</code> is
+ * not supported
*/
- public View create(Element value0)
+ public View create(Element element)
{
- return null; // TODO
+ String name = element.getName();
+ View view = null;
+ if (name.equals(AbstractDocument.ContentElementName))
+ view = new LabelView(element);
+ else if (name.equals(AbstractDocument.ParagraphElementName))
+ view = new ParagraphView(element);
+ else if (name.equals(AbstractDocument.SectionElementName))
+ view = new BoxView(element, View.Y_AXIS);
+ else if (name.equals(StyleConstants.ComponentElementName))
+ view = new ComponentView(element);
+ else if (name.equals(StyleConstants.IconElementName))
+ view = new IconView(element);
+ else
+ throw new AssertionError("Unknown Element type: "
+ + element.getClass().getName() + " : "
+ + name);
+ return view;
}
}
/**
- * AttributeTracker
+ * Keeps track of the caret position and updates the currentRun
+ * <code>Element</code> and the <code>inputAttributes</code>.
*/
- class AttributeTracker
- implements CaretListener, PropertyChangeListener, Serializable
+ class CaretTracker
+ implements CaretListener
{
/**
- * Constructor AttributeTracker
- * @param value0 TODO
- */
- AttributeTracker(StyledEditorKit value0)
- {
- // TODO
- }
-
- /**
- * updateInputAttributes
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
+ * Notifies an update of the caret position.
+ *
+ * @param ev the event for the caret update
*/
- void updateInputAttributes(int value0, int value1, JTextComponent value2)
+ public void caretUpdate(CaretEvent ev)
{
- // TODO
- }
-
- /**
- * propertyChange
- * @param value0 TODO
- */
- public void propertyChange(PropertyChangeEvent value0)
- {
- // TODO
- }
-
- /**
- * caretUpdate
- * @param value0 TODO
- */
- public void caretUpdate(CaretEvent value0)
- {
- // TODO
+ Object source = ev.getSource();
+ if (!(source instanceof JTextComponent))
+ throw new AssertionError("CaretEvents are expected to come from a"
+ + "JTextComponent.");
+
+ JTextComponent text = (JTextComponent) source;
+ Document doc = text.getDocument();
+ if (!(doc instanceof StyledDocument))
+ throw new AssertionError("The Document used by StyledEditorKits is"
+ + "expected to be a StyledDocument");
+
+ StyledDocument styleDoc = (StyledDocument) doc;
+ currentRun = styleDoc.getCharacterElement(ev.getDot());
+ createInputAttributes(currentRun, inputAttributes);
}
}
/**
- * currentRun
+ * Stores the <code>Element</code> at the current caret position. This
+ * is updated by {@link CaretTracker}.
*/
Element currentRun;
/**
- * currentParagraph
+ * The current input attributes. This is updated by {@link CaretTracker}.
*/
- Element currentParagraph;
+ MutableAttributeSet inputAttributes;
/**
- * inputAttributes
+ * The CaretTracker that keeps track of the current input attributes, and
+ * the current character run Element.
*/
- MutableAttributeSet inputAttributes;
+ CaretTracker caretTracker;
+
+ /**
+ * The ViewFactory for StyledEditorKits.
+ */
+ StyledViewFactory viewFactory;
/**
- * Constructor StyledEditorKit
+ * Creates a new instance of <code>StyledEditorKit</code>.
*/
public StyledEditorKit()
{
- // TODO
+ inputAttributes = new SimpleAttributeSet();
}
/**
- * clone
- * @returns Object
+ * Creates an exact copy of this <code>StyledEditorKit</code>.
+ *
+ * @return an exact copy of this <code>StyledEditorKit</code>
*/
public Object clone()
{
- return null; // TODO
+ StyledEditorKit clone = (StyledEditorKit) super.clone();
+ // FIXME: Investigate which fields must be copied.
+ return clone;
}
/**
- * getActions
- * @returns Action[]
+ * Returns the <code>Action</code>s supported by this {@link EditorKit}.
+ * This includes the {@link BoldAction}, {@link ItalicAction} and
+ * {@link UnderlineAction} as well as the <code>Action</code>s supported
+ * by {@link DefaultEditorKit}.
+ *
+ * The other <code>Action</code>s of <code>StyledEditorKit</code> are not
+ * returned here, since they require a parameter and thus custom
+ * instantiation.
+ *
+ * @return the <code>Action</code>s supported by this {@link EditorKit}
*/
public Action[] getActions()
{
- return null; // TODO
+ Action[] actions1 = super.getActions();
+ Action[] myActions = new Action[] { new BoldAction(), new ItalicAction(),
+ new UnderlineAction() };
+ return TextAction.augmentList(actions1, myActions);
}
/**
- * getInputAttributes
- * @returns MutableAttributeSet
+ * Returns the current input attributes. These are automatically set on
+ * any newly inserted content, if not specified otherwise.
+ *
+ * @return the current input attributes
*/
public MutableAttributeSet getInputAttributes()
{
- return null; // TODO
+ return inputAttributes;
}
/**
- * getCharacterAttributeRun
- * @returns Element
+ * Returns the {@link Element} that represents the character run at the
+ * current caret position.
+ *
+ * @return the {@link Element} that represents the character run at the
+ * current caret position
*/
public Element getCharacterAttributeRun()
{
- return null; // TODO
+ return currentRun;
}
/**
- * createDefaultDocument
- * @returns Document
+ * Creates the default {@link Document} supported by this
+ * <code>EditorKit</code>. This is an instance of
+ * {@link DefaultStyledDocument} in this case but may be overridden by
+ * subclasses.
+ *
+ * @return an instance of <code>DefaultStyledDocument</code>
*/
public Document createDefaultDocument()
{
- return null; // TODO
+ return new DefaultStyledDocument();
}
/**
- * install
- * @param component TODO
+ * Installs this <code>EditorKit</code> on the specified {@link JEditorPane}.
+ * This basically involves setting up required listeners on the
+ * <code>JEditorPane</code>.
+ *
+ * @param component the <code>JEditorPane</code> to install this
+ * <code>EditorKit</code> on
*/
public void install(JEditorPane component)
{
- // TODO
+ CaretTracker tracker = new CaretTracker();
+ component.addCaretListener(tracker);
}
/**
- * deinstall
- * @param component TODO
+ * Deinstalls this <code>EditorKit</code> from the specified
+ * {@link JEditorPane}. This basically involves removing all listeners from
+ * <code>JEditorPane</code> that have been set up by this
+ * <code>EditorKit</code>.
+ *
+ * @param component the <code>JEditorPane</code> from which to deinstall this
+ * <code>EditorKit</code>
*/
public void deinstall(JEditorPane component)
{
- // TODO
+ CaretTracker t = caretTracker;
+ if (t != null)
+ component.removeCaretListener(t);
+ caretTracker = null;
}
/**
- * getViewFactory
- * @returns ViewFactory
+ * Returns a {@link ViewFactory} that is able to create {@link View}s
+ * for {@link Element}s that are supported by this <code>EditorKit</code>,
+ * namely the following types of <code>Element</code>s:
+ *
+ * <ul>
+ * <li>{@link AbstractDocument.ContentElementName}</li>
+ * <li>{@link AbstractDocument.ParagraphElementName}</li>
+ * <li>{@link AbstractDocument.SectionElementName}</li>
+ * <li>{@link StyleContext.ComponentElementName}</li>
+ * <li>{@link StyleContext.IconElementName}</li>
+ * </ul>
+ *
+ * @return a {@link ViewFactory} that is able to create {@link View}s
+ * for {@link Element}s that are supported by this <code>EditorKit</code>
*/
public ViewFactory getViewFactory()
{
- return null; // TODO
+ if (viewFactory == null)
+ viewFactory = new StyledViewFactory();
+ return viewFactory;
}
/**
- * createInputAttributes
- * @param element TODO
- * @param set TODO
+ * Copies the text attributes from <code>element</code> to <code>set</code>.
+ * This is called everytime when the caret position changes to keep
+ * track of the current input attributes. The attributes in <code>set</code>
+ * are cleaned before adding the attributes of <code>element</code>.
+ *
+ * This method filters out attributes for element names, <code>Icon</code>s
+ * and <code>Component</code>s.
+ *
+ * @param element the <code>Element</code> from which to copy the text
+ * attributes
+ * @param set the inputAttributes to copy the attributes to
*/
- protected void createInputAttributes(Element element, MutableAttributeSet set)
+ protected void createInputAttributes(Element element,
+ MutableAttributeSet set)
{
- // TODO
+ AttributeSet atts = element.getAttributes();
+ set.removeAttributes(set);
+ // FIXME: Filter out component, icon and element name attributes.
+ set.addAttributes(atts);
}
}
diff --git a/libjava/classpath/javax/swing/text/View.java b/libjava/classpath/javax/swing/text/View.java
index 4d9ed7b3122..24efba9a1bc 100644
--- a/libjava/classpath/javax/swing/text/View.java
+++ b/libjava/classpath/javax/swing/text/View.java
@@ -62,11 +62,6 @@ public abstract class View implements SwingConstants
private View parent;
/**
- * The child views.
- */
- View[] children;
-
- /**
* Creates a new <code>View</code> instance.
*
* @param elem an <code>Element</code> value
@@ -74,7 +69,6 @@ public abstract class View implements SwingConstants
public View(Element elem)
{
elt = elem;
- children = new View[0];
}
public abstract void paint(Graphics g, Shape s);
@@ -92,7 +86,10 @@ public abstract class View implements SwingConstants
public Container getContainer()
{
View parent = getParent();
- return parent != null ? parent.getContainer() : null;
+ if (parent == null)
+ throw new AssertionError("The parent of a View must not be null.");
+
+ return parent.getContainer();
}
public Document getDocument()
@@ -178,12 +175,13 @@ public abstract class View implements SwingConstants
public void append(View view)
{
View[] array = { view };
- replace(getViewCount(), 1, array);
+ int offset = getViewCount();
+ replace(offset, 0, array);
}
public void removeAll()
{
- replace(0, getViewCount(), null);
+ replace(0, getViewCount(), new View[0]);
}
public void remove(int index)
@@ -250,8 +248,6 @@ public abstract class View implements SwingConstants
{
if (parent != null)
parent.preferenceChanged(this, width, height);
- else
- ((JComponent) getContainer()).revalidate();
}
public int getBreakWeight(int axis, float pos, float len)
@@ -351,7 +347,7 @@ public abstract class View implements SwingConstants
Element el = getElement();
DocumentEvent.ElementChange ec = ev.getChange(el);
if (ec != null)
- updateChildren(ec, ev, vf);
+ updateChildren(ec, ev, vf);
forwardUpdate(ec, ev, shape, vf);
updateLayout(ec, ev, shape);
}
@@ -382,16 +378,12 @@ public abstract class View implements SwingConstants
{
Element[] added = ec.getChildrenAdded();
Element[] removed = ec.getChildrenRemoved();
- View[] newChildren = new View[children.length + added.length
- - removed.length];
int index = ec.getIndex();
- System.arraycopy(children, 0, newChildren, 0, index);
- System.arraycopy(children, index, added, 0, added.length);
- int index2 = index + removed.length;
- int len2 = children.length - index2;
- System.arraycopy(children, index2, newChildren, index + added.length,
- len2);
- children = newChildren;
+
+ View[] newChildren = new View[added.length];
+ for (int i = 0; i < added.length; ++i)
+ newChildren[i] = vf.create(added[i]);
+ replace(index, removed.length, newChildren);
return true;
}
@@ -412,9 +404,10 @@ public abstract class View implements SwingConstants
protected void forwardUpdate(DocumentEvent.ElementChange ec,
DocumentEvent ev, Shape shape, ViewFactory vf)
{
- for (int i = 0; i < children.length; i++)
+ int count = getViewCount();
+ for (int i = 0; i < count; i++)
{
- View child = children[i];
+ View child = getView(i);
forwardUpdateToView(child, ev, shape, vf);
}
}
@@ -459,5 +452,104 @@ public abstract class View implements SwingConstants
if (ec != null)
preferenceChanged(this, true, true);
}
-}
+ /**
+ * Maps a position in the document into the coordinate space of the View.
+ * The output rectangle usually reflects the font height but has a width
+ * of zero.
+ *
+ * @param pos the position of the character in the model
+ * @param a the area that is occupied by the view
+ * @param b either {@link Position.Bias#Forward} or
+ * {@link Position.Bias#Backward} depending on the preferred
+ * direction bias. If <code>null</code> this defaults to
+ * <code>Position.Bias.Forward</code>
+ *
+ * @return a rectangle that gives the location of the document position
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if <code>pos</code> is invalid
+ * @throws IllegalArgumentException if b is not one of the above listed
+ * valid values
+ */
+ public abstract Shape modelToView(int pos, Shape a, Position.Bias b)
+ throws BadLocationException;
+
+ /**
+ * Maps a region in the document into the coordinate space of the View.
+ *
+ * @param p1 the beginning position inside the document
+ * @param b1 the direction bias for the beginning position
+ * @param p2 the end position inside the document
+ * @param b2 the direction bias for the end position
+ * @param a the area that is occupied by the view
+ *
+ * @return a rectangle that gives the span of the document region
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if <code>p1</code> or <code>p2</code> are
+ * invalid
+ * @throws IllegalArgumentException if b1 or b2 is not one of the above
+ * listed valid values
+ */
+ public Shape modelToView(int p1, Position.Bias b1,
+ int p2, Position.Bias b2, Shape a)
+ throws BadLocationException
+ {
+ if (b1 != Position.Bias.Forward && b1 != Position.Bias.Backward)
+ throw new IllegalArgumentException
+ ("b1 must be either Position.Bias.Forward or Position.Bias.Backward");
+ if (b2 != Position.Bias.Forward && b2 != Position.Bias.Backward)
+ throw new IllegalArgumentException
+ ("b2 must be either Position.Bias.Forward or Position.Bias.Backward");
+ Shape s1 = modelToView(p1, a, b1);
+ Shape s2 = modelToView(p2, a, b2);
+ return s1.getBounds().union(s2.getBounds());
+ }
+
+ /**
+ * Maps coordinates from the <code>View</code>'s space into a position
+ * in the document model.
+ *
+ * @param x the x coordinate in the view space
+ * @param y the y coordinate in the view space
+ * @param a the allocation of this <code>View</code>
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates <code>x, y</code>
+ */
+ public abstract int viewToModel(float x, float y, Shape a, Position.Bias[] b);
+
+
+ /**
+ * Dumps the complete View hierarchy. This method can be used for debugging
+ * purposes.
+ */
+ void dump()
+ {
+ // Climb up the hierarchy to the parent.
+ View parent = getParent();
+ if (parent != null)
+ parent.dump();
+ else
+ dump(0);
+ }
+
+ /**
+ * Dumps the view hierarchy below this View with the specified indentation
+ * level.
+ *
+ * @param indent the indentation level to be used for this view
+ */
+ void dump(int indent)
+ {
+ for (int i = 0; i < indent; ++i)
+ System.out.print('.');
+ System.out.println(this);
+
+ int count = getViewCount();
+ for (int i = 0; i < count; ++i)
+ getView(i).dump(indent + 1);
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
index 7ae78ec0725..c0182fe6ac9 100644
--- a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
+++ b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package javax.swing.text.html;
+import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
@@ -75,7 +76,7 @@ public class HTMLEditorKit
public abstract void parse(Reader reader, ParserCallback callback,
boolean ignoreCharSet
)
- throws java.io.IOException;
+ throws IOException;
}
/**
@@ -123,8 +124,8 @@ public class HTMLEditorKit
* The method is called when the HTML closing tag ((like &lt;/table&gt;)
* is found or if the parser concludes that the one should be present
* in the current position.
- * @param The tag being handled
- * @position the tag position in the text being parsed.
+ * @param tag The tag being handled
+ * @param position the tag position in the text being parsed.
*/
public void handleEndTag(HTML.Tag tag, int position)
{
diff --git a/libjava/classpath/javax/swing/text/html/parser/DTD.java b/libjava/classpath/javax/swing/text/html/parser/DTD.java
index 63d03eaccf0..f17ca011ea0 100644
--- a/libjava/classpath/javax/swing/text/html/parser/DTD.java
+++ b/libjava/classpath/javax/swing/text/html/parser/DTD.java
@@ -62,7 +62,8 @@ import java.util.Vector;
* <p>
* If you need more information about SGML DTD documents,
* the author suggests to read SGML tutorial on
- * {@link http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html}.
+ * <a href="http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html"
+ * >http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html</a>.
* We also recommend Goldfarb C.F (1991) <i>The SGML Handbook</i>,
* Oxford University Press, 688 p, ISBN: 0198537379.
* </p>
@@ -402,7 +403,7 @@ public class DTD
* placed to the field
* {@link javax.swing.text.html.parser.AttributeList#next },
* creating a linked list.
- * @return
+ * @return The attributes.
*/
protected AttributeList defAttributeList(String name, int type, int modifier,
String default_value,
@@ -541,7 +542,7 @@ public class DTD
* The unknown elements are automatically defined and added
* to the element table.
* @param elements
- * @return
+ * @return The bit set.
*/
private BitSet bitSet(String[] elements)
{
diff --git a/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java b/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java
index a771264a1ad..75e7afb4db6 100644
--- a/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java
+++ b/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java
@@ -40,14 +40,16 @@ package javax.swing.text.html.parser;
/**
* <p>This class defines the SGML basic types, used for describing HTML 4.01
- * at {@link http://www.w3.org/TR/html4/types.html }. Not all constants,
+ * at <a href="http://www.w3.org/TR/html4/types.html"
+ * >http://www.w3.org/TR/html4/types.html</a>. Not all constants,
* defined here, are actually used in HTML 4.01 SGML specification. Some others
* are defined just as part of the required implementation.
* </p>
* <p>
* If you need more information about SGML DTD documents,
* the author suggests to read SGML tutorial on
- * {@link http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html}.
+ * <a href="http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html"
+ * >http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html</a>.
* We also recommend Goldfarb C.F (1991) <i>The SGML Handbook</i>,
* Oxford University Press, 688 p, ISBN: 0198537379.
* </p>
diff --git a/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java b/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java
index c706f4d0f0b..164297f1882 100644
--- a/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java
+++ b/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java
@@ -167,7 +167,7 @@ public class DocumentParser
* to get a default DTD; you must either refer to the implementation -
* specific packages, write your own DTD or obtain the working instance
* of parser in other way, for example, by calling
- * {@link javax.swing.text.html.HTMLEditorKit#getParser() }.
+ * {@link javax.swing.text.html.HTMLEditorKit#getParser()}.
* @param a_dtd a DTD to use.
*/
public DocumentParser(DTD a_dtd)
@@ -180,18 +180,18 @@ public class DocumentParser
* Parses the HTML document, calling methods of the provided
* callback. This method must be multithread - safe.
* @param reader The reader to read the HTML document from
- * @param callback The callback that is notifyed about the presence
+ * @param aCallback The callback that is notifyed about the presence
* of HTML elements in the document.
* @param ignoreCharSet If thrue, any charset changes during parsing
* are ignored.
* @throws java.io.IOException
*/
- public void parse(Reader reader, HTMLEditorKit.ParserCallback a_callback,
+ public void parse(Reader reader, HTMLEditorKit.ParserCallback aCallback,
boolean ignoreCharSet
)
throws IOException
{
- callBack = a_callback;
+ callBack = aCallback;
gnu.parse(reader);
callBack.handleEndOfLineString(gnu.getEndOfLineSequence());
@@ -230,7 +230,7 @@ public class DocumentParser
* The method is called when the HTML closing tag ((like &lt;/table&gt;)
* is found or if the parser concludes that the one should be present
* in the current position.
- * @param The tag being handled
+ * @param tag The tag being handled
*/
protected void handleEndTag(TagElement tag)
{
@@ -245,7 +245,7 @@ public class DocumentParser
* The method is called when the HTML opening tag ((like &lt;table&gt;)
* is found or if the parser concludes that the one should be present
* in the current position.
- * @param The tag being handled
+ * @param tag The tag being handled
*/
protected void handleStartTag(TagElement tag)
{
diff --git a/libjava/classpath/javax/swing/text/html/parser/Element.java b/libjava/classpath/javax/swing/text/html/parser/Element.java
index f0a0f3303cb..098983c6923 100644
--- a/libjava/classpath/javax/swing/text/html/parser/Element.java
+++ b/libjava/classpath/javax/swing/text/html/parser/Element.java
@@ -225,7 +225,7 @@ public final class Element
/**
* Get all attributes of this document as an attribute list.
- * @return
+ * @return The attribute list.
*/
public AttributeList getAttributes()
{
diff --git a/libjava/classpath/javax/swing/text/html/parser/Parser.java b/libjava/classpath/javax/swing/text/html/parser/Parser.java
index 5867107cd45..7ff6853da82 100644
--- a/libjava/classpath/javax/swing/text/html/parser/Parser.java
+++ b/libjava/classpath/javax/swing/text/html/parser/Parser.java
@@ -327,7 +327,7 @@ public class Parser
* Handle the tag with no content, like &lt;br&gt;. The method is
* called for the elements that, in accordance with the current DTD,
* has an empty content.
- * @param The tag being handled.
+ * @param tag The tag being handled.
* @throws javax.swing.text.ChangedCharSetException
*/
protected void handleEmptyTag(TagElement tag)
@@ -339,7 +339,7 @@ public class Parser
* The method is called when the HTML closing tag ((like &lt;/table&gt;)
* is found or if the parser concludes that the one should be present
* in the current position.
- * @param The tag being handled
+ * @param tag The tag being handled
*/
protected void handleEndTag(TagElement tag)
{
@@ -354,7 +354,7 @@ public class Parser
* The method is called when the HTML opening tag ((like &lt;table&gt;)
* is found or if the parser concludes that the one should be present
* in the current position.
- * @param The tag being handled
+ * @param tag The tag being handled
*/
protected void handleStartTag(TagElement tag)
{
@@ -383,7 +383,7 @@ public class Parser
* both title starting and closing tags are already behind.
* The passed argument contains the concatenation of all
* title text sections.
- * @param The title text.
+ * @param title The title text.
*/
protected void handleTitle(char[] title)
{
@@ -402,7 +402,7 @@ public class Parser
/**
* Constructs the tag from the given element.
- * @param the tag base {@link javax.swing.text.html.parser.Element}
+ * @param element the tag base {@link javax.swing.text.html.parser.Element}
* @param isSupposed true if the tag is not actually present in the
* html input, but the parser supposes that it should to occur in
* the current location.
@@ -427,7 +427,7 @@ public class Parser
* is found or if the parser concludes that the one should be present
* in the current position. The method is called immediately before
* calling the handleStartTag.
- * @param The tag
+ * @param tag The tag
*/
protected void startTag(TagElement tag)
throws ChangedCharSetException
diff --git a/libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java b/libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java
index 4b54e8a486c..e5d2db4df7c 100644
--- a/libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java
+++ b/libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java
@@ -143,7 +143,7 @@ public class ParserDelegator
* Parses the HTML document, calling methods of the provided
* callback. This method must be multithread - safe.
* @param reader The reader to read the HTML document from
- * @param callback The callback that is notifyed about the presence
+ * @param a_callback The callback that is notifyed about the presence
* of HTML elements in the document.
* @param ignoreCharSet If thrue, any charset changes during parsing
* are ignored.
@@ -191,7 +191,7 @@ public class ParserDelegator
* all subsequent calls to the parse(...) . If you need to specify
* your DTD locally, simply {@link javax.swing.text.html.parser.Parser}
* instead.
- * @param dtd The DTD that will be used to parse documents by this class.
+ * @param a_dtd The DTD that will be used to parse documents by this class.
* @param name The name of this DTD.
* @return No standard is specified on which instance of DTD must be
* returned by this method, and it is recommended to leave the returned
OpenPOWER on IntegriCloud