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.java912
-rw-r--r--libjava/classpath/javax/swing/text/AttributeSet.java72
-rw-r--r--libjava/classpath/javax/swing/text/BadLocationException.java65
-rw-r--r--libjava/classpath/javax/swing/text/Caret.java81
-rw-r--r--libjava/classpath/javax/swing/text/ChangedCharSetException.java100
-rw-r--r--libjava/classpath/javax/swing/text/ComponentView.java103
-rw-r--r--libjava/classpath/javax/swing/text/DateFormatter.java85
-rw-r--r--libjava/classpath/javax/swing/text/DefaultCaret.java315
-rw-r--r--libjava/classpath/javax/swing/text/DefaultEditorKit.java418
-rw-r--r--libjava/classpath/javax/swing/text/DefaultFormatter.java429
-rw-r--r--libjava/classpath/javax/swing/text/DefaultHighlighter.java257
-rw-r--r--libjava/classpath/javax/swing/text/DefaultStyledDocument.java202
-rw-r--r--libjava/classpath/javax/swing/text/Document.java221
-rw-r--r--libjava/classpath/javax/swing/text/DocumentFilter.java83
-rw-r--r--libjava/classpath/javax/swing/text/EditorKit.java96
-rw-r--r--libjava/classpath/javax/swing/text/Element.java54
-rw-r--r--libjava/classpath/javax/swing/text/FieldView.java176
-rw-r--r--libjava/classpath/javax/swing/text/GapContent.java356
-rw-r--r--libjava/classpath/javax/swing/text/Highlighter.java79
-rw-r--r--libjava/classpath/javax/swing/text/InternationalFormatter.java354
-rw-r--r--libjava/classpath/javax/swing/text/JTextComponent.java1674
-rw-r--r--libjava/classpath/javax/swing/text/Keymap.java60
-rw-r--r--libjava/classpath/javax/swing/text/LayeredHighlighter.java57
-rw-r--r--libjava/classpath/javax/swing/text/MutableAttributeSet.java85
-rw-r--r--libjava/classpath/javax/swing/text/NavigationFilter.java71
-rw-r--r--libjava/classpath/javax/swing/text/PasswordView.java170
-rw-r--r--libjava/classpath/javax/swing/text/PlainDocument.java166
-rw-r--r--libjava/classpath/javax/swing/text/PlainView.java241
-rw-r--r--libjava/classpath/javax/swing/text/Position.java62
-rw-r--r--libjava/classpath/javax/swing/text/Segment.java176
-rw-r--r--libjava/classpath/javax/swing/text/SimpleAttributeSet.java193
-rw-r--r--libjava/classpath/javax/swing/text/StringContent.java307
-rw-r--r--libjava/classpath/javax/swing/text/Style.java64
-rw-r--r--libjava/classpath/javax/swing/text/StyleConstants.java443
-rw-r--r--libjava/classpath/javax/swing/text/StyleContext.java730
-rw-r--r--libjava/classpath/javax/swing/text/StyledDocument.java145
-rw-r--r--libjava/classpath/javax/swing/text/StyledEditorKit.java503
-rw-r--r--libjava/classpath/javax/swing/text/TabExpander.java43
-rw-r--r--libjava/classpath/javax/swing/text/TabSet.java102
-rw-r--r--libjava/classpath/javax/swing/text/TabStop.java133
-rw-r--r--libjava/classpath/javax/swing/text/TabableView.java44
-rw-r--r--libjava/classpath/javax/swing/text/TextAction.java111
-rw-r--r--libjava/classpath/javax/swing/text/Utilities.java198
-rw-r--r--libjava/classpath/javax/swing/text/View.java463
-rw-r--r--libjava/classpath/javax/swing/text/ViewFactory.java50
-rw-r--r--libjava/classpath/javax/swing/text/html/HTML.java1309
-rw-r--r--libjava/classpath/javax/swing/text/html/HTMLDocument.java53
-rw-r--r--libjava/classpath/javax/swing/text/html/HTMLEditorKit.java249
-rw-r--r--libjava/classpath/javax/swing/text/html/HTMLFrameHyperlinkEvent.java132
-rw-r--r--libjava/classpath/javax/swing/text/html/package.html50
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/AttributeList.java294
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/ContentModel.java218
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/DTD.java607
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/DTDConstants.java290
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/DocumentParser.java261
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/Element.java317
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/Entity.java185
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/Parser.java436
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java210
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/TagElement.java142
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/package.html50
-rw-r--r--libjava/classpath/javax/swing/text/package.html46
-rw-r--r--libjava/classpath/javax/swing/text/rtf/ControlWordToken.java86
-rw-r--r--libjava/classpath/javax/swing/text/rtf/RTFEditorKit.java114
-rw-r--r--libjava/classpath/javax/swing/text/rtf/RTFParseException.java65
-rw-r--r--libjava/classpath/javax/swing/text/rtf/RTFParser.java195
-rw-r--r--libjava/classpath/javax/swing/text/rtf/RTFScanner.java268
-rw-r--r--libjava/classpath/javax/swing/text/rtf/TextToken.java65
-rw-r--r--libjava/classpath/javax/swing/text/rtf/Token.java91
69 files changed, 16482 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/text/AbstractDocument.java b/libjava/classpath/javax/swing/text/AbstractDocument.java
new file mode 100644
index 00000000000..c3a3d70ae37
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/AbstractDocument.java
@@ -0,0 +1,912 @@
+/* AbstractDocument.java --
+ Copyright (C) 2002, 2004, 2005 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.io.PrintStream;
+import java.io.Serializable;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.EventListenerList;
+import javax.swing.event.UndoableEditEvent;
+import javax.swing.event.UndoableEditListener;
+import javax.swing.tree.TreeNode;
+import javax.swing.undo.AbstractUndoableEdit;
+import javax.swing.undo.CompoundEdit;
+import javax.swing.undo.UndoableEdit;
+
+public abstract class AbstractDocument
+ implements Document, Serializable
+{
+ private static final long serialVersionUID = -116069779446114664L;
+
+ protected static final String BAD_LOCATION = "document location failure";
+
+ public static final String BidiElementName = "bidi level";
+ public static final String ContentElementName = "content";
+ public static final String ParagraphElementName = "paragraph";
+ public static final String SectionElementName = "section";
+ public static final String ElementNameAttribute = "$ename";
+
+ Content content;
+ AttributeContext context;
+ DocumentFilter documentFilter;
+
+ /** The documents properties. */
+ Dictionary properties;
+
+ protected EventListenerList listenerList = new EventListenerList();
+
+ protected AbstractDocument(Content doc)
+ {
+ this(doc, StyleContext.getDefaultStyleContext());
+ }
+
+ protected AbstractDocument(Content doc, AttributeContext ctx)
+ {
+ content = doc;
+ context = ctx;
+ }
+
+ // These still need to be implemented by a derived class:
+ public abstract Element getParagraphElement(int pos);
+
+ public abstract Element getDefaultRootElement();
+
+ protected Element createBranchElement(Element parent,
+ AttributeSet attributes)
+ {
+ return new BranchElement(parent, attributes);
+ }
+
+ protected Element createLeafElement(Element parent, AttributeSet attributes,
+ int start, int end)
+ {
+ return new LeafElement(parent, attributes, start, end);
+ }
+
+ 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;
+ }
+ };
+ }
+
+ protected void fireChangedUpdate(DocumentEvent event)
+ {
+ DocumentListener[] listeners = getDocumentListeners();
+
+ for (int index = 0; index < listeners.length; ++index)
+ listeners[index].changedUpdate(event);
+ }
+
+ protected void fireInsertUpdate(DocumentEvent event)
+ {
+ DocumentListener[] listeners = getDocumentListeners();
+
+ for (int index = 0; index < listeners.length; ++index)
+ listeners[index].insertUpdate(event);
+ }
+
+ protected void fireRemoveUpdate(DocumentEvent event)
+ {
+ DocumentListener[] listeners = getDocumentListeners();
+
+ for (int index = 0; index < listeners.length; ++index)
+ listeners[index].removeUpdate(event);
+ }
+
+ protected void fireUndoableEditUpdate(UndoableEditEvent event)
+ {
+ UndoableEditListener[] listeners = getUndoableEditListeners();
+
+ for (int index = 0; index < listeners.length; ++index)
+ listeners[index].undoableEditHappened(event);
+ }
+
+ public int getAsynchronousLoadPriority()
+ {
+ return 0;
+ }
+
+ protected AttributeContext getAttributeContext()
+ {
+ return context;
+ }
+
+ public Element getBidiRootElement()
+ {
+ return null;
+ }
+
+ protected Content getContent()
+ {
+ return content;
+ }
+
+ protected Thread getCurrentWriter()
+ {
+ return null;
+ }
+
+ public Dictionary getDocumentProperties()
+ {
+ // FIXME: make me thread-safe
+ if (properties == null)
+ properties = new Hashtable();
+
+ return properties;
+ }
+
+ public Position getEndPosition()
+ {
+ return new Position()
+ {
+ public int getOffset()
+ {
+ return getLength();
+ }
+ };
+ }
+
+ public int getLength()
+ {
+ return content.length() - 1;
+ }
+
+ public EventListener[] getListeners(Class listenerType)
+ {
+ return listenerList.getListeners(listenerType);
+ }
+
+ public Object getProperty(Object key)
+ {
+ // FIXME: make me thread-safe
+ Object value = null;
+ if (properties != null)
+ value = properties.get(key);
+
+ return value;
+ }
+
+ public Element[] getRootElements()
+ {
+ Element[] elements = new Element[1];
+ elements[0] = getDefaultRootElement();
+ return elements;
+ }
+
+ public Position getStartPosition()
+ {
+ return new Position()
+ {
+ public int getOffset()
+ {
+ return 0;
+ }
+ };
+ }
+
+ public String getText(int offset, int length) throws BadLocationException
+ {
+ return content.getString(offset, length);
+ }
+
+ public void getText(int offset, int length, Segment segment)
+ throws BadLocationException
+ {
+ content.getChars(offset, length, segment);
+ }
+
+ public void insertString(int offset, String text, AttributeSet attributes)
+ throws BadLocationException
+ {
+ // Just return when no text to insert was given.
+ if (text == null || text.length() == 0)
+ return;
+
+ DefaultDocumentEvent event =
+ new DefaultDocumentEvent(offset, text.length(),
+ DocumentEvent.EventType.INSERT);
+ content.insertString(offset, text);
+ insertUpdate(event, attributes);
+ fireInsertUpdate(event);
+ }
+
+ protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr)
+ {
+ }
+
+ protected void postRemoveUpdate(DefaultDocumentEvent chng)
+ {
+ }
+
+ public void putProperty(Object key, Object value)
+ {
+ // FIXME: make me thread-safe
+ if (properties == null)
+ properties = new Hashtable();
+
+ properties.put(key, value);
+ }
+
+ public void readLock()
+ {
+ }
+
+ public void readUnlock()
+ {
+ }
+
+ public void remove(int offset, int length) throws BadLocationException
+ {
+ DefaultDocumentEvent event =
+ new DefaultDocumentEvent(offset, length,
+ DocumentEvent.EventType.REMOVE);
+ removeUpdate(event);
+ content.remove(offset, length);
+ postRemoveUpdate(event);
+ fireRemoveUpdate(event);
+ }
+
+ /**
+ * Replaces some text in the document.
+ *
+ * @since 1.4
+ */
+ public void replace(int offset, int length, String text,
+ AttributeSet attributes)
+ throws BadLocationException
+ {
+ remove(offset, length);
+ insertString(offset, text, attributes);
+ }
+
+ /**
+ * Adds a <code>DocumentListener</code> object to this document.
+ *
+ * @param listener the listener to add
+ */
+ public void addDocumentListener(DocumentListener listener)
+ {
+ listenerList.add(DocumentListener.class, listener);
+ }
+
+ /**
+ * Removes a <code>DocumentListener</code> object from this document.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeDocumentListener(DocumentListener listener)
+ {
+ listenerList.remove(DocumentListener.class, listener);
+ }
+
+ /**
+ * Returns add added <code>DocumentListener</code> objects.
+ *
+ * @return an array of listeners
+ */
+ public DocumentListener[] getDocumentListeners()
+ {
+ return (DocumentListener[]) getListeners(DocumentListener.class);
+ }
+
+ /**
+ * Adds a <code>UndoableEditListener</code> object to this document.
+ *
+ * @param listener the listener to add
+ */
+ public void addUndoableEditListener(UndoableEditListener listener)
+ {
+ listenerList.add(UndoableEditListener.class, listener);
+ }
+
+ /**
+ * Removes a <code>UndoableEditListener</code> object from this document.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeUndoableEditListener(UndoableEditListener listener)
+ {
+ listenerList.remove(UndoableEditListener.class, listener);
+ }
+
+ /**
+ * Returns add added <code>UndoableEditListener</code> objects.
+ *
+ * @return an array of listeners
+ */
+ public UndoableEditListener[] getUndoableEditListeners()
+ {
+ return (UndoableEditListener[]) getListeners(UndoableEditListener.class);
+ }
+
+ protected void removeUpdate(DefaultDocumentEvent chng)
+ {
+ }
+
+ public void render(Runnable r)
+ {
+ }
+
+ public void setAsynchronousLoadPriority(int p)
+ {
+ }
+
+ public void setDocumentProperties(Dictionary x)
+ {
+ // FIXME: make me thread-safe
+ properties = x;
+ }
+
+ protected void writeLock()
+ {
+ }
+
+ protected void writeUnlock()
+ {
+ }
+
+ /**
+ * @since 1.4
+ */
+ public DocumentFilter getDocumentFilter()
+ {
+ return documentFilter;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public void setDocumentFilter(DocumentFilter filter)
+ {
+ this.documentFilter = filter;
+ }
+
+ public void dump(PrintStream out)
+ {
+ ((AbstractElement) getDefaultRootElement()).dump(out, 0);
+ }
+
+ public interface AttributeContext
+ {
+ AttributeSet addAttribute(AttributeSet old, Object name, Object value);
+
+ AttributeSet addAttributes(AttributeSet old, AttributeSet attributes);
+
+ AttributeSet getEmptySet();
+
+ void reclaim(AttributeSet attributes);
+
+ AttributeSet removeAttribute(AttributeSet old, Object name);
+
+ AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes);
+
+ AttributeSet removeAttributes(AttributeSet old, Enumeration names);
+ }
+
+ public interface Content
+ {
+ Position createPosition(int offset) throws BadLocationException;
+
+ int length();
+
+ UndoableEdit insertString(int where, String str)
+ throws BadLocationException;
+
+ UndoableEdit remove(int where, int nitems) throws BadLocationException;
+
+ String getString(int where, int len) throws BadLocationException;
+
+ void getChars(int where, int len, Segment txt) throws BadLocationException;
+ }
+
+ public abstract class AbstractElement
+ implements Element, MutableAttributeSet, TreeNode, Serializable
+ {
+ private static final long serialVersionUID = 1265312733007397733L;
+ int count;
+ int offset;
+
+ AttributeSet attributes;
+
+ Element element_parent;
+
+ TreeNode tree_parent;
+ Vector tree_children;
+
+ public AbstractElement(Element p, AttributeSet s)
+ {
+ element_parent = p;
+ attributes = s;
+ }
+
+ // TreeNode implementation
+
+ public abstract Enumeration children();
+
+ public abstract boolean getAllowsChildren();
+
+ public TreeNode getChildAt(int index)
+ {
+ return (TreeNode) tree_children.get(index);
+ }
+
+ public int getChildCount()
+ {
+ return tree_children.size();
+ }
+
+ public int getIndex(TreeNode node)
+ {
+ return tree_children.indexOf(node);
+ }
+
+ public TreeNode getParent()
+ {
+ return tree_parent;
+ }
+
+ public abstract boolean isLeaf();
+
+
+ // MutableAttributeSet support
+
+ public void addAttribute(Object name, Object value)
+ {
+ attributes = getAttributeContext().addAttribute(attributes, name, value);
+ }
+
+ public void addAttributes(AttributeSet attrs)
+ {
+ attributes = getAttributeContext().addAttributes(attributes, attrs);
+ }
+
+ public void removeAttribute(Object name)
+ {
+ attributes = getAttributeContext().removeAttribute(attributes, name);
+ }
+
+ public void removeAttributes(AttributeSet attrs)
+ {
+ attributes = getAttributeContext().removeAttributes(attributes, attrs);
+ }
+
+ public void removeAttributes(Enumeration names)
+ {
+ attributes = getAttributeContext().removeAttributes(attributes, names);
+ }
+
+ public void setResolveParent(AttributeSet parent)
+ {
+ attributes = getAttributeContext().addAttribute(attributes, ResolveAttribute, parent);
+ }
+
+
+ // AttributeSet interface support
+
+ public boolean containsAttribute(Object name, Object value)
+ {
+ return attributes.containsAttribute(name, value);
+ }
+
+ public boolean containsAttributes(AttributeSet attrs)
+ {
+ return attributes.containsAttributes(attrs);
+ }
+
+ public AttributeSet copyAttributes()
+ {
+ return attributes.copyAttributes();
+ }
+
+ public Object getAttribute(Object key)
+ {
+ return attributes.getAttribute(key);
+ }
+
+ public int getAttributeCount()
+ {
+ return attributes.getAttributeCount();
+ }
+
+ public Enumeration getAttributeNames()
+ {
+ return attributes.getAttributeNames();
+ }
+
+ public AttributeSet getResolveParent()
+ {
+ return attributes.getResolveParent();
+ }
+
+ public boolean isDefined(Object attrName)
+ {
+ return attributes.isDefined(attrName);
+ }
+
+ public boolean isEqual(AttributeSet attrs)
+ {
+ return attributes.isEqual(attrs);
+ }
+
+ // Element interface support
+
+ public AttributeSet getAttributes()
+ {
+ return attributes;
+ }
+
+ public Document getDocument()
+ {
+ return AbstractDocument.this;
+ }
+
+ public abstract Element getElement(int index);
+
+ public String getName()
+ {
+ return (String) getAttribute(NameAttribute);
+ }
+
+ public Element getParentElement()
+ {
+ return element_parent;
+ }
+
+ public abstract int getEndOffset();
+
+ public abstract int getElementCount();
+
+ public abstract int getElementIndex(int offset);
+
+ public abstract int getStartOffset();
+
+ private void dumpElement(PrintStream stream, String indent, Element element)
+ {
+ System.out.println(indent + "<" + element.getName() +">");
+
+ if (element.isLeaf())
+ {
+ int start = element.getStartOffset();
+ int end = element.getEndOffset();
+ String text = "";
+ try
+ {
+ text = getContent().getString(start, end - start);
+ }
+ catch (BadLocationException e)
+ {
+ }
+ System.out.println(indent + " ["
+ + start + ","
+ + end + "]["
+ + text + "]");
+ }
+ else
+ {
+ for (int i = 0; i < element.getElementCount(); ++i)
+ dumpElement(stream, indent + " ", element.getElement(i));
+ }
+ }
+
+ public void dump(PrintStream stream, int indent)
+ {
+ String indentStr = "";
+ for (int i = 0; i < indent; ++i)
+ indentStr += " ";
+ dumpElement(stream, indentStr, this);
+ }
+ }
+
+ public class BranchElement extends AbstractElement
+ {
+ private static final long serialVersionUID = -8595176318868717313L;
+
+ private Element[] children = new Element[0];
+
+ public BranchElement(Element parent, AttributeSet attributes)
+ {
+ super(parent, attributes);
+ }
+
+ public Enumeration children()
+ {
+ if (children.length == 0)
+ return null;
+
+ Vector tmp = new Vector();
+
+ for (int index = 0; index < children.length; ++index)
+ tmp.add(children[index]);
+
+ return tmp.elements();
+ }
+
+ public boolean getAllowsChildren()
+ {
+ return true;
+ }
+
+ public Element getElement(int index)
+ {
+ if (index < 0 || index >= children.length)
+ return null;
+
+ return children[index];
+ }
+
+ public int getElementCount()
+ {
+ return children.length;
+ }
+
+ public int getElementIndex(int offset)
+ {
+ // 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];
+
+ if ((elem.getStartOffset() <= offset)
+ && (offset < elem.getEndOffset()))
+ return index;
+ }
+
+ return 0;
+ }
+
+ public int getEndOffset()
+ {
+ return children[children.length - 1].getEndOffset();
+ }
+
+ public String getName()
+ {
+ return ParagraphElementName;
+ }
+
+ public int getStartOffset()
+ {
+ return children[0].getStartOffset();
+ }
+
+ public boolean isLeaf()
+ {
+ return false;
+ }
+
+ public Element positionToElement(int position)
+ {
+ // 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];
+
+ if ((elem.getStartOffset() <= position)
+ && (position < elem.getEndOffset()))
+ return elem;
+ }
+
+ return null;
+ }
+
+ public void replace(int offset, int length, Element[] elements)
+ {
+ Element[] target = new Element[children.length - length
+ + elements.length];
+ System.arraycopy(children, 0, target, 0, offset);
+ System.arraycopy(elements, 0, target, offset, elements.length);
+ System.arraycopy(children, offset + length, target,
+ offset + elements.length,
+ children.length - offset - length);
+ children = target;
+ }
+
+ public String toString()
+ {
+ return ("BranchElement(" + getName() + ") "
+ + getStartOffset() + "," + getEndOffset() + "\n");
+ }
+ }
+
+ public class DefaultDocumentEvent extends CompoundEdit
+ implements DocumentEvent
+ {
+ private static final long serialVersionUID = -7406103236022413522L;
+
+ private int offset;
+ private int length;
+ private DocumentEvent.EventType type;
+
+ public DefaultDocumentEvent(int offset, int length,
+ DocumentEvent.EventType type)
+ {
+ this.offset = offset;
+ this.length = length;
+ this.type = type;
+ }
+
+ public Document getDocument()
+ {
+ return AbstractDocument.this;
+ }
+
+ public int getLength()
+ {
+ return length;
+ }
+
+ public int getOffset()
+ {
+ return offset;
+ }
+
+ public DocumentEvent.EventType getType()
+ {
+ return type;
+ }
+
+ public DocumentEvent.ElementChange getChange(Element elem)
+ {
+ return null;
+ }
+ }
+
+ public static class ElementEdit extends AbstractUndoableEdit
+ implements DocumentEvent.ElementChange
+ {
+ private static final long serialVersionUID = -1216620962142928304L;
+
+ private Element elem;
+ private int index;
+ private Element[] removed;
+ private Element[] added;
+
+ public ElementEdit(Element elem, int index,
+ Element[] removed, Element[] added)
+ {
+ this.elem = elem;
+ this.index = index;
+ this.removed = removed;
+ this.added = added;
+ }
+
+ public Element[] getChildrenAdded()
+ {
+ return added;
+ }
+
+ public Element[] getChildrenRemoved()
+ {
+ return removed;
+ }
+
+ public Element getElement()
+ {
+ return elem;
+ }
+
+ public int getIndex()
+ {
+ return index;
+ }
+ }
+
+ public class LeafElement extends AbstractElement
+ {
+ private static final long serialVersionUID = 5115368706941283802L;
+ int start;
+ int end;
+
+ public LeafElement(Element parent, AttributeSet attributes, int start,
+ int end)
+ {
+ super(parent, attributes);
+ this.start = start;
+ this.end = end;
+ }
+
+ public Enumeration children()
+ {
+ return null;
+ }
+
+ public boolean getAllowsChildren()
+ {
+ return false;
+ }
+
+ public Element getElement(int index)
+ {
+ return null;
+ }
+
+ public int getElementCount()
+ {
+ return 0;
+ }
+
+ public int getElementIndex(int offset)
+ {
+ return -1;
+ }
+
+ public int getEndOffset()
+ {
+ return end;
+ }
+
+ public String getName()
+ {
+ return ContentElementName;
+ }
+
+ public int getStartOffset()
+ {
+ return start;
+ }
+
+ public boolean isLeaf()
+ {
+ return true;
+ }
+
+ public String toString()
+ {
+ return ("LeafElement(" + getName() + ") "
+ + getStartOffset() + "," + getEndOffset() + "\n");
+ }
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/AttributeSet.java b/libjava/classpath/javax/swing/text/AttributeSet.java
new file mode 100644
index 00000000000..87e7b98af22
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/AttributeSet.java
@@ -0,0 +1,72 @@
+/* AttributeSet.java --
+ Copyright (C) 2002, 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.util.Enumeration;
+
+public interface AttributeSet
+{
+ static interface CharacterAttribute
+ {
+ }
+
+ static interface ColorAttribute
+ {
+ }
+
+ static interface FontAttribute
+ {
+ }
+
+ static interface ParagraphAttribute
+ {
+ }
+
+ Object NameAttribute = StyleConstants.NameAttribute;
+ Object ResolveAttribute = StyleConstants.ResolveAttribute;
+
+ boolean containsAttribute(Object name, Object value);
+ boolean containsAttributes(AttributeSet attributes);
+ AttributeSet copyAttributes();
+ Object getAttribute(Object key);
+ int getAttributeCount();
+ Enumeration getAttributeNames();
+ AttributeSet getResolveParent();
+ boolean isDefined(Object attrName);
+ boolean isEqual(AttributeSet attr);
+}
diff --git a/libjava/classpath/javax/swing/text/BadLocationException.java b/libjava/classpath/javax/swing/text/BadLocationException.java
new file mode 100644
index 00000000000..e1a2ebcc604
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/BadLocationException.java
@@ -0,0 +1,65 @@
+/* BadLocationException.java --
+ Copyright (C) 2002, 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;
+
+public class BadLocationException extends Exception
+{
+ private static final long serialVersionUID = -7712259886815656766L;
+
+ 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
+ */
+ public BadLocationException(String str, int offset)
+ {
+ super(str);
+ this.offset = offset;
+ }
+
+ /**
+ * Returns the offset into the document that was not legal
+ */
+ public int offsetRequested()
+ {
+ return offset;
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/Caret.java b/libjava/classpath/javax/swing/text/Caret.java
new file mode 100644
index 00000000000..46072ef19c5
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/Caret.java
@@ -0,0 +1,81 @@
+/* Caret.java --
+ Copyright (C) 2002, 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.Graphics;
+import java.awt.Point;
+
+import javax.swing.event.ChangeListener;
+
+public interface Caret
+{
+ void addChangeListener(ChangeListener l);
+
+ void deinstall(JTextComponent c);
+
+ int getBlinkRate();
+
+ int getDot();
+
+ Point getMagicCaretPosition();
+
+ int getMark();
+
+ void install(JTextComponent c);
+
+ boolean isSelectionVisible();
+
+ boolean isVisible();
+
+ void moveDot(int dot);
+
+ void paint(Graphics g);
+
+ void removeChangeListener(ChangeListener l);
+
+ void setBlinkRate(int rate);
+
+ void setDot(int dot);
+
+ void setMagicCaretPosition(Point p);
+
+ void setSelectionVisible(boolean v);
+
+ void setVisible(boolean v);
+}
diff --git a/libjava/classpath/javax/swing/text/ChangedCharSetException.java b/libjava/classpath/javax/swing/text/ChangedCharSetException.java
new file mode 100644
index 00000000000..7fba29a309f
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/ChangedCharSetException.java
@@ -0,0 +1,100 @@
+/* ChangedCharSetException.java --
+ Copyright (C) 2005 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.io.IOException;
+import java.io.Serializable;
+
+/**
+ * The exception is thrown when the document charset is changed.
+ *
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
+ */
+public class ChangedCharSetException
+ extends IOException
+ implements Serializable
+{
+ /**
+ * Use serialVersionUID for interoperability.
+ * This value corresponds the version 1.4.
+ */
+ private static final long serialVersionUID = 9119851554465432389L;
+
+ /**
+ * The char set specification.
+ */
+ private final String m_charSetSpec;
+
+ /**
+ * The char set key.
+ */
+ private final boolean m_charSetKey;
+
+ /**
+ * Constructs a new char set exception with two additional parameters,
+ * defining the circumstances under that the exception was raised.
+ */
+ public ChangedCharSetException(String charSetSpec, boolean charSetKey)
+ {
+ m_charSetSpec = charSetSpec;
+ m_charSetKey = charSetKey;
+ }
+
+ /**
+ * Get the value of the first parameter, previously passed to the
+ * constructor.
+ *
+ * @return the value of the first parameter
+ */
+ public String getCharSetSpec()
+ {
+ return m_charSetSpec;
+ }
+
+ /**
+ * Get the value of the second parameter, previously passed to the
+ * constructor.
+ *
+ * @return the value of the second parameter
+ */
+ public boolean keyEqualsCharSet()
+ {
+ return m_charSetKey;
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/ComponentView.java b/libjava/classpath/javax/swing/text/ComponentView.java
new file mode 100644
index 00000000000..744d537aec6
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/ComponentView.java
@@ -0,0 +1,103 @@
+/* ComponentView.java --
+ Copyright (C) 2002, 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.Component;
+import java.awt.Graphics;
+import java.awt.Shape;
+
+public class ComponentView extends View
+{
+ public ComponentView(Element elem)
+ {
+ super(elem);
+ }
+
+ protected Component createComponent()
+ {
+ return null;
+ }
+
+ public float getAlignment(int axis)
+ {
+ return 0;
+ }
+
+ public final Component getComponent()
+ {
+ return null;
+ }
+
+ public float getMaximumSpan(int axis)
+ {
+ return 0;
+ }
+
+ public float getMinimumSpan(int axis)
+ {
+ return 0;
+ }
+
+ public float getPreferredSpan(int axis)
+ {
+ return 0;
+ }
+
+ public Shape modelToView(int pos, Shape a, Position.Bias b)
+ throws BadLocationException
+ {
+ return null;
+ }
+
+ public void paint(Graphics g, Shape a)
+ {
+ }
+
+ public void setParent(View p)
+ {
+ }
+
+ public void setSize(float width, float height)
+ {
+ }
+
+ public int viewToModel(float x, float y, Shape a, Position.Bias[] bias)
+ {
+ return 0;
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/DateFormatter.java b/libjava/classpath/javax/swing/text/DateFormatter.java
new file mode 100644
index 00000000000..0e20b771b45
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/DateFormatter.java
@@ -0,0 +1,85 @@
+/* DateFormatter.java --
+Copyright (C) 2005 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.text.DateFormat;
+
+/**
+ * <code>DateFormatter</code> is an {@link InternationalFormatter}
+ * that implements value to string and string to value conversion via
+ * an instance of {@link DateFormat}.
+ *
+ * @author Roman Kennke (roman@kennke.org)
+ */
+public class DateFormatter extends InternationalFormatter
+{
+
+ /** The serialVersoinUID. */
+ private static final long serialVersionUID = 5423279572591848797L;
+
+ /**
+ * Creates a new instance using the default {@link DateFormat} object
+ * returned by {@link DateFormat#getDateInstance}.
+ */
+ public DateFormatter()
+ {
+ this(DateFormat.getDateInstance());
+ }
+
+ /**
+ * Creates a new instance of <code>DateFormatter</code> using the
+ * specified <code>DateFormat</code>
+ *
+ * @param format the <code>DateFormat</code> to use
+ */
+ public DateFormatter(DateFormat format)
+ {
+ super();
+ setFormat(format);
+ }
+
+ /**
+ * Sets the format that is used by this <code>DateFormatter</code>.
+ *
+ * @param format the <code>DateFormat</code> to use
+ */
+ public void setFormat(DateFormat format)
+ {
+ super.setFormat(format);
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/DefaultCaret.java b/libjava/classpath/javax/swing/text/DefaultCaret.java
new file mode 100644
index 00000000000..b57b3656384
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/DefaultCaret.java
@@ -0,0 +1,315 @@
+/* DefaultCaret.java --
+ Copyright (C) 2002, 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.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.EventListener;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+
+
+public class DefaultCaret extends Rectangle
+ implements Caret, FocusListener, MouseListener, MouseMotionListener
+{
+ private static final long serialVersionUID = 228155774675466193L;
+
+ protected ChangeEvent changeEvent = new ChangeEvent(this);
+ protected EventListenerList listenerList = new EventListenerList();
+
+ private JTextComponent textComponent;
+
+ private boolean selectionVisible = true;
+ private int blinkRate = 500;
+ private int dot = 0;
+ private int mark = 0;
+ private Point magicCaretPosition = null;
+ private boolean visible = true;
+ private Object highlightEntry;
+
+ public void mouseDragged(MouseEvent event)
+ {
+ }
+
+ public void mouseMoved(MouseEvent event)
+ {
+ }
+
+ public void mouseClicked(MouseEvent event)
+ {
+ }
+
+ public void mouseEntered(MouseEvent event)
+ {
+ }
+
+ public void mouseExited(MouseEvent event)
+ {
+ }
+
+ public void mousePressed(MouseEvent event)
+ {
+ }
+
+ public void mouseReleased(MouseEvent event)
+ {
+ }
+
+ public void focusGained(FocusEvent event)
+ {
+ }
+
+ public void focusLost(FocusEvent event)
+ {
+ }
+
+ protected void moveCaret(MouseEvent event)
+ {
+ }
+
+ protected void positionCaret(MouseEvent event)
+ {
+ }
+
+ public void deinstall(JTextComponent c)
+ {
+ textComponent.removeFocusListener(this);
+ textComponent.removeMouseListener(this);
+ textComponent.removeMouseMotionListener(this);
+ textComponent = null;
+ }
+
+ public void install(JTextComponent c)
+ {
+ textComponent = c;
+ textComponent.addFocusListener(this);
+ textComponent.addMouseListener(this);
+ textComponent.addMouseMotionListener(this);
+ repaint();
+ }
+
+ public void setMagicCaretPosition(Point p)
+ {
+ magicCaretPosition = p;
+ }
+
+ public Point getMagicCaretPosition()
+ {
+ return magicCaretPosition;
+ }
+
+ public int getMark()
+ {
+ return mark;
+ }
+
+ private void handleHighlight()
+ {
+ Highlighter highlighter = textComponent.getHighlighter();
+
+ if (highlighter == null)
+ return;
+
+ int p0 = Math.min(dot, mark);
+ int p1 = Math.max(dot, mark);
+
+ if (selectionVisible && p0 != p1)
+ {
+ try
+ {
+ if (highlightEntry == null)
+ highlightEntry = highlighter.addHighlight(p0, p1, getSelectionPainter());
+ else
+ highlighter.changeHighlight(highlightEntry, p0, p1);
+ }
+ catch (BadLocationException e)
+ {
+ // This should never happen.
+ throw new InternalError();
+ }
+ }
+ else
+ {
+ if (highlightEntry != null)
+ {
+ highlighter.removeHighlight(highlightEntry);
+ highlightEntry = null;
+ }
+ }
+ }
+
+ public void setSelectionVisible(boolean v)
+ {
+ if (selectionVisible == v)
+ return;
+
+ selectionVisible = v;
+ handleHighlight();
+ repaint();
+ }
+
+ public boolean isSelectionVisible()
+ {
+ return selectionVisible;
+ }
+
+ protected final void repaint()
+ {
+ if (textComponent != null)
+ textComponent.repaint();
+ }
+
+ public void paint(Graphics g)
+ {
+ if (textComponent == null)
+ return;
+
+ int dot = getDot();
+ Rectangle rect = null;
+
+ try
+ {
+ rect = textComponent.modelToView(dot);
+ }
+ catch (BadLocationException e)
+ {
+ // This should never happen as dot should be always valid.
+ return;
+ }
+
+ if (rect == null)
+ return;
+
+ // First we need to delete the old caret.
+ // FIXME: Implement deleting of old caret.
+
+ // Now draw the caret on the new position if visible.
+ if (visible)
+ {
+ g.setColor(textComponent.getCaretColor());
+ g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height);
+ }
+ }
+
+ public EventListener[] getListeners(Class listenerType)
+ {
+ return listenerList.getListeners(listenerType);
+ }
+
+ public void addChangeListener(ChangeListener listener)
+ {
+ listenerList.add(ChangeListener.class, listener);
+ }
+
+ public void removeChangeListener(ChangeListener listener)
+ {
+ listenerList.remove(ChangeListener.class, listener);
+ }
+
+ public ChangeListener[] getChangeListeners()
+ {
+ return (ChangeListener[]) getListeners(ChangeListener.class);
+ }
+
+ protected void fireStateChanged()
+ {
+ ChangeListener[] listeners = getChangeListeners();
+
+ for (int index = 0; index < listeners.length; ++index)
+ listeners[index].stateChanged(changeEvent);
+ }
+
+ protected final JTextComponent getComponent()
+ {
+ return textComponent;
+ }
+
+ public int getBlinkRate()
+ {
+ return blinkRate;
+ }
+
+ public void setBlinkRate(int rate)
+ {
+ blinkRate = rate;
+ }
+
+ public int getDot()
+ {
+ return dot;
+ }
+
+ public void moveDot(int dot)
+ {
+ this.dot = dot;
+ handleHighlight();
+ repaint();
+ }
+
+ public void setDot(int dot)
+ {
+ this.dot = dot;
+ this.mark = dot;
+ handleHighlight();
+ repaint();
+ }
+
+ public boolean isVisible()
+ {
+ return visible;
+ }
+
+ public void setVisible(boolean v)
+ {
+ visible = v;
+ repaint();
+ }
+
+ 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
new file mode 100644
index 00000000000..aa2fbe8509a
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/DefaultEditorKit.java
@@ -0,0 +1,418 @@
+/* DefaultEditorKit.java --
+ Copyright (C) 2002, 2004, 2005 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.Toolkit;
+import java.awt.event.ActionEvent;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+
+import javax.swing.Action;
+
+public class DefaultEditorKit extends EditorKit
+{
+ public static class BeepAction
+ extends TextAction
+ {
+ public BeepAction()
+ {
+ super(beepAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ Toolkit.getDefaultToolkit().beep();
+ }
+ }
+
+ public static class CopyAction
+ extends TextAction
+ {
+ public CopyAction()
+ {
+ super(copyAction);
+ }
+ public void actionPerformed(ActionEvent event)
+ {
+ }
+ }
+
+ public static class CutAction
+ extends TextAction
+ {
+ public CutAction()
+ {
+ super(cutAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ }
+ }
+
+ /**
+ * This action is executed as default action when a KEY_TYPED
+ * event is received and no keymap entry exists for that. The purpose
+ * of this action is to filter out a couple of characters. This includes
+ * 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.
+ */
+ public static class DefaultKeyTypedAction
+ extends TextAction
+ {
+ public DefaultKeyTypedAction()
+ {
+ super(defaultKeyTypedAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ // first we filter the following events:
+ // - control characters
+ // - key events with the ALT modifier (FIXME: filter that too!)
+ char c = event.getActionCommand().charAt(0);
+ if (Character.isISOControl(c))
+ return;
+
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ try
+ {
+ t.getDocument().insertString(t.getCaret().getDot(), event.getActionCommand(), null);
+ t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
+ t.getDocument().getEndPosition().getOffset()));
+ }
+ catch (BadLocationException be)
+ {
+ // FIXME: we're not authorized to throw this.. swallow it?
+ }
+ }
+ }
+ }
+
+ /**
+ * This action inserts a newline character into the document
+ * of the text component. This is typically triggered by hitting
+ * ENTER on the keyboard.
+ */
+ public static class InsertBreakAction
+ extends TextAction
+ {
+ public InsertBreakAction()
+ {
+ super(insertBreakAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ t.replaceSelection("\n");
+ }
+ }
+
+ public static class InsertContentAction
+ extends TextAction
+ {
+ public InsertContentAction()
+ {
+ super(insertContentAction);
+ }
+ public void actionPerformed(ActionEvent event)
+ {
+ }
+ }
+
+ public static class InsertTabAction
+ extends TextAction
+ {
+ public InsertTabAction()
+ {
+ super(insertTabAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ }
+ }
+
+ public static class PasteAction
+ extends TextAction
+ {
+ public PasteAction()
+ {
+ super(pasteAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ }
+ }
+
+ private static final long serialVersionUID = 9017245433028523428L;
+
+ public static final String backwardAction = "caret-backward";
+ public static final String beepAction = "beep";
+ public static final String beginAction = "caret-begin";
+ public static final String beginLineAction = "caret-begin-line";
+ public static final String beginParagraphAction = "caret-begin-paragraph";
+ public static final String beginWordAction = "caret-begin-word";
+ public static final String copyAction = "copy-to-clipboard";
+ public static final String cutAction = "cut-to-clipboard";
+ public static final String defaultKeyTypedAction = "default-typed";
+ public static final String deleteNextCharAction = "delete-next";
+ public static final String deletePrevCharAction = "delete-previous";
+ public static final String downAction = "caret-down";
+ public static final String endAction = "caret-end";
+ public static final String endLineAction = "caret-end-line";
+ public static final String EndOfLineStringProperty = "__EndOfLine__";
+ public static final String endParagraphAction = "caret-end-paragraph";
+ public static final String endWordAction = "caret-end-word";
+ public static final String forwardAction = "caret-forward";
+ public static final String insertBreakAction = "insert-break";
+ public static final String insertContentAction = "insert-content";
+ public static final String insertTabAction = "insert-tab";
+ public static final String nextWordAction = "caret-next-word";
+ public static final String pageDownAction = "page-down";
+ public static final String pageUpAction = "page-up";
+ public static final String pasteAction = "paste-from-clipboard";
+ public static final String previousWordAction = "caret-previous-word";
+ public static final String readOnlyAction = "set-read-only";
+ public static final String selectAllAction = "select-all";
+ public static final String selectionBackwardAction = "selection-backward";
+ public static final String selectionBeginAction = "selection-begin";
+ public static final String selectionBeginLineAction = "selection-begin-line";
+ public static final String selectionBeginParagraphAction =
+ "selection-begin-paragraph";
+ public static final String selectionBeginWordAction = "selection-begin-word";
+ public static final String selectionDownAction = "selection-down";
+ public static final String selectionEndAction = "selection-end";
+ public static final String selectionEndLineAction = "selection-end-line";
+ public static final String selectionEndParagraphAction =
+ "selection-end-paragraph";
+ public static final String selectionEndWordAction = "selection-end-word";
+ public static final String selectionForwardAction = "selection-forward";
+ public static final String selectionNextWordAction = "selection-next-word";
+ public static final String selectionPreviousWordAction =
+ "selection-previous-word";
+ public static final String selectionUpAction = "selection-up";
+ public static final String selectLineAction = "select-line";
+ public static final String selectParagraphAction = "select-paragraph";
+ public static final String selectWordAction = "select-word";
+ public static final String upAction = "caret-up";
+ public static final String writableAction = "set-writable";
+
+ public DefaultEditorKit()
+ {
+ }
+
+ private static Action[] defaultActions =
+ new Action[] {
+ new BeepAction(),
+ new CopyAction(),
+ new CutAction(),
+ new DefaultKeyTypedAction(),
+ new InsertBreakAction(),
+ new InsertContentAction(),
+ new InsertTabAction(),
+ new PasteAction(),
+ new TextAction(deleteNextCharAction)
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ try
+ {
+ int pos = t.getCaret().getDot();
+ if (pos < t.getDocument().getEndPosition().getOffset())
+ {
+ t.getDocument().remove(t.getCaret().getDot(), 1);
+ }
+ }
+ catch (BadLocationException e)
+ {
+ // FIXME: we're not authorized to throw this.. swallow it?
+ }
+ }
+ }
+ },
+ new TextAction(deletePrevCharAction)
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ try
+ {
+ int pos = t.getCaret().getDot();
+ if (pos > t.getDocument().getStartPosition().getOffset())
+ {
+ t.getDocument().remove(pos - 1, 1);
+ t.getCaret().setDot(pos - 1);
+ }
+ }
+ catch (BadLocationException e)
+ {
+ // FIXME: we're not authorized to throw this.. swallow it?
+ }
+ }
+ }
+ },
+ new TextAction(backwardAction)
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ t.getCaret().setDot(Math.max(t.getCaret().getDot() - 1,
+ t.getDocument().getStartPosition().getOffset()));
+ }
+ }
+ },
+ new TextAction(forwardAction)
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
+ t.getDocument().getEndPosition().getOffset()));
+ }
+ }
+ },
+ new TextAction(selectionBackwardAction)
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ t.getCaret().moveDot(Math.max(t.getCaret().getDot() - 1,
+ t.getDocument().getStartPosition().getOffset()));
+ }
+ }
+ },
+ new TextAction(selectionForwardAction)
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ if (t != null)
+ {
+ t.getCaret().moveDot(Math.min(t.getCaret().getDot() + 1,
+ t.getDocument().getEndPosition().getOffset()));
+ }
+ }
+ },
+ };
+
+ public Caret createCaret()
+ {
+ return new DefaultCaret();
+ }
+
+ public Document createDefaultDocument()
+ {
+ return new PlainDocument();
+ }
+
+ public Action[] getActions()
+ {
+ return defaultActions;
+ }
+
+ public String getContentType()
+ {
+ return "text/plain";
+ }
+
+ public ViewFactory getViewFactory()
+ {
+ return null;
+ }
+
+ public void read(InputStream in, Document document, int offset)
+ throws BadLocationException, IOException
+ {
+ read(new InputStreamReader(in), document, offset);
+ }
+
+ public void read(Reader in, Document document, int offset)
+ throws BadLocationException, IOException
+ {
+ BufferedReader reader = new BufferedReader(in);
+
+ String line;
+ StringBuffer content = new StringBuffer();
+
+ while ((line = reader.readLine()) != null)
+ {
+ content.append(line);
+ content.append("\n");
+ }
+
+ document.insertString(offset, content.toString(),
+ SimpleAttributeSet.EMPTY);
+ }
+
+ public void write(OutputStream out, Document document, int offset, int len)
+ throws BadLocationException, IOException
+ {
+ write(new OutputStreamWriter(out), document, offset, len);
+ }
+
+ public void write(Writer out, Document document, int offset, int len)
+ throws BadLocationException, IOException
+ {
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/DefaultFormatter.java b/libjava/classpath/javax/swing/text/DefaultFormatter.java
new file mode 100644
index 00000000000..c97d90703c7
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/DefaultFormatter.java
@@ -0,0 +1,429 @@
+/* DefaultFormatter.java --
+Copyright (C) 2005 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.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.text.ParseException;
+
+import javax.swing.JFormattedTextField;
+
+/**
+ * The <code>DefaultFormatter</code> is a concrete formatter for use in
+ * {@link JFormattedTextField}s.
+ *
+ * It can format arbitrary values by invoking
+ * their {@link Object#toString} method.
+ *
+ * In order to convert a String back to
+ * a value, the value class must provide a single argument constructor that
+ * takes a String object as argument value. If no such constructor is found,
+ * the String itself is passed back by #stringToValue.
+ *
+ * @author Roman Kennke (roman@kennke.org)
+ */
+public class DefaultFormatter
+ extends JFormattedTextField.AbstractFormatter
+ implements Cloneable, Serializable
+{
+
+ /**
+ * A {@link DocumentFilter} that intercepts modification of the
+ * JFormattedTextField's Document and commits the value depending
+ * on the value of the <code>commitsOnValidEdit</code> property.
+ *
+ */
+ // FIXME: Handle allowsInvalid and overwriteMode properties
+ private class FormatterDocumentFilter
+ extends DocumentFilter
+ {
+ /**
+ * Invoked when text is removed from a text component.
+ *
+ * @param bypass the FilterBypass to use to mutate the document
+ * @param offset the start position of the modification
+ * @param length the length of the removed text
+ *
+ * @throws BadLocationException if offset or lenght are invalid in
+ * the Document
+ */
+ public void remove(DocumentFilter.FilterBypass bypass, int offset,
+ int length)
+ throws BadLocationException
+ {
+ super.remove(bypass, offset, length);
+ checkValidInput();
+ commitIfAllowed();
+ }
+
+ /**
+ * Invoked when text is inserted into a text component.
+ *
+ * @param bypass the FilterBypass to use to mutate the document
+ * @param offset the start position of the modification
+ * @param text the inserted text
+ * @param attributes the attributes of the inserted text
+ *
+ * @throws BadLocationException if offset or lenght are invalid in
+ * the Document
+ */
+ public void insertString(DocumentFilter.FilterBypass bypass, int offset,
+ String text, AttributeSet attributes)
+ throws BadLocationException
+ {
+ if (overwriteMode == true)
+ replace(bypass, offset, text.length(), text, attributes);
+ else
+ super.insertString(bypass, offset, text, attributes);
+ checkValidInput();
+ commitIfAllowed();
+ }
+
+ /**
+ * Invoked when text is replaced in a text component.
+ *
+ * @param bypass the FilterBypass to use to mutate the document
+ * @param offset the start position of the modification
+ * @param length the length of the removed text
+ * @param text the inserted text
+ * @param attributes the attributes of the inserted text
+ *
+ * @throws BadLocationException if offset or lenght are invalid in
+ * the Document
+ */
+ public void replace(DocumentFilter.FilterBypass bypass, int offset,
+ int length, String text, AttributeSet attributes)
+ throws BadLocationException
+ {
+ super.replace(bypass, offset, length, text, attributes);
+ checkValidInput();
+ commitIfAllowed();
+ }
+
+ /**
+ * Commits the value to the JTextTextField if the property
+ * <code>commitsOnValidEdit</code> is set to <code>true</code>.
+ */
+ private void commitIfAllowed()
+ {
+ if (commitsOnValidEdit == true)
+ try
+ {
+ getFormattedTextField().commitEdit();
+ }
+ catch (ParseException ex)
+ {
+ // ignore invalid edits
+ }
+ }
+
+ /**
+ * Checks if the value in the input field is valid. If the
+ * property allowsInvalid is set to <code>false</code>, then
+ * the string in the input field is not allowed to be entered.
+ *
+ * @param doc the document of the input field
+ * @param value the current (old) value of the input field
+ */
+ private void checkValidInput()
+ {
+ JFormattedTextField ftf = getFormattedTextField();
+ try
+ {
+ Object newval = stringToValue(ftf.getText());
+ }
+ catch (ParseException ex)
+ {
+ if (!allowsInvalid)
+ {
+ // roll back the input if invalid edits are not allowed
+ try
+ {
+ ftf.setText(valueToString(ftf.getValue()));
+ }
+ catch (ParseException pe)
+ {
+ // if that happens, something serious must be wrong
+ throw new AssertionError("values must be parseable");
+ }
+ }
+ }
+ }
+ }
+
+ /** The serialVersoinUID. */
+ private static final long serialVersionUID = -7369196326612908900L;
+
+ /**
+ * Indicates if the value should be committed after every
+ * valid modification of the Document.
+ */
+ boolean commitsOnValidEdit;
+
+ /**
+ * If <code>true</code> newly inserted characters overwrite existing
+ * values, otherwise insertion is done the normal way.
+ */
+ boolean overwriteMode;
+
+ /**
+ * If <code>true</code> invalid edits are allowed for a limited
+ * time.
+ */
+ boolean allowsInvalid;
+
+ /**
+ * The class that is used for values.
+ */
+ Class valueClass;
+
+ /**
+ * Creates a new instance of <code>DefaultFormatter</code>.
+ */
+ public DefaultFormatter()
+ {
+ commitsOnValidEdit = true;
+ overwriteMode = true;
+ allowsInvalid = true;
+ valueClass = Object.class;
+ }
+
+ /**
+ * Installs the formatter on the specified {@link JFormattedTextField}.
+ *
+ * This method does the following things:
+ * <ul>
+ * <li>Display the value of #valueToString in the
+ * <code>JFormattedTextField</code></li>
+ * <li>Install the Actions from #getActions on the <code>JTextField</code>
+ * </li>
+ * <li>Install the DocumentFilter returned by #getDocumentFilter</li>
+ * <li>Install the NavigationFilter returned by #getNavigationFilter</li>
+ * </ul>
+ *
+ * This method is typically not overridden by subclasses. Instead override
+ * one of the mentioned methods in order to customize behaviour.
+ *
+ * @param ftf the {@link JFormattedTextField} in which this formatter
+ * is installed
+ */
+ public void install(JFormattedTextField ftf)
+ {
+ super.install(ftf);
+ }
+
+ /**
+ * Returns <code>true</code> if the value should be committed after
+ * each valid modification of the input field, <code>false</code> if
+ * it should never be committed by this formatter.
+ *
+ * @return the state of the <code>commitsOnValidEdit</code> property
+ *
+ * @see #setCommitsOnValidEdit
+ */
+ public boolean getCommitsOnValidEdit()
+ {
+ return commitsOnValidEdit;
+ }
+
+ /**
+ * Sets the value of the <code>commitsOnValidEdit</code> property.
+ *
+ * @param commitsOnValidEdit the new state of the
+ * <code>commitsOnValidEdit</code> property
+ *
+ * @see #getCommitsOnValidEdit
+ */
+ public void setCommitsOnValidEdit(boolean commitsOnValidEdit)
+ {
+ this.commitsOnValidEdit = commitsOnValidEdit;
+ }
+
+ /**
+ * Returns the value of the <code>overwriteMode</code> property.
+ * If that is set to <code>true</code> then newly inserted characters
+ * overwrite existing values, otherwise the characters are inserted like
+ * normal. The default is <code>true</code>.
+ *
+ * @return the value of the <code>overwriteMode</code> property
+ */
+ public boolean getOverwriteMode()
+ {
+ return overwriteMode;
+ }
+
+ /**
+ * Sets the value of the <code>overwriteMode</code> property.
+ *
+ * If that is set to <code>true</code> then newly inserted characters
+ * overwrite existing values, otherwise the characters are inserted like
+ * normal. The default is <code>true</code>.
+ *
+ * @param overwriteMode the new value for the <code>overwriteMode</code>
+ * property
+ */
+ public void setOverwriteMode(boolean overwriteMode)
+ {
+ this.overwriteMode = overwriteMode;
+ }
+
+ /**
+ * Returns whether or not invalid edits are allowed or not. If invalid
+ * edits are allowed, the JFormattedTextField may temporarily contain invalid
+ * characters.
+ *
+ * @return the value of the allowsInvalid property
+ */
+ public boolean getAllowsInvalid()
+ {
+ return allowsInvalid;
+ }
+
+ /**
+ * Sets the value of the <code>allowsInvalid</code> property.
+ *
+ * @param allowsInvalid the new value for the property
+ *
+ * @see #getAllowsInvalid()
+ */
+ public void setAllowsInvalid(boolean allowsInvalid)
+ {
+ this.allowsInvalid = allowsInvalid;
+ }
+
+ /**
+ * Returns the class that is used for values. When Strings are converted
+ * back to values, this class is used to create new value objects.
+ *
+ * @return the class that is used for values
+ */
+ public Class getValueClass()
+ {
+ return valueClass;
+ }
+
+ /**
+ * Sets the class that is used for values.
+ *
+ * @param valueClass the class that is used for values
+ *
+ * @see #getValueClass()
+ */
+ public void setValueClass(Class valueClass)
+ {
+ this.valueClass = valueClass;
+ }
+
+ /**
+ * Converts a String (from the JFormattedTextField input) to a value.
+ * In order to achieve this, the formatter tries to instantiate an object
+ * of the class returned by #getValueClass() using a single argument
+ * constructor that takes a String argument. If such a constructor cannot
+ * be found, the String itself is returned.
+ *
+ * @param string the string to convert
+ *
+ * @return the value for the string
+ *
+ * @throws ParseException if the string cannot be converted into
+ * a value object (e.g. invalid input)
+ */
+ public Object stringToValue(String string)
+ throws ParseException
+ {
+ Object value = string;
+ Class valueClass = getValueClass();
+ if (valueClass == null)
+ valueClass = getFormattedTextField().getValue().getClass();
+ if (valueClass != null)
+ try
+ {
+ Constructor constr = valueClass.getConstructor
+ (new Class[]{String.class});
+ value = constr.newInstance(new Object[]{ string });
+ }
+ catch (NoSuchMethodException ex)
+ {
+ // leave value as string
+ }
+ catch (Exception ex)
+ {
+ throw new ParseException(string, 0);
+ }
+ return value;
+ }
+
+ /**
+ * Converts a value object into a String. This is done by invoking the
+ * {@link Object#toString()} method on the value.
+ *
+ * @param value the value to be converted
+ *
+ * @return the string representation of the value
+ *
+ * @throws ParseException if the value cannot be converted
+ */
+ public String valueToString(Object value)
+ throws ParseException
+ {
+ return value.toString();
+ }
+
+ /**
+ * Creates and returns a clone of this DefaultFormatter.
+ *
+ * @return a clone of this object
+ *
+ * @throws CloneNotSupportedException not thrown here
+ */
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ return super.clone();
+ }
+
+ /**
+ * Returns the DocumentFilter that is used to restrict input.
+ *
+ * @return the DocumentFilter that is used to restrict input
+ */
+ protected DocumentFilter getDocumentFilter()
+ {
+ return new FormatterDocumentFilter();
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/DefaultHighlighter.java b/libjava/classpath/javax/swing/text/DefaultHighlighter.java
new file mode 100644
index 00000000000..c8d874caa51
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/DefaultHighlighter.java
@@ -0,0 +1,257 @@
+/* DefaultHighlighter.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. */
+
+
+package javax.swing.text;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.Vector;
+
+public class DefaultHighlighter extends LayeredHighlighter
+{
+ public static class DefaultHighlightPainter
+ extends LayerPainter
+ {
+ private Color color;
+
+ public DefaultHighlightPainter(Color c)
+ {
+ super();
+ color = c;
+ }
+
+ public Color getColor()
+ {
+ return color;
+ }
+
+ private void paintHighlight(Graphics g, Rectangle rect)
+ {
+ g.fillRect(rect.x, rect.y, rect.width, rect.height);
+ }
+
+ public void paint(Graphics g, int p0, int p1, Shape bounds,
+ JTextComponent c)
+ {
+ Rectangle r0 = null;
+ Rectangle r1 = null;
+ Rectangle rect = bounds.getBounds();
+
+ try
+ {
+ r0 = c.modelToView(p0);
+ r1 = c.modelToView(p1);
+ }
+ catch (BadLocationException e)
+ {
+ // This should never occur.
+ return;
+ }
+
+ if (r0 == null || r1 == null)
+ return;
+
+ if (color == null)
+ g.setColor(c.getSelectionColor());
+ else
+ g.setColor(color);
+
+ // Check if only one line to highlight.
+ if (r0.y == r1.y)
+ {
+ r0.width = r1.x - r0.x;
+ paintHighlight(g, r0);
+ return;
+ }
+
+ // First line, from p0 to end-of-line.
+ r0.width = rect.x + rect.width - r0.x;
+ paintHighlight(g, r0);
+
+ // FIXME: All the full lines in between, if any (assumes that all lines
+ // have the same height -- not a good assumption with JEditorPane/JTextPane).
+ r0.y += r0.height;
+ r0.x = rect.x;
+
+ while (r0.y < r1.y)
+ {
+ paintHighlight(g, r0);
+ r0.y += r0.height;
+ }
+
+ // Last line, from beginnin-of-line to p1.
+ paintHighlight(g, r1);
+ }
+
+ public Shape paintLayer(Graphics g, int p0, int p1, Shape bounds,
+ JTextComponent c, View view)
+ {
+ throw new InternalError();
+ }
+ }
+
+ private class HighlightEntry
+ {
+ int p0;
+ int p1;
+ Highlighter.HighlightPainter painter;
+
+ public HighlightEntry(int p0, int p1, Highlighter.HighlightPainter painter)
+ {
+ this.p0 = p0;
+ this.p1 = p1;
+ this.painter = painter;
+ }
+
+ public int getStartPosition()
+ {
+ return p0;
+ }
+
+ public int getEndPosition()
+ {
+ return p1;
+ }
+
+ public Highlighter.HighlightPainter getPainter()
+ {
+ return painter;
+ }
+ }
+
+ /**
+ * @specnote final as of 1.4
+ */
+ public static final LayeredHighlighter.LayerPainter DefaultPainter =
+ new DefaultHighlightPainter(null);
+
+ private JTextComponent textComponent;
+ private Vector highlights = new Vector();
+ private boolean drawsLayeredHighlights = true;
+
+ public DefaultHighlighter()
+ {
+ }
+
+ public boolean getDrawsLayeredHighlights()
+ {
+ return drawsLayeredHighlights;
+ }
+
+ public void setDrawsLayeredHighlights(boolean newValue)
+ {
+ drawsLayeredHighlights = newValue;
+ }
+
+ private void checkPositions(int p0, int p1)
+ throws BadLocationException
+ {
+ if (p0 < 0)
+ throw new BadLocationException("DefaultHighlighter", p0);
+
+ if (p1 < p0)
+ throw new BadLocationException("DefaultHighlighter", p1);
+ }
+
+ public void install(JTextComponent c)
+ {
+ textComponent = c;
+ removeAllHighlights();
+ }
+
+ public void deinstall(JTextComponent c)
+ {
+ textComponent = null;
+ }
+
+ public Object addHighlight(int p0, int p1, Highlighter.HighlightPainter painter)
+ throws BadLocationException
+ {
+ checkPositions(p0, p1);
+ HighlightEntry entry = new HighlightEntry(p0, p1, painter);
+ highlights.add(entry);
+ return entry;
+ }
+
+ public void removeHighlight(Object tag)
+ {
+ highlights.remove(tag);
+ }
+
+ public void removeAllHighlights()
+ {
+ highlights.clear();
+ }
+
+ public Highlighter.Highlight[] getHighlights()
+ {
+ return null;
+ }
+
+ public void changeHighlight(Object tag, int p0, int p1)
+ throws BadLocationException
+ {
+ checkPositions(p0, p1);
+ HighlightEntry entry = (HighlightEntry) tag;
+ entry.p0 = p0;
+ entry.p1 = p1;
+ }
+
+ public void paintLayeredHighlights(Graphics g, int p0, int p1,
+ Shape viewBounds, JTextComponent editor,
+ View view)
+ {
+ }
+
+ public void paint(Graphics g)
+ {
+ // Check if there are any highlights.
+ if (highlights.size() == 0)
+ return;
+
+ Shape bounds = textComponent.getBounds();
+
+ for (int index = 0; index < highlights.size(); ++index)
+ {
+ HighlightEntry entry = (HighlightEntry) highlights.get(index);
+ entry.painter.paint(g, entry.p0, entry.p1, bounds, textComponent);
+ }
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/DefaultStyledDocument.java b/libjava/classpath/javax/swing/text/DefaultStyledDocument.java
new file mode 100644
index 00000000000..6fe206a8453
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/DefaultStyledDocument.java
@@ -0,0 +1,202 @@
+/* DefaultStyledDocument.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. */
+
+
+package javax.swing.text;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.io.Serializable;
+
+/**
+ * @author Michael Koch (konqueror@gmx.de)
+ */
+public class DefaultStyledDocument extends AbstractDocument
+ implements StyledDocument
+{
+ public class ElementBuffer
+ implements Serializable
+ {
+ private Element root;
+
+ public ElementBuffer(Element root)
+ {
+ this.root = root;
+ }
+
+ public Element getRootElement()
+ {
+ return root;
+ }
+ }
+
+ public static final int BUFFER_SIZE_DEFAULT = 4096;
+
+ protected DefaultStyledDocument.ElementBuffer buffer;
+
+ public DefaultStyledDocument()
+ {
+ this(new GapContent(BUFFER_SIZE_DEFAULT), new StyleContext());
+ }
+
+ public DefaultStyledDocument(StyleContext context)
+ {
+ this(new GapContent(BUFFER_SIZE_DEFAULT), context);
+ }
+
+ public DefaultStyledDocument(AbstractDocument.Content content,
+ StyleContext context)
+ {
+ super(content, context);
+ buffer = new ElementBuffer(createDefaultRoot());
+ setLogicalStyle(0, context.getStyle(StyleContext.DEFAULT_STYLE));
+ }
+
+ public Style addStyle(String nm, Style parent)
+ {
+ StyleContext context = (StyleContext) getAttributeContext();
+ return context.addStyle(nm, parent);
+ }
+
+ protected AbstractDocument.AbstractElement createDefaultRoot()
+ {
+ Element[] tmp;
+ BranchElement section = new BranchElement(null, null);
+
+ BranchElement paragraph = new BranchElement(section, null);
+ tmp = new Element[1];
+ tmp[0] = paragraph;
+ section.replace(0, 0, tmp);
+
+ LeafElement leaf = new LeafElement(paragraph, null, 0, 1);
+ tmp = new Element[1];
+ tmp[0] = leaf;
+ paragraph.replace(0, 0, tmp);
+
+ return section;
+ }
+
+ public Element getCharacterElement(int position)
+ {
+ Element element = getDefaultRootElement();
+
+ while (! element.isLeaf())
+ {
+ int index = element.getElementIndex(position);
+ element = element.getElement(index);
+ }
+
+ return element;
+ }
+
+ public Color getBackground(AttributeSet attributes)
+ {
+ StyleContext context = (StyleContext) getAttributeContext();
+ return context.getBackground(attributes);
+ }
+
+ public Element getDefaultRootElement()
+ {
+ return buffer.getRootElement();
+ }
+
+ public Font getFont(AttributeSet attributes)
+ {
+ StyleContext context = (StyleContext) getAttributeContext();
+ return context.getFont(attributes);
+ }
+
+ public Color getForeground(AttributeSet attributes)
+ {
+ StyleContext context = (StyleContext) getAttributeContext();
+ return context.getForeground(attributes);
+ }
+
+ public Style getLogicalStyle(int position)
+ {
+ Element paragraph = getParagraphElement(position);
+ AttributeSet attributes = paragraph.getAttributes();
+ return (Style) attributes.getResolveParent();
+ }
+
+ public Element getParagraphElement(int position)
+ {
+ Element element = getCharacterElement(position);
+ return element.getParentElement();
+ }
+
+ public Style getStyle(String nm)
+ {
+ StyleContext context = (StyleContext) getAttributeContext();
+ return context.getStyle(nm);
+ }
+
+ public void removeStyle(String nm)
+ {
+ StyleContext context = (StyleContext) getAttributeContext();
+ context.removeStyle(nm);
+ }
+
+ public void setCharacterAttributes(int offset, int length,
+ AttributeSet attributes,
+ boolean replace)
+ {
+ // FIXME: Implement me.
+ throw new Error("not implemented");
+ }
+
+ public void setLogicalStyle(int position, Style style)
+ {
+ Element el = getParagraphElement(position);
+ if (el instanceof AbstractElement)
+ {
+ AbstractElement ael = (AbstractElement) el;
+ ael.setResolveParent(style);
+ }
+ else
+ throw new AssertionError("paragraph elements are expected to be"
+ + "instances of javax.swing.text.AbstractDocument.AbstractElement");
+ }
+
+ public void setParagraphAttributes(int offset, int length,
+ AttributeSet attributes,
+ boolean replace)
+ {
+ // FIXME: Implement me.
+ throw new Error("not implemented");
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/Document.java b/libjava/classpath/javax/swing/text/Document.java
new file mode 100644
index 00000000000..f23767f58ef
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/Document.java
@@ -0,0 +1,221 @@
+/* Document.java --
+ Copyright (C) 2002, 2004, 2005 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 javax.swing.event.DocumentListener;
+import javax.swing.event.UndoableEditListener;
+
+/**
+ * A Document is the model that backs up all text components in Swing.
+ * This interface supports different kinds of implementations, from
+ * simple plain text model up to complex styled HTML or RTF models.
+ */
+public interface Document
+{
+ /**
+ * The key for the property that describes the source of a document.
+ */
+ String StreamDescriptionProperty = "stream";
+
+ /**
+ * The key for the property that is the title of a document.
+ */
+ String TitleProperty = "title";
+
+ /**
+ * Adds a {@link DocumentListener} to this document.
+ *
+ * @param listener the DocumentListener to add
+ */
+ void addDocumentListener(DocumentListener listener);
+
+ /**
+ * Adds an {@link UndoableEditListener} to this document.
+ *
+ * @param listener the UndoableEditListener to add
+ */
+ void addUndoableEditListener(UndoableEditListener listener);
+
+ /**
+ * Creates a mark in the character content at the specified offset.
+ *
+ * @param offs the offset where to place the mark
+ *
+ * @return the created Position object
+ *
+ * @throws BadLocationException of the specified offset is not a valid
+ * position in the documents content
+ */
+ Position createPosition(int offs)
+ throws BadLocationException;
+
+ /**
+ * Returns the default root element. Views should be using this element
+ * unless other mechanisms for assigning views to element structure is
+ * provided.
+ *
+ * @return the default root element
+ */
+ Element getDefaultRootElement();
+
+ /**
+ * Returns the position that marks the end of the document.
+ *
+ * @return the position that marks the end of the document
+ */
+ Position getEndPosition();
+
+ /**
+ * Returns the length of the document content.
+ *
+ * @return the length of the document content
+ */
+ int getLength();
+
+ /**
+ * Returns a document property with the specified key.
+ *
+ * @param key the (non-null) key for the property to fetch
+ *
+ * @return the property for <code>key</code> or null if no such property
+ * is stored
+ */
+ Object getProperty(Object key);
+
+ /**
+ * Returns the root elements of the document content.
+ *
+ * @return the root elements of the document content
+ */
+ Element[] getRootElements();
+
+ /**
+ * Returns the position that marks the beginning of the document
+ * content.
+ *
+ * @return the start position
+ */
+ Position getStartPosition();
+
+ /**
+ * Returns the textual content starting at <code>offset</code> with
+ * a length of <code>length</code>.
+ *
+ * @param offset the beginning of the text fragment to fetch
+ * @param length the length of the text fragment to fetch
+ *
+ * @return the text fragment starting at <code>offset</code> with
+ * a length of <code>length</code>
+ *
+ * @throws BadLocationException if <code>offset</code> or <code>length</code>
+ * are no valid locations in the document content
+ */
+ String getText(int offset, int length)
+ throws BadLocationException;
+
+ /**
+ * Fetch the textual content starting at <code>offset</code> with
+ * a length of <code>length</code> and store it in <code>txt</code>.
+ *
+ * @param offset the beginning of the text fragment to fetch
+ * @param length the length of the text fragment to fetch
+ * @param txt the Segment where to store the text fragment
+ *
+ * @throws BadLocationException if <code>offset</code> or <code>length</code>
+ * are no valid locations in the document content
+ */
+ void getText(int offset, int length, Segment txt)
+ throws BadLocationException;
+
+ /**
+ * Inserts a piece of text with an AttributeSet at the specified
+ * <code>offset</code>.
+ *
+ * @param offset the location where to insert the content
+ * @param str the textual content to insert
+ * @param a the Attributes associated with the piece of text
+ *
+ * @throws BadLocationException if <code>offset</code>
+ * is not a valid location in the document content
+ */
+ void insertString(int offset, String str, AttributeSet a)
+ throws BadLocationException;
+
+ /**
+ * Sets a document property.
+ *
+ * @param key the key of the property
+ * @param value the value of the property
+ */
+ void putProperty(Object key, Object value);
+
+ /**
+ * Removes a piece of content.
+ *
+ * @param offs the location of the fragment to remove
+ * @param len the length of the fragment to remove
+ *
+ * @throws BadLocationException if <code>offs</code> or <code>len</code>
+ * are no valid locations in the document content
+ */
+ void remove(int offs, int len)
+ throws BadLocationException;
+
+ /**
+ * Removes a DocumentListener from this Document.
+ *
+ * @param listener the DocumentListener to remove
+ */
+ void removeDocumentListener(DocumentListener listener);
+
+ /**
+ * Removes an UndoableEditListener from this Document.
+ *
+ * @param listener the UndoableEditListener to remove
+ */
+ void removeUndoableEditListener(UndoableEditListener listener);
+
+ /**
+ * This allows the Document to be rendered safely. It is made sure that
+ * the Runnable can read the document without any changes while reading.
+ * The Runnable is not allowed to change the Document itself.
+ *
+ * @param r the Runnable that renders the Document
+ */
+ void render(Runnable r);
+}
diff --git a/libjava/classpath/javax/swing/text/DocumentFilter.java b/libjava/classpath/javax/swing/text/DocumentFilter.java
new file mode 100644
index 00000000000..f86f41ca6c0
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/DocumentFilter.java
@@ -0,0 +1,83 @@
+/* DocumentFilter.java --
+ Copyright (C) 2003, 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;
+
+public class DocumentFilter
+{
+ public abstract static class FilterBypass
+ {
+ public FilterBypass()
+ {
+ // Do nothing here.
+ }
+
+ public abstract Document getDocument();
+
+ public abstract void insertString(int offset, String string,
+ AttributeSet attr)
+ throws BadLocationException;
+
+ public abstract void remove(int offset, int length)
+ throws BadLocationException;
+
+ public abstract void replace(int offset, int length, String string,
+ AttributeSet attrs)
+ throws BadLocationException;
+ }
+
+ public void insertString(DocumentFilter.FilterBypass fb, int offset,
+ String string, AttributeSet attr)
+ throws BadLocationException
+ {
+ fb.insertString(offset, string, attr);
+ }
+
+ public void remove(DocumentFilter.FilterBypass fb, int offset, int length)
+ throws BadLocationException
+ {
+ fb.remove(offset, length);
+ }
+
+ public void replace(DocumentFilter.FilterBypass fb, int offset, int length,
+ String text, AttributeSet attr)
+ throws BadLocationException
+ {
+ fb.replace(offset, length, text, attr);
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/EditorKit.java b/libjava/classpath/javax/swing/text/EditorKit.java
new file mode 100644
index 00000000000..bd51a866f68
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/EditorKit.java
@@ -0,0 +1,96 @@
+/* EditorKit.java --
+ Copyright (C) 2002, 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.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Serializable;
+import java.io.Writer;
+
+import javax.swing.Action;
+import javax.swing.JEditorPane;
+
+public abstract class EditorKit
+ implements Cloneable, Serializable
+{
+ private static final long serialVersionUID = -5044124649345887822L;
+
+ public EditorKit()
+ {
+ }
+
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Called when the kit is being removed from the JEditorPane.
+ */
+ public void deinstall(JEditorPane c)
+ {
+ }
+
+ public void install(JEditorPane c)
+ {
+ }
+
+ public abstract Caret createCaret();
+ public abstract Document createDefaultDocument();
+ public abstract Action[] getActions();
+ public abstract String getContentType();
+ public abstract ViewFactory getViewFactory();
+ public abstract void read(InputStream in, Document doc, int pos)
+ throws BadLocationException, IOException;
+ public abstract void read(Reader in, Document doc, int pos)
+ throws BadLocationException, IOException;
+ public abstract void write(OutputStream out, Document doc, int pos, int len)
+ throws BadLocationException, IOException;
+ public abstract void write(Writer out, Document doc, int pos, int len)
+ throws BadLocationException, IOException;
+}
diff --git a/libjava/classpath/javax/swing/text/Element.java b/libjava/classpath/javax/swing/text/Element.java
new file mode 100644
index 00000000000..eb53ee9d3e1
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/Element.java
@@ -0,0 +1,54 @@
+/* Element.java --
+ Copyright (C) 2002 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;
+
+
+
+public interface Element
+{
+ AttributeSet getAttributes();
+ Document getDocument();
+ Element getElement(int index);
+ int getElementCount();
+ int getElementIndex(int offset);
+ int getEndOffset();
+ String getName();
+ Element getParentElement();
+ int getStartOffset();
+ boolean isLeaf();
+ }
diff --git a/libjava/classpath/javax/swing/text/FieldView.java b/libjava/classpath/javax/swing/text/FieldView.java
new file mode 100644
index 00000000000..4d5c51cebb4
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/FieldView.java
@@ -0,0 +1,176 @@
+/* FieldView.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. */
+
+
+package javax.swing.text;
+
+import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+import javax.swing.JTextField;
+import javax.swing.event.DocumentEvent;
+
+public class FieldView extends PlainView
+{
+ public FieldView(Element elem)
+ {
+ super(elem);
+ }
+
+ protected FontMetrics getFontMetrics()
+ {
+ Component container = getContainer();
+ return container.getFontMetrics(container.getFont());
+ }
+
+ /**
+ * Vertically centers the single line of text within the
+ * bounds of the input shape. The returned Rectangle is centered
+ * vertically within <code>shape</code> and has a height of the
+ * preferred span along the Y axis. Horizontal adjustment is done according
+ * to the horizontalAligment property of the component that is rendered.
+ *
+ * @param shape the shape within which the line is beeing centered
+ */
+ protected Shape adjustAllocation(Shape shape)
+ {
+ Rectangle rectIn = shape.getBounds();
+ // vertical adjustment
+ int height = (int) getPreferredSpan(Y_AXIS);
+ int y = rectIn.y + (rectIn.height - height) / 2;
+ // horizontal adjustment
+ JTextField textField = (JTextField) getContainer();
+ int halign = textField.getHorizontalAlignment();
+ int width = (int) getPreferredSpan(X_AXIS);
+ int x;
+ ComponentOrientation orientation = textField.getComponentOrientation();
+ switch (halign)
+ {
+ case JTextField.CENTER:
+ x = rectIn.x + (rectIn.width - width) / 2;
+ break;
+ case JTextField.RIGHT:
+ x = rectIn.x + (rectIn.width - width);
+ break;
+ case JTextField.TRAILING:
+ if (orientation.isLeftToRight())
+ x = rectIn.x + (rectIn.width - width);
+ else
+ x = rectIn.x;
+ break;
+ case JTextField.LEADING:
+ if (orientation.isLeftToRight())
+ x = rectIn.x;
+ else
+ x = rectIn.x + (rectIn.width - width);
+ break;
+ case JTextField.LEFT:
+ default:
+ x = rectIn.x;
+ break;
+ }
+ return new Rectangle(x, y, width, height);
+ }
+
+ 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);
+ }
+
+ public int getResizeWeight(int axis)
+ {
+ return axis = axis == X_AXIS ? 1 : 0;
+ }
+
+ public Shape modelToView(int pos, Shape a, Position.Bias bias)
+ throws BadLocationException
+ {
+ Shape newAlloc = adjustAllocation(a);
+ return super.modelToView(pos, newAlloc, bias);
+ }
+
+ public void paint(Graphics g, Shape s)
+ {
+ Shape newAlloc = adjustAllocation(s);
+ super.paint(g, newAlloc);
+ }
+
+ public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
+ {
+ Shape newAlloc = adjustAllocation(shape);
+ super.insertUpdate(ev, newAlloc, vf);
+ }
+
+ public void removeUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
+ {
+ Shape newAlloc = adjustAllocation(shape);
+ super.removeUpdate(ev, newAlloc, vf);
+ }
+
+ public void changedUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
+ {
+ Shape newAlloc = adjustAllocation(shape);
+ super.removeUpdate(ev, newAlloc, vf);
+ }
+
+}
diff --git a/libjava/classpath/javax/swing/text/GapContent.java b/libjava/classpath/javax/swing/text/GapContent.java
new file mode 100644
index 00000000000..1bbef8f93d6
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/GapContent.java
@@ -0,0 +1,356 @@
+/* GapContent.java --
+ Copyright (C) 2002, 2004, 2005 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.io.Serializable;
+
+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.
+ *
+ * TODO: Implement UndoableEdit support stuff
+ */
+public class GapContent
+ implements AbstractDocument.Content, Serializable
+{
+ 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.
+ */
+ static final int DEFAULT_BUFSIZE = 64;
+
+ /**
+ * The text buffer.
+ */
+ char[] buffer;
+
+ /**
+ * The index of the first character of the gap.
+ */
+ int gapStart;
+
+ /**
+ * The index of the character after the last character of the gap.
+ */
+ int gapEnd;
+
+ /**
+ * Creates a new GapContent object.
+ */
+ public GapContent()
+ {
+ this(DEFAULT_BUFSIZE);
+ }
+
+ /**
+ * Creates a new GapContent object with a specified initial size.
+ *
+ * @param size the initial size of the buffer
+ */
+ public GapContent(int size)
+ {
+ buffer = (char[]) allocateArray(size);
+ gapStart = 0;
+ gapEnd = size - 1;
+ buffer[size - 1] = '\n';
+ }
+
+ /**
+ * 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)
+ {
+ return new char[size];
+ }
+
+ /**
+ * Returns the length of the allocated buffer array.
+ *
+ * @return the length of the allocated buffer array
+ */
+ protected int getArrayLength()
+ {
+ return buffer.length;
+ }
+
+ /**
+ * Returns the length of the content.
+ *
+ * @return the length of the content
+ */
+ public int length()
+ {
+ return buffer.length - (gapEnd - gapStart);
+ }
+
+ /**
+ * 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
+ */
+ public UndoableEdit insertString(int where, String str)
+ throws BadLocationException
+ {
+ // check arguments
+ int length = length();
+ int strLen = str.length();
+
+ 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);
+
+ // are we at the gap boundary?
+ if (where != gapStart)
+ shiftGap(where);
+
+ // 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
+ */
+ 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);
+ if ((where + nitems) > length)
+ throw new BadLocationException("where + nitems cannot be greater"
+ + " than the content length",
+ where + nitems);
+
+ // check if we are at the gap boundary
+ if (where != gapStart)
+ shiftGap(where);
+
+ // 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);
+ }
+
+ /**
+ * 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.
+ *
+ * @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
+ {
+ // check arguments
+ int length = length();
+ if (where >= length)
+ throw new BadLocationException("the where argument cannot be greater"
+ + " than the content length", where);
+ if ((where + len) > length)
+ throw new BadLocationException("len plus where cannot be greater"
+ + " 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;
+ }
+ 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;
+ }
+ }
+
+ /**
+ * 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
+ */
+ public Position createPosition(final int offset) throws BadLocationException
+ {
+ return new Position()
+ {
+ int off = offset;
+
+ public int getOffset()
+ {
+ return off;
+ }
+ };
+ }
+
+ /**
+ * 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.
+ *
+ * @param newSize the new size of the gap
+ */
+ protected void shiftEnd(int newSize)
+ {
+ char[] newBuf = (char[]) allocateArray(length() + newSize);
+ System.arraycopy(buffer, 0, newBuf, 0, gapStart);
+ System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize,
+ buffer.length - gapEnd);
+ gapEnd = gapStart + newSize;
+ buffer = newBuf;
+ }
+
+ /**
+ * 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);
+
+ if (newGapStart == gapStart)
+ return;
+ else if (newGapStart < gapStart)
+ {
+ System.arraycopy(buffer, newGapStart, buffer, newGapEnd,
+ gapStart - newGapStart);
+ gapStart = newGapStart;
+ gapEnd = newGapEnd;
+ }
+ else
+ {
+ System.arraycopy(buffer, gapEnd, buffer, gapStart,
+ newGapStart - gapStart);
+ gapStart = newGapStart;
+ gapEnd = newGapEnd;
+ }
+ }
+
+ /**
+ * Returns the allocated buffer array.
+ *
+ * @return the allocated buffer array
+ */
+ protected Object getArray()
+ {
+ return buffer;
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/Highlighter.java b/libjava/classpath/javax/swing/text/Highlighter.java
new file mode 100644
index 00000000000..91f3b7903d0
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/Highlighter.java
@@ -0,0 +1,79 @@
+/* Highlighter.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. */
+
+
+package javax.swing.text;
+
+import java.awt.Graphics;
+import java.awt.Shape;
+
+
+public interface Highlighter
+{
+ public interface Highlight
+ {
+ int getEndOffset();
+
+ int getStartOffset();
+
+ HighlightPainter getPainter();
+ }
+
+ public interface HighlightPainter
+ {
+ void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c);
+ }
+
+ void install(JTextComponent c);
+
+ void deinstall(JTextComponent c);
+
+ Object addHighlight(int p0, int p1, HighlightPainter p)
+ throws BadLocationException;
+
+ void removeAllHighlights();
+
+ void removeHighlight(Object tag);
+
+ void changeHighlight(Object tag, int p0, int p1)
+ throws BadLocationException;
+
+ Highlight[] getHighlights();
+
+ void paint(Graphics g);
+}
+
diff --git a/libjava/classpath/javax/swing/text/InternationalFormatter.java b/libjava/classpath/javax/swing/text/InternationalFormatter.java
new file mode 100644
index 00000000000..531a4c1aa10
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/InternationalFormatter.java
@@ -0,0 +1,354 @@
+/* InternationalFormatter.java --
+Copyright (C) 2005 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.text.AttributedCharacterIterator;
+import java.text.Format;
+import java.text.ParseException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.swing.Action;
+import javax.swing.JFormattedTextField;
+
+/**
+ * This extends {@link DefaultFormatter} so that the value to string
+ * conversion is done via a {@link Format} object. This allows
+ * various additional formats to be handled by JFormattedField.
+ *
+ * @author Roman Kennke (roman@kennke.org)
+ */
+public class InternationalFormatter
+ extends DefaultFormatter
+{
+
+ /** The serialVersoinUID. */
+ private static final long serialVersionUID = 6941977820906408656L;
+
+ /** The format that handles value to string conversion. */
+ Format format;
+
+ /** The minimal permissable value. */
+ Comparable minimum;
+
+ /** The maximal permissable value. */
+ Comparable maximum;
+
+ /**
+ * Creates a new InternationalFormatter with no Format specified.
+ */
+ public InternationalFormatter()
+ {
+ super();
+ minimum = null;
+ maximum = null;
+ format = null;
+ }
+
+ /**
+ * Creates a new InternationalFormatter that uses the specified
+ * Format object for value to string conversion.
+ *
+ * @param format the Format object to use for value to string conversion
+ */
+ public InternationalFormatter(Format format)
+ {
+ this();
+ setFormat(format);
+ }
+
+ /**
+ * Sets the Format object that is used to convert values to strings.
+ *
+ * @param format the Format to use for value to string conversion
+ *
+ * @see Format
+ */
+ public void setFormat(Format format)
+ {
+ this.format = format;
+ }
+
+ /**
+ * Returns the currently used Format object that is used to format
+ * the JFormattedField.
+ *
+ * @return the current Format
+ */
+ public Format getFormat()
+ {
+ return format;
+ }
+
+ /**
+ * Sets the minimum value that is allowed by this Formatter. The minimum
+ * value is given as an object that implements the {@link Comparable}
+ * interface.
+ *
+ * If <code>minValue</code> is null, then the Formatter has no restrictions
+ * at the lower end.
+ *
+ * If value class is not yet specified and <code>minValue</code> is not
+ * null, then <code>valueClass</code> is set to the class of the minimum
+ * value.
+ *
+ * @param minValue the minimum permissable value
+ *
+ * @see Comparable
+ */
+ public void setMinimum(Comparable minValue)
+ {
+ minimum = minValue;
+ if (valueClass == null && minValue != null)
+ valueClass = minValue.getClass();
+ }
+
+ /**
+ * Returns the minimal value that is allowed by this Formatter.
+ *
+ * A <code>null</code> value means that there is no restriction.
+ *
+ * @return the minimal value that is allowed by this Formatter or
+ * <code>null</code> if there is no restriction
+ */
+ public Comparable getMinimum()
+ {
+ return minimum;
+ }
+
+ /**
+ * Sets the maximum value that is allowed by this Formatter. The maximum
+ * value is given as an object that implements the {@link Comparable}
+ * interface.
+ *
+ * If <code>maxValue</code> is null, then the Formatter has no restrictions
+ * at the upper end.
+ *
+ * If value class is not yet specified and <code>maxValue</code> is not
+ * null, then <code>valueClass</code> is set to the class of the maximum
+ * value.
+ *
+ * @param maxValue the maximum permissable value
+ *
+ * @see Comparable
+ */
+ public void setMaximum(Comparable maxValue)
+ {
+ maximum = maxValue;
+ if (valueClass == null && maxValue != null)
+ valueClass = maxValue.getClass();
+ }
+
+ /**
+ * Returns the maximal value that is allowed by this Formatter.
+ *
+ * A <code>null</code> value means that there is no restriction.
+ *
+ * @return the maximal value that is allowed by this Formatter or
+ * <code>null</code> if there is no restriction
+ */
+ public Comparable getMaximum()
+ {
+ return maximum;
+ }
+
+ /**
+ * Installs the formatter on the specified {@link JFormattedTextField}.
+ *
+ * This method does the following things:
+ * <ul>
+ * <li>Display the value of #valueToString in the
+ * <code>JFormattedTextField</code></li>
+ * <li>Install the Actions from #getActions on the <code>JTextField</code>
+ * </li>
+ * <li>Install the DocumentFilter returned by #getDocumentFilter</li>
+ * <li>Install the NavigationFilter returned by #getNavigationFilter</li>
+ * </ul>
+ *
+ * This method is typically not overridden by subclasses. Instead override
+ * one of the mentioned methods in order to customize behaviour.
+ *
+ * @param ftf the {@link JFormattedTextField} in which this formatter
+ * is installed
+ */
+ public void install(JFormattedTextField ftf)
+ {
+ super.install(ftf);
+ }
+
+ /**
+ * Converts a value object into a String. This is done by invoking
+ * {@link Format#format} on the specified <code>Format</code> object.
+ * If no format is set, then {@link DefaultFormatter#valueToString(Object)}
+ * is called as a fallback.
+ *
+ * @param value the value to be converted
+ *
+ * @return the string representation of the value
+ *
+ * @throws ParseException if the value cannot be converted
+ */
+ public String valueToString(Object value)
+ throws ParseException
+ {
+ if (format != null)
+ return format.format(value);
+ else
+ return super.valueToString(value);
+ }
+
+ /**
+ * Converts a String (from the JFormattedTextField input) to a value.
+ * This is achieved by invoking {@link Format#parseObject(String)} on
+ * the specified <code>Format</code> object.
+ *
+ * This implementation differs slightly from {@link DefaultFormatter},
+ * it does:
+ * <ol>
+ * <li>Convert the string to an <code>Object</code> using the
+ * <code>Formatter</code>.</li>
+ * <li>If a <code>valueClass</code> has been set, this object is passed to
+ * {@link DefaultFormatter#stringToValue(String)} so that the value
+ * has the correct type. This may or may not work correctly, depending on
+ * the implementation of toString() in the value class and if the class
+ * implements a constructor that takes one String as argument.</li>
+ * <li>If no {@link ParseException} has been thrown so far, we check if the
+ * value exceeds either <code>minimum</code> or <code>maximum</code> if
+ * one of those has been specified and throw a <code>ParseException</code>
+ * if it does.</li>
+ * <li>Return the value.</li>
+ * </ol>
+ *
+ * If no format has been specified, then
+ * {@link DefaultFormatter#stringToValue(String)} is invoked as fallback.
+ *
+ * @param string the string to convert
+ *
+ * @return the value for the string
+ *
+ * @throws ParseException if the string cannot be converted into
+ * a value object (e.g. invalid input)
+ */
+ public Object stringToValue(String string)
+ throws ParseException
+ {
+ if (format != null)
+ {
+ Object o = format.parseObject(string);
+
+ // If a value class has been set, call super in order to get
+ // the class right. That is what the JDK API docs suggest, so we do
+ // it that way.
+ if (valueClass != null)
+ o = super.stringToValue(o.toString());
+
+ // Check for minimum and maximum bounds
+ if (minimum != null && minimum.compareTo(o) > 0)
+ throw new ParseException("The value may not be less than the"
+ + " specified minimum", 0);
+ if (maximum != null && minimum.compareTo(o) < 0)
+ throw new ParseException("The value may not be greater than the"
+ + " specified maximum", 0);
+ return o;
+ }
+ else
+ return super.stringToValue(string);
+ }
+
+ /**
+ * Returns the {@link Format.Field} constants that are associated with
+ * the specified position in the text.
+ *
+ * If <code>offset</code> is not a valid location in the input field,
+ * an empty array of fields is returned.
+ *
+ * @param offset the position in the text from which we want to fetch
+ * the fields constants
+ *
+ * @return the field values associated with the specified position in
+ * the text
+ */
+ public Format.Field[] getFields(int offset)
+ {
+ // TODO: don't know if this is correct
+ AttributedCharacterIterator aci = format.formatToCharacterIterator
+ (getFormattedTextField().getValue());
+ aci.setIndex(offset);
+ Map atts = aci.getAttributes();
+ Set keys = atts.keySet();
+ Format.Field[] fields = new Format.Field[keys.size()];
+ int index = 0;
+ for (Iterator i = keys.iterator(); i.hasNext(); index++)
+ fields[index] = (Format.Field) i.next();
+ return fields;
+ }
+
+ /**
+ * This creates and returns a clone of this Formatter.
+ *
+ * @return a clone of this formatter
+ *
+ * @throws CloneNotSupportedException not thrown here, since cloning is
+ * supported
+ * XXX - FIXME - Whole method disabled as workaround for gcj bug #22060.
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ // TODO: it has to be considered, if we should return a deep or shallow
+ // clone here. for now we return a shallow clone
+ Object clone = super.clone();
+ return clone;
+ }
+ */
+
+ /**
+ * Returns the Actions that are supported by this Formatter.
+ *
+ * @specnote the JDK API docs say here: <cite>If
+ * <code>getSupportsIncrement</code> returns true, this returns two
+ * Actions suitable for incrementing/decrementing the value.</cite>
+ * The questsion is, which method <code>getSupportsIncrement</code>?
+ * There is no such method in the whole API! So we just call
+ * super.getActions here.
+ */
+ public Action[] getActions()
+ {
+ return super.getActions();
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/JTextComponent.java b/libjava/classpath/javax/swing/text/JTextComponent.java
new file mode 100644
index 00000000000..f2ef4d77ffe
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/JTextComponent.java
@@ -0,0 +1,1674 @@
+/* JTextComponent.java --
+ Copyright (C) 2002, 2004, 2005 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.AWTEvent;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.InputMethodListener;
+import java.awt.event.KeyEvent;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleText;
+import javax.swing.Action;
+import javax.swing.ActionMap;
+import javax.swing.InputMap;
+import javax.swing.JComponent;
+import javax.swing.JViewport;
+import javax.swing.KeyStroke;
+import javax.swing.Scrollable;
+import javax.swing.SwingConstants;
+import javax.swing.Timer;
+import javax.swing.TransferHandler;
+import javax.swing.UIManager;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.plaf.ActionMapUIResource;
+import javax.swing.plaf.InputMapUIResource;
+import javax.swing.plaf.TextUI;
+
+public abstract class JTextComponent extends JComponent
+ implements Scrollable, Accessible
+{
+ /**
+ * AccessibleJTextComponent
+ */
+ public class AccessibleJTextComponent extends AccessibleJComponent
+ implements AccessibleText, CaretListener, DocumentListener
+ {
+ private static final long serialVersionUID = 7664188944091413696L;
+
+ /**
+ * Constructor AccessibleJTextComponent
+ * @param component TODO
+ */
+ public AccessibleJTextComponent()
+ {
+ }
+
+ /**
+ * getCaretPosition
+ * @return int
+ */
+ public int getCaretPosition()
+ {
+ return 0; // TODO
+ }
+
+ /**
+ * getSelectedText
+ * @return String
+ */
+ public String getSelectedText()
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getSelectionStart
+ * @return int
+ */
+ public int getSelectionStart()
+ {
+ return 0; // TODO
+ }
+
+ /**
+ * getSelectionEnd
+ * @return int
+ */
+ public int getSelectionEnd()
+ {
+ return 0; // TODO
+ }
+
+ /**
+ * caretUpdate
+ * @param value0 TODO
+ */
+ public void caretUpdate(CaretEvent value0)
+ {
+ // TODO
+ }
+
+ /**
+ * getAccessibleStateSet
+ * @return AccessibleStateSet
+ */
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getAccessibleRole
+ * @return AccessibleRole
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getAccessibleText
+ * @return AccessibleText
+ */
+ public AccessibleText getAccessibleText()
+ {
+ return null; // TODO
+ }
+
+ /**
+ * insertUpdate
+ * @param value0 TODO
+ */
+ public void insertUpdate(DocumentEvent value0)
+ {
+ // TODO
+ }
+
+ /**
+ * removeUpdate
+ * @param value0 TODO
+ */
+ public void removeUpdate(DocumentEvent value0)
+ {
+ // TODO
+ }
+
+ /**
+ * changedUpdate
+ * @param value0 TODO
+ */
+ public void changedUpdate(DocumentEvent value0)
+ {
+ // TODO
+ }
+
+ /**
+ * getIndexAtPoint
+ * @param value0 TODO
+ * @return int
+ */
+ public int getIndexAtPoint(Point value0)
+ {
+ return 0; // TODO
+ }
+
+ /**
+ * getRootEditorRect
+ * @return Rectangle
+ */
+ Rectangle getRootEditorRect()
+ {
+ return null;
+ }
+
+ /**
+ * getCharacterBounds
+ * @param value0 TODO
+ * @return Rectangle
+ */
+ public Rectangle getCharacterBounds(int value0)
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getCharCount
+ * @return int
+ */
+ public int getCharCount()
+ {
+ return 0; // TODO
+ }
+
+ /**
+ * getCharacterAttribute
+ * @param value0 TODO
+ * @return AttributeSet
+ */
+ public AttributeSet getCharacterAttribute(int value0)
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getAtIndex
+ * @param value0 TODO
+ * @param value1 TODO
+ * @return String
+ */
+ public String getAtIndex(int value0, int value1)
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getAfterIndex
+ * @param value0 TODO
+ * @param value1 TODO
+ * @return String
+ */
+ public String getAfterIndex(int value0, int value1)
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getBeforeIndex
+ * @param value0 TODO
+ * @param value1 TODO
+ * @return String
+ */
+ public String getBeforeIndex(int value0, int value1)
+ {
+ return null; // TODO
+ }
+ }
+
+ public static class KeyBinding
+ {
+ public KeyStroke key;
+ public String actionName;
+
+ /**
+ * Creates a new <code>KeyBinding</code> instance.
+ *
+ * @param key a <code>KeyStroke</code> value
+ * @param actionName a <code>String</code> value
+ */
+ public KeyBinding(KeyStroke key, String actionName)
+ {
+ this.key = key;
+ this.actionName = actionName;
+ }
+ }
+
+ /**
+ * The timer that lets the caret blink.
+ */
+ private class CaretBlinkTimer
+ extends Timer
+ implements ActionListener
+ {
+ /**
+ * Creates a new CaretBlinkTimer object with a default delay of 1 second.
+ */
+ public CaretBlinkTimer()
+ {
+ super(1000, null);
+ addActionListener(this);
+ }
+
+ /**
+ * Lets the caret blink.
+ */
+ public void actionPerformed(ActionEvent ev)
+ {
+ Caret c = caret;
+ if (c != null)
+ c.setVisible(!c.isVisible());
+ }
+
+ /**
+ * Updates the blink delay according to the current caret.
+ */
+ public void update()
+ {
+ stop();
+ Caret c = caret;
+ if (c != null)
+ {
+ setDelay(c.getBlinkRate());
+ if (editable)
+ start();
+ else
+ c.setVisible(false);
+ }
+ }
+ }
+
+ /**
+ * According to <a
+ * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">this
+ * report</a>, a pair of private classes wraps a {@link
+ * javax.swing.text.Keymap} in the new {@link InputMap} / {@link
+ * ActionMap} interfaces, such that old Keymap-using code can make use of
+ * the new framework.
+ *
+ * <p>A little bit of experimentation with these classes reveals the following
+ * structure:
+ *
+ * <ul>
+ *
+ * <li>KeymapWrapper extends {@link InputMap} and holds a reference to
+ * the underlying {@link Keymap}.</li>
+ *
+ * <li>KeymapWrapper maps {@link KeyStroke} objects to {@link Action}
+ * objects, by delegation to the underlying {@link Keymap}.</li>
+ *
+ * <li>KeymapActionMap extends {@link ActionMap} also holds a reference to
+ * the underlying {@link Keymap} but only appears to use it for listing
+ * its keys. </li>
+ *
+ * <li>KeymapActionMap maps all {@link Action} objects to
+ * <em>themselves</em>, whether they exist in the underlying {@link
+ * Keymap} or not, and passes other objects to the parent {@link
+ * ActionMap} for resolving.
+ *
+ * </ul>
+ */
+
+ private class KeymapWrapper extends InputMap
+ {
+ Keymap map;
+
+ public KeymapWrapper(Keymap k)
+ {
+ map = k;
+ }
+
+ public int size()
+ {
+ return map.getBoundKeyStrokes().length + super.size();
+ }
+
+ public Object get(KeyStroke ks)
+ {
+ Action mapped = null;
+ Keymap m = map;
+ while(mapped == null && m != null)
+ {
+ mapped = m.getAction(ks);
+ if (mapped == null && ks.getKeyEventType() == KeyEvent.KEY_TYPED)
+ mapped = m.getDefaultAction();
+ if (mapped == null)
+ m = m.getResolveParent();
+ }
+
+ if (mapped == null)
+ return super.get(ks);
+ else
+ return mapped;
+ }
+
+ public KeyStroke[] keys()
+ {
+ KeyStroke[] superKeys = super.keys();
+ KeyStroke[] mapKeys = map.getBoundKeyStrokes();
+ KeyStroke[] bothKeys = new KeyStroke[superKeys.length + mapKeys.length];
+ for (int i = 0; i < superKeys.length; ++i)
+ bothKeys[i] = superKeys[i];
+ for (int i = 0; i < mapKeys.length; ++i)
+ bothKeys[i + superKeys.length] = mapKeys[i];
+ return bothKeys;
+ }
+
+ public KeyStroke[] allKeys()
+ {
+ KeyStroke[] superKeys = super.allKeys();
+ KeyStroke[] mapKeys = map.getBoundKeyStrokes();
+ KeyStroke[] bothKeys = new KeyStroke[superKeys.length + mapKeys.length];
+ for (int i = 0; i < superKeys.length; ++i)
+ bothKeys[i] = superKeys[i];
+ for (int i = 0; i < mapKeys.length; ++i)
+ bothKeys[i + superKeys.length] = mapKeys[i];
+ return bothKeys;
+ }
+ }
+
+ private class KeymapActionMap extends ActionMap
+ {
+ Keymap map;
+
+ public KeymapActionMap(Keymap k)
+ {
+ map = k;
+ }
+
+ public Action get(Object cmd)
+ {
+ if (cmd instanceof Action)
+ return (Action) cmd;
+ else
+ return super.get(cmd);
+ }
+
+ public int size()
+ {
+ return map.getBoundKeyStrokes().length + super.size();
+ }
+
+ public Object[] keys()
+ {
+ Object[] superKeys = super.keys();
+ Object[] mapKeys = map.getBoundKeyStrokes();
+ Object[] bothKeys = new Object[superKeys.length + mapKeys.length];
+ for (int i = 0; i < superKeys.length; ++i)
+ bothKeys[i] = superKeys[i];
+ for (int i = 0; i < mapKeys.length; ++i)
+ bothKeys[i + superKeys.length] = mapKeys[i];
+ return bothKeys;
+ }
+
+ public Object[] allKeys()
+ {
+ Object[] superKeys = super.allKeys();
+ Object[] mapKeys = map.getBoundKeyStrokes();
+ Object[] bothKeys = new Object[superKeys.length + mapKeys.length];
+ for (int i = 0; i < superKeys.length; ++i)
+ bothKeys[i] = superKeys[i];
+ for (int i = 0; i < mapKeys.length; ++i)
+ bothKeys[i + superKeys.length] = mapKeys[i];
+ return bothKeys;
+ }
+
+ }
+
+ static class DefaultKeymap implements Keymap
+ {
+ String name;
+ Keymap parent;
+ Hashtable map;
+ Action defaultAction;
+
+ public DefaultKeymap(String name)
+ {
+ this.name = name;
+ this.map = new Hashtable();
+ }
+
+ public void addActionForKeyStroke(KeyStroke key, Action a)
+ {
+ map.put(key, a);
+ }
+
+ /**
+ * Looks up a KeyStroke either in the current map or the parent Keymap;
+ * does <em>not</em> return the default action if lookup fails.
+ *
+ * @param key The KeyStroke to look up an Action for.
+ *
+ * @return The mapping for <code>key</code>, or <code>null</code>
+ * if no mapping exists in this Keymap or any of its parents.
+ */
+ public Action getAction(KeyStroke key)
+ {
+ if (map.containsKey(key))
+ return (Action) map.get(key);
+ else if (parent != null)
+ return parent.getAction(key);
+ else
+ return null;
+ }
+
+ public Action[] getBoundActions()
+ {
+ Action [] ret = new Action[map.size()];
+ Enumeration e = map.elements();
+ int i = 0;
+ while (e.hasMoreElements())
+ {
+ ret[i++] = (Action) e.nextElement();
+ }
+ return ret;
+ }
+
+ public KeyStroke[] getBoundKeyStrokes()
+ {
+ KeyStroke [] ret = new KeyStroke[map.size()];
+ Enumeration e = map.keys();
+ int i = 0;
+ while (e.hasMoreElements())
+ {
+ ret[i++] = (KeyStroke) e.nextElement();
+ }
+ return ret;
+ }
+
+ public Action getDefaultAction()
+ {
+ return defaultAction;
+ }
+
+ public KeyStroke[] getKeyStrokesForAction(Action a)
+ {
+ int i = 0;
+ Enumeration e = map.keys();
+ while (e.hasMoreElements())
+ {
+ if (map.get(e.nextElement()).equals(a))
+ ++i;
+ }
+ KeyStroke [] ret = new KeyStroke[i];
+ i = 0;
+ e = map.keys();
+ while (e.hasMoreElements())
+ {
+ KeyStroke k = (KeyStroke) e.nextElement();
+ if (map.get(k).equals(a))
+ ret[i++] = k;
+ }
+ return ret;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public Keymap getResolveParent()
+ {
+ return parent;
+ }
+
+ public boolean isLocallyDefined(KeyStroke key)
+ {
+ return map.containsKey(key);
+ }
+
+ public void removeBindings()
+ {
+ map.clear();
+ }
+
+ public void removeKeyStrokeBinding(KeyStroke key)
+ {
+ map.remove(key);
+ }
+
+ public void setDefaultAction(Action a)
+ {
+ defaultAction = a;
+ }
+
+ public void setResolveParent(Keymap p)
+ {
+ parent = p;
+ }
+ }
+
+ class DefaultTransferHandler
+ extends TransferHandler
+ {
+ public boolean canImport(JComponent component, DataFlavor[] flavors)
+ {
+ JTextComponent textComponent = (JTextComponent) component;
+
+ if (! (textComponent.isEnabled()
+ && textComponent.isEditable()
+ && flavors != null))
+ return false;
+
+ for (int i = 0; i < flavors.length; ++i)
+ if (flavors[i].equals(DataFlavor.stringFlavor))
+ return true;
+
+ return false;
+ }
+
+ public void exportToClipboard(JComponent component, Clipboard clipboard,
+ int action)
+ {
+ JTextComponent textComponent = (JTextComponent) component;
+ int start = textComponent.getSelectionStart();
+ int end = textComponent.getSelectionEnd();
+
+ if (start == end)
+ return;
+
+ try
+ {
+ // Copy text to clipboard.
+ String data = textComponent.getDocument().getText(start, end);
+ StringSelection selection = new StringSelection(data);
+ clipboard.setContents(selection, null);
+
+ // Delete selected text on cut action.
+ if (action == MOVE)
+ doc.remove(start, end - start);
+ }
+ catch (BadLocationException e)
+ {
+ // Ignore this and do nothing.
+ }
+ }
+
+ public int getSourceActions()
+ {
+ return NONE;
+ }
+
+ public boolean importData(JComponent component, Transferable transferable)
+ {
+ DataFlavor flavor = null;
+ DataFlavor[] flavors = transferable.getTransferDataFlavors();
+
+ if (flavors == null)
+ return false;
+
+ for (int i = 0; i < flavors.length; ++i)
+ if (flavors[i].equals(DataFlavor.stringFlavor))
+ flavor = flavors[i];
+
+ if (flavor == null)
+ return false;
+
+ try
+ {
+ JTextComponent textComponent = (JTextComponent) component;
+ String data = (String) transferable.getTransferData(flavor);
+ textComponent.replaceSelection(data);
+ return true;
+ }
+ catch (IOException e)
+ {
+ // Ignored.
+ }
+ catch (UnsupportedFlavorException e)
+ {
+ // Ignored.
+ }
+
+ return false;
+ }
+ }
+
+ private static final long serialVersionUID = -8796518220218978795L;
+
+ public static final String DEFAULT_KEYMAP = "default";
+ public static final String FOCUS_ACCELERATOR_KEY = "focusAcceleratorKey";
+
+ private static DefaultTransferHandler defaultTransferHandler;
+ private static Hashtable keymaps = new Hashtable();
+ private Keymap keymap;
+ private char focusAccelerator = '\0';
+ private NavigationFilter navigationFilter;
+
+ private CaretBlinkTimer caretBlinkTimer;
+
+ /**
+ * Get a Keymap from the global keymap table, by name.
+ *
+ * @param n The name of the Keymap to look up
+ *
+ * @return A Keymap associated with the provided name, or
+ * <code>null</code> if no such Keymap exists
+ *
+ * @see #addKeymap()
+ * @see #removeKeymap()
+ * @see #keymaps
+ */
+ public static Keymap getKeymap(String n)
+ {
+ return (Keymap) keymaps.get(n);
+ }
+
+ /**
+ * Remove a Keymap from the global Keymap table, by name.
+ *
+ * @param n The name of the Keymap to remove
+ *
+ * @return The keymap removed from the global table
+ *
+ * @see #addKeymap()
+ * @see #getKeymap()
+ * @see #keymaps
+ */
+ public static Keymap removeKeymap(String n)
+ {
+ Keymap km = (Keymap) keymaps.get(n);
+ keymaps.remove(n);
+ return km;
+ }
+
+ /**
+ * Create a new Keymap with a specific name and parent, and add the new
+ * Keymap to the global keymap table. The name may be <code>null</code>,
+ * in which case the new Keymap will <em>not</em> be added to the global
+ * Keymap table. The parent may also be <code>null</code>, which is
+ * harmless.
+ *
+ * @param n The name of the new Keymap, or <code>null</code>
+ * @param parent The parent of the new Keymap, or <code>null</code>
+ *
+ * @return The newly created Keymap
+ *
+ * @see #removeKeymap()
+ * @see #getKeymap()
+ * @see #keymaps
+ */
+ public static Keymap addKeymap(String n, Keymap parent)
+ {
+ Keymap k = new DefaultKeymap(n);
+ k.setResolveParent(parent);
+ if (n != null)
+ keymaps.put(n, k);
+ return k;
+ }
+
+ /**
+ * Get the current Keymap of this component.
+ *
+ * @return The component's current Keymap
+ *
+ * @see #setKeymap()
+ * @see #keymap
+ */
+ public Keymap getKeymap()
+ {
+ return keymap;
+ }
+
+ /**
+ * Set the current Keymap of this component, installing appropriate
+ * {@link KeymapWrapper} and {@link KeymapActionMap} objects in the
+ * {@link InputMap} and {@link ActionMap} parent chains, respectively,
+ * and fire a property change event with name <code>"keymap"</code>.
+ *
+ * @see #getKeymap()
+ * @see #keymap
+ */
+ public void setKeymap(Keymap k)
+ {
+
+ // phase 1: replace the KeymapWrapper entry in the InputMap chain.
+ // the goal here is to always maintain the following ordering:
+ //
+ // [InputMap]? -> [KeymapWrapper]? -> [InputMapUIResource]*
+ //
+ // that is to say, component-specific InputMaps need to remain children
+ // of Keymaps, and Keymaps need to remain children of UI-installed
+ // InputMaps (and the order of each group needs to be preserved, of
+ // course).
+
+ KeymapWrapper kw = (k == null ? null : new KeymapWrapper(k));
+ InputMap childInputMap = getInputMap(JComponent.WHEN_FOCUSED);
+ if (childInputMap == null)
+ setInputMap(JComponent.WHEN_FOCUSED, kw);
+ else
+ {
+ while (childInputMap.getParent() != null
+ && !(childInputMap.getParent() instanceof KeymapWrapper)
+ && !(childInputMap.getParent() instanceof InputMapUIResource))
+ childInputMap = childInputMap.getParent();
+
+ // option 1: there is nobody to replace at the end of the chain
+ if (childInputMap.getParent() == null)
+ childInputMap.setParent(kw);
+
+ // option 2: there is already a KeymapWrapper in the chain which
+ // needs replacing (possibly with its own parents, possibly without)
+ else if (childInputMap.getParent() instanceof KeymapWrapper)
+ {
+ if (kw == null)
+ childInputMap.setParent(childInputMap.getParent().getParent());
+ else
+ {
+ kw.setParent(childInputMap.getParent().getParent());
+ childInputMap.setParent(kw);
+ }
+ }
+
+ // option 3: there is an InputMapUIResource in the chain, which marks
+ // the place where we need to stop and insert ourselves
+ else if (childInputMap.getParent() instanceof InputMapUIResource)
+ {
+ if (kw != null)
+ {
+ kw.setParent(childInputMap.getParent());
+ childInputMap.setParent(kw);
+ }
+ }
+ }
+
+ // phase 2: replace the KeymapActionMap entry in the ActionMap chain
+
+ KeymapActionMap kam = (k == null ? null : new KeymapActionMap(k));
+ ActionMap childActionMap = getActionMap();
+ if (childActionMap == null)
+ setActionMap(kam);
+ else
+ {
+ while (childActionMap.getParent() != null
+ && !(childActionMap.getParent() instanceof KeymapActionMap)
+ && !(childActionMap.getParent() instanceof ActionMapUIResource))
+ childActionMap = childActionMap.getParent();
+
+ // option 1: there is nobody to replace at the end of the chain
+ if (childActionMap.getParent() == null)
+ childActionMap.setParent(kam);
+
+ // option 2: there is already a KeymapActionMap in the chain which
+ // needs replacing (possibly with its own parents, possibly without)
+ else if (childActionMap.getParent() instanceof KeymapActionMap)
+ {
+ if (kam == null)
+ childActionMap.setParent(childActionMap.getParent().getParent());
+ else
+ {
+ kam.setParent(childActionMap.getParent().getParent());
+ childActionMap.setParent(kam);
+ }
+ }
+
+ // option 3: there is an ActionMapUIResource in the chain, which marks
+ // the place where we need to stop and insert ourselves
+ else if (childActionMap.getParent() instanceof ActionMapUIResource)
+ {
+ if (kam != null)
+ {
+ kam.setParent(childActionMap.getParent());
+ childActionMap.setParent(kam);
+ }
+ }
+ }
+
+ // phase 3: update the explicit keymap field
+
+ Keymap old = keymap;
+ keymap = k;
+ firePropertyChange("keymap", old, k);
+ }
+
+ /**
+ * Resolves a set of bindings against a set of actions and inserts the
+ * results into a {@link Keymap}. Specifically, for each provided binding
+ * <code>b</code>, if there exists a provided action <code>a</code> such
+ * that <code>a.getValue(Action.NAME) == b.ActionName</code> then an
+ * entry is added to the Keymap mapping <code>b</code> to
+ * <code>a</code>.
+ *
+ * @param map The Keymap to add new mappings to
+ * @param bindings The set of bindings to add to the Keymap
+ * @param actions The set of actions to resolve binding names against
+ *
+ * @see Action#NAME
+ * @see Action#getValue()
+ * @see KeyBinding#ActionName
+ */
+ public static void loadKeymap(Keymap map,
+ JTextComponent.KeyBinding[] bindings,
+ Action[] actions)
+ {
+ Hashtable acts = new Hashtable(actions.length);
+ for (int i = 0; i < actions.length; ++i)
+ acts.put(actions[i].getValue(Action.NAME), actions[i]);
+ for (int i = 0; i < bindings.length; ++i)
+ if (acts.containsKey(bindings[i].actionName))
+ map.addActionForKeyStroke(bindings[i].key, (Action) acts.get(bindings[i].actionName));
+ }
+
+ /**
+ * Returns the set of available Actions this component's associated
+ * 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
+ * against this component.
+ *
+ * @return The set of available Actions on this component's {@link EditorKit}
+ *
+ * @see TextUI#getEditorKit()
+ * @see EditorKit#getActions()
+ */
+ public Action[] getActions()
+ {
+ return getUI().getEditorKit(this).getActions();
+ }
+
+ // These are package-private to avoid an accessor method.
+ Document doc;
+ Caret caret;
+ boolean editable;
+
+ private Highlighter highlighter;
+ private Color caretColor;
+ private Color disabledTextColor;
+ private Color selectedTextColor;
+ private Color selectionColor;
+ private Insets margin;
+ private boolean dragEnabled;
+
+ /**
+ * Creates a new <code>JTextComponent</code> instance.
+ */
+ public JTextComponent()
+ {
+ Keymap defkeymap = getKeymap(DEFAULT_KEYMAP);
+ boolean creatingKeymap = false;
+ if (defkeymap == null)
+ {
+ defkeymap = addKeymap(DEFAULT_KEYMAP, null);
+ defkeymap.setDefaultAction(new DefaultEditorKit.DefaultKeyTypedAction());
+ creatingKeymap = true;
+ }
+
+ caretBlinkTimer = new CaretBlinkTimer();
+
+ setFocusable(true);
+ setEditable(true);
+ enableEvents(AWTEvent.KEY_EVENT_MASK);
+ updateUI();
+
+ // need to do this after updateUI()
+ if (creatingKeymap)
+ loadKeymap(defkeymap,
+ new KeyBinding[] {
+ new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),
+ DefaultEditorKit.backwardAction),
+ new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0),
+ DefaultEditorKit.forwardAction),
+ new KeyBinding(KeyStroke.getKeyStroke("typed \b"),
+ DefaultEditorKit.deletePrevCharAction),
+ new KeyBinding(KeyStroke.getKeyStroke("typed \u007f"),
+ DefaultEditorKit.deleteNextCharAction)
+ },
+ getActions());
+ }
+
+ public void setDocument(Document newDoc)
+ {
+ Document oldDoc = doc;
+ doc = newDoc;
+ firePropertyChange("document", oldDoc, newDoc);
+ revalidate();
+ repaint();
+ }
+
+ public Document getDocument()
+ {
+ return doc;
+ }
+
+ /**
+ * Get the <code>AccessibleContext</code> of this object.
+ *
+ * @return an <code>AccessibleContext</code> object
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ return null;
+ }
+
+ public void setMargin(Insets m)
+ {
+ margin = m;
+ }
+
+ public Insets getMargin()
+ {
+ return margin;
+ }
+
+ public void setText(String text)
+ {
+ try
+ {
+ doc.remove(0, doc.getLength());
+ doc.insertString(0, text, null);
+ }
+ catch (BadLocationException e)
+ {
+ // This can never happen.
+ }
+ }
+
+ /**
+ * Retrieves the current text in this text document.
+ *
+ * @return the text
+ *
+ * @exception NullPointerException if the underlaying document is null
+ */
+ public String getText()
+ {
+ if (doc == null)
+ return null;
+
+ try
+ {
+ return doc.getText(0, doc.getLength());
+ }
+ catch (BadLocationException e)
+ {
+ // This should never happen.
+ return "";
+ }
+ }
+
+ /**
+ * Retrieves a part of the current text in this document.
+ *
+ * @param offset the postion of the first character
+ * @param length the length of the text to retrieve
+ *
+ * @return the text
+ *
+ * @exception BadLocationException if arguments do not hold pre-conditions
+ */
+ public String getText(int offset, int length)
+ throws BadLocationException
+ {
+ return getDocument().getText(offset, length);
+ }
+
+ /**
+ * Retrieves the currently selected text in this text document.
+ *
+ * @return the selected text
+ *
+ * @exception NullPointerException if the underlaying document is null
+ */
+ public String getSelectedText()
+ {
+ try
+ {
+ return doc.getText(getSelectionStart(), getSelectionEnd());
+ }
+ catch (BadLocationException e)
+ {
+ // This should never happen.
+ return null;
+ }
+ }
+
+ /**
+ * Returns a string that specifies the name of the Look and Feel class
+ * that renders this component.
+ *
+ * @return the string "TextComponentUI"
+ */
+ public String getUIClassID()
+ {
+ return "TextComponentUI";
+ }
+
+ /**
+ * Returns a string representation of this JTextComponent.
+ */
+ protected String paramString()
+ {
+ return "JTextComponent";
+ }
+
+ /**
+ * This method returns the label's UI delegate.
+ *
+ * @return The label's UI delegate.
+ */
+ public TextUI getUI()
+ {
+ return (TextUI) ui;
+ }
+
+ /**
+ * This method sets the label's UI delegate.
+ *
+ * @param ui The label's UI delegate.
+ */
+ public void setUI(TextUI newUI)
+ {
+ super.setUI(newUI);
+ }
+
+ /**
+ * This method resets the label's UI delegate to the default UI for the
+ * current look and feel.
+ */
+ public void updateUI()
+ {
+ setUI((TextUI) UIManager.getUI(this));
+ }
+
+ public Dimension getPreferredScrollableViewportSize()
+ {
+ return getPreferredSize();
+ }
+
+ public int getScrollableUnitIncrement(Rectangle visible, int orientation,
+ int direction)
+ {
+ // We return 1/10 of the visible area as documented in Sun's API docs.
+ if (orientation == SwingConstants.HORIZONTAL)
+ return visible.width / 10;
+ else if (orientation == SwingConstants.VERTICAL)
+ return visible.height / 10;
+ else
+ throw new IllegalArgumentException("orientation must be either "
+ + "javax.swing.SwingConstants.VERTICAL "
+ + "or "
+ + "javax.swing.SwingConstants.HORIZONTAL"
+ );
+ }
+
+ public int getScrollableBlockIncrement(Rectangle visible, int orientation,
+ int direction)
+ {
+ // We return the whole visible area as documented in Sun's API docs.
+ if (orientation == SwingConstants.HORIZONTAL)
+ return visible.width;
+ else if (orientation == SwingConstants.VERTICAL)
+ return visible.height;
+ else
+ throw new IllegalArgumentException("orientation must be either "
+ + "javax.swing.SwingConstants.VERTICAL "
+ + "or "
+ + "javax.swing.SwingConstants.HORIZONTAL"
+ );
+ }
+
+ /**
+ * Checks whether this text component it editable.
+ *
+ * @return true if editable, false otherwise
+ */
+ public boolean isEditable()
+ {
+ return editable;
+ }
+
+ /**
+ * Enables/disabled this text component's editability.
+ *
+ * @param newValue true to make it editable, false otherwise.
+ */
+ public void setEditable(boolean newValue)
+ {
+ if (editable == newValue)
+ return;
+
+ if (newValue == true)
+ caretBlinkTimer.start();
+ else
+ {
+ caretBlinkTimer.stop();
+ caret.setVisible(false);
+ }
+
+ boolean oldValue = editable;
+ editable = newValue;
+ firePropertyChange("editable", oldValue, newValue);
+ }
+
+ /**
+ * The <code>Caret</code> object used in this text component.
+ *
+ * @return the caret object
+ */
+ public Caret getCaret()
+ {
+ return caret;
+ }
+
+ /**
+ * Sets a new <code>Caret</code> for this text component.
+ *
+ * @param newCaret the new <code>Caret</code> to set
+ */
+ public void setCaret(Caret newCaret)
+ {
+ if (caret != null)
+ caret.deinstall(this);
+
+ Caret oldCaret = caret;
+ caret = newCaret;
+
+ caretBlinkTimer.update();
+
+ if (caret != null)
+ caret.install(this);
+
+ firePropertyChange("caret", oldCaret, newCaret);
+ }
+
+ public Color getCaretColor()
+ {
+ return caretColor;
+ }
+
+ public void setCaretColor(Color newColor)
+ {
+ Color oldCaretColor = caretColor;
+ caretColor = newColor;
+ firePropertyChange("caretColor", oldCaretColor, newColor);
+ }
+
+ public Color getDisabledTextColor()
+ {
+ return disabledTextColor;
+ }
+
+ public void setDisabledTextColor(Color newColor)
+ {
+ Color oldColor = disabledTextColor;
+ disabledTextColor = newColor;
+ firePropertyChange("disabledTextColor", oldColor, newColor);
+ }
+
+ public Color getSelectedTextColor()
+ {
+ return selectedTextColor;
+ }
+
+ public void setSelectedTextColor(Color newColor)
+ {
+ Color oldColor = selectedTextColor;
+ selectedTextColor = newColor;
+ firePropertyChange("selectedTextColor", oldColor, newColor);
+ }
+
+ public Color getSelectionColor()
+ {
+ return selectionColor;
+ }
+
+ public void setSelectionColor(Color newColor)
+ {
+ Color oldColor = selectionColor;
+ selectionColor = newColor;
+ firePropertyChange("selectionColor", oldColor, newColor);
+ }
+
+ /**
+ * Retrisves the current caret position.
+ *
+ * @return the current position
+ */
+ public int getCaretPosition()
+ {
+ return caret.getDot();
+ }
+
+ /**
+ * Sets the caret to a new position.
+ *
+ * @param position the new position
+ */
+ public void setCaretPosition(int position)
+ {
+ if (doc == null)
+ return;
+
+ if (position < 0 || position > doc.getLength())
+ throw new IllegalArgumentException();
+
+ caret.setDot(position);
+ }
+
+ /**
+ * Moves the caret to a given position. This selects the text between
+ * the old and the new position of the caret.
+ */
+ public void moveCaretPosition(int position)
+ {
+ if (doc == null)
+ return;
+
+ if (position < 0 || position > doc.getLength())
+ throw new IllegalArgumentException();
+
+ caret.moveDot(position);
+ }
+
+ public Highlighter getHighlighter()
+ {
+ return highlighter;
+ }
+
+ public void setHighlighter(Highlighter newHighlighter)
+ {
+ if (highlighter != null)
+ highlighter.deinstall(this);
+
+ Highlighter oldHighlighter = highlighter;
+ highlighter = newHighlighter;
+
+ if (highlighter != null)
+ highlighter.install(this);
+
+ firePropertyChange("highlighter", oldHighlighter, newHighlighter);
+ }
+
+ /**
+ * Returns the start postion of the currently selected text.
+ *
+ * @return the start postion
+ */
+ public int getSelectionStart()
+ {
+ return Math.min(caret.getDot(), caret.getMark());
+ }
+
+ /**
+ * Selects the text from the given postion to the selection end position.
+ *
+ * @param end the start positon of the selected text.
+ */
+ public void setSelectionStart(int start)
+ {
+ select(start, getSelectionEnd());
+ }
+
+ /**
+ * Returns the end postion of the currently selected text.
+ *
+ * @return the end postion
+ */
+ public int getSelectionEnd()
+ {
+ return Math.max(caret.getDot(), caret.getMark());
+ }
+
+ /**
+ * Selects the text from the selection start postion to the given position.
+ *
+ * @param end the end positon of the selected text.
+ */
+ public void setSelectionEnd(int end)
+ {
+ select(getSelectionStart(), end);
+ }
+
+ /**
+ * 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
+ */
+ public void select(int start, int end)
+ {
+ int length = doc.getLength();
+
+ start = Math.max(start, 0);
+ start = Math.min(start, length);
+
+ end = Math.max(end, 0);
+ end = Math.min(end, length);
+
+ setCaretPosition(start);
+ moveCaretPosition(end);
+ }
+
+ /**
+ * Selects the whole content of the text component.
+ */
+ public void selectAll()
+ {
+ select(0, doc.getLength());
+ }
+
+ public synchronized void replaceSelection(String content)
+ {
+ int dot = caret.getDot();
+ int mark = caret.getMark();
+
+ // If content is empty delete selection.
+ if (content == null)
+ {
+ caret.setDot(dot);
+ return;
+ }
+
+ try
+ {
+ int start = getSelectionStart();
+ int end = getSelectionEnd();
+
+ // Remove selected text.
+ if (dot != mark)
+ doc.remove(start, end - start);
+
+ // Insert new text.
+ doc.insertString(start, content, null);
+
+ // Set dot to new position.
+ setCaretPosition(start + content.length());
+ }
+ catch (BadLocationException e)
+ {
+ // This should never happen.
+ }
+ }
+
+ public boolean getScrollableTracksViewportHeight()
+ {
+ if (getParent() instanceof JViewport)
+ return ((JViewport) getParent()).getHeight() > getPreferredSize().height;
+
+ return false;
+ }
+
+ public boolean getScrollableTracksViewportWidth()
+ {
+ if (getParent() instanceof JViewport)
+ return ((JViewport) getParent()).getWidth() > getPreferredSize().width;
+
+ return false;
+ }
+
+ /**
+ * Adds a <code>CaretListener</code> object to this text component.
+ *
+ * @param listener the listener to add
+ */
+ public void addCaretListener(CaretListener listener)
+ {
+ listenerList.add(CaretListener.class, listener);
+ }
+
+ /**
+ * Removed a <code>CaretListener</code> object from this text component.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeCaretListener(CaretListener listener)
+ {
+ listenerList.remove(CaretListener.class, listener);
+ }
+
+ /**
+ * Returns all added <code>CaretListener</code> objects.
+ *
+ * @return an array of listeners
+ */
+ public CaretListener[] getCaretListeners()
+ {
+ return (CaretListener[]) getListeners(CaretListener.class);
+ }
+
+ /**
+ * Notifies all registered <code>CaretListener</code> objects that the caret
+ * was updated.
+ *
+ * @param event the event to send
+ */
+ protected void fireCaretUpdate(CaretEvent event)
+ {
+ CaretListener[] listeners = getCaretListeners();
+
+ for (int index = 0; index < listeners.length; ++index)
+ listeners[index].caretUpdate(event);
+ }
+
+ /**
+ * Adds an <code>InputListener</code> object to this text component.
+ *
+ * @param listener the listener to add
+ */
+ public void addInputMethodListener(InputMethodListener listener)
+ {
+ listenerList.add(InputMethodListener.class, listener);
+ }
+
+ /**
+ * Removes an <code>InputListener</code> object from this text component.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeInputMethodListener(InputMethodListener listener)
+ {
+ listenerList.remove(InputMethodListener.class, listener);
+ }
+
+ /**
+ * Returns all added <code>InputMethodListener</code> objects.
+ *
+ * @return an array of listeners
+ */
+ public InputMethodListener[] getInputMethodListeners()
+ {
+ return (InputMethodListener[]) getListeners(InputMethodListener.class);
+ }
+
+ public Rectangle modelToView(int position) throws BadLocationException
+ {
+ return getUI().modelToView(this, position);
+ }
+
+ public boolean getDragEnabled()
+ {
+ return dragEnabled;
+ }
+
+ public void setDragEnabled(boolean enabled)
+ {
+ dragEnabled = enabled;
+ }
+
+ public int viewToModel(Point pt)
+ {
+ return getUI().viewToModel(this, pt);
+ }
+
+ public void copy()
+ {
+ doTransferAction("copy", TransferHandler.getCopyAction());
+ }
+
+ public void cut()
+ {
+ doTransferAction("cut", TransferHandler.getCutAction());
+ }
+
+ public void paste()
+ {
+ doTransferAction("paste", TransferHandler.getPasteAction());
+ }
+
+ private void doTransferAction(String name, Action action)
+ {
+ // Install default TransferHandler if none set.
+ if (getTransferHandler() == null)
+ {
+ if (defaultTransferHandler == null)
+ defaultTransferHandler = new DefaultTransferHandler();
+
+ setTransferHandler(defaultTransferHandler);
+ }
+
+ // Perform action.
+ ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
+ action.getValue(Action.NAME).toString());
+ action.actionPerformed(event);
+ }
+
+ public void setFocusAccelerator(char newKey)
+ {
+ if (focusAccelerator == newKey)
+ return;
+
+ char oldKey = focusAccelerator;
+ focusAccelerator = newKey;
+ firePropertyChange(FOCUS_ACCELERATOR_KEY, oldKey, newKey);
+ }
+
+ public char getFocusAccelerator()
+ {
+ return focusAccelerator;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public NavigationFilter getNavigationFilter()
+ {
+ return navigationFilter;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public void setNavigationFilter(NavigationFilter filter)
+ {
+ navigationFilter = filter;
+ }
+
+ /**
+ * Read and set the content this component. If not overridden, the
+ * method reads the component content as a plain text.
+ *
+ * The second parameter of this method describes the input stream. It can
+ * be String, URL, File and so on. If not null, this object is added to
+ * the properties of the associated document under the key
+ * {@link Document#StreamDescriptionProperty}.
+ *
+ * @param input an input stream to read from.
+ * @param streamDescription an object, describing the stream.
+ *
+ * @throws IOException if the reader throws it.
+ *
+ * @see getDocument()
+ * @see Document#getProperty(Object)
+ */
+ public void read(Reader input, Object streamDescription)
+ throws IOException
+ {
+ if (streamDescription != null)
+ {
+ Document d = getDocument();
+ if (d != null)
+ d.putProperty(Document.StreamDescriptionProperty, streamDescription);
+ }
+
+ StringBuffer b = new StringBuffer();
+ int c;
+
+ // Read till -1 (EOF).
+ while ((c = input.read()) >= 0)
+ b.append((char) c);
+
+ setText(b.toString());
+ }
+
+ /**
+ * Write the content of this component to the given stream. If not
+ * overridden, the method writes the component content as a plain text.
+ *
+ * @param output the writer to write into.
+ *
+ * @throws IOException if the writer throws it.
+ */
+ public void write(Writer output)
+ throws IOException
+ {
+ output.write(getText());
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/Keymap.java b/libjava/classpath/javax/swing/text/Keymap.java
new file mode 100644
index 00000000000..c3f61d88e07
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/Keymap.java
@@ -0,0 +1,60 @@
+/* Keymap.java --
+ Copyright (C) 2002, 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 javax.swing.Action;
+import javax.swing.KeyStroke;
+
+public interface Keymap
+{
+ void addActionForKeyStroke(KeyStroke key, Action a);
+ Action getAction(KeyStroke key);
+ Action[] getBoundActions();
+ KeyStroke[] getBoundKeyStrokes();
+ Action getDefaultAction();
+ KeyStroke[] getKeyStrokesForAction(Action a);
+ String getName();
+ Keymap getResolveParent();
+ boolean isLocallyDefined(KeyStroke key);
+ void removeBindings();
+ void removeKeyStrokeBinding(KeyStroke keys);
+ void setDefaultAction(Action a);
+ void setResolveParent(Keymap parent);
+}
+
+
diff --git a/libjava/classpath/javax/swing/text/LayeredHighlighter.java b/libjava/classpath/javax/swing/text/LayeredHighlighter.java
new file mode 100644
index 00000000000..dcaf1c504c6
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/LayeredHighlighter.java
@@ -0,0 +1,57 @@
+/* LayeredHighlighter.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. */
+
+package javax.swing.text;
+
+import java.awt.Graphics;
+import java.awt.Shape;
+
+public abstract class LayeredHighlighter
+ implements Highlighter
+{
+ public abstract static class LayerPainter
+ implements Highlighter.HighlightPainter
+ {
+ public abstract Shape paintLayer(Graphics g, int p0, int p1,
+ Shape viewBounds, JTextComponent editor,
+ View view);
+ }
+
+ public abstract void paintLayeredHighlights(Graphics g, int p0, int p1,
+ Shape viewBounds,
+ JTextComponent editor, View view);
+}
diff --git a/libjava/classpath/javax/swing/text/MutableAttributeSet.java b/libjava/classpath/javax/swing/text/MutableAttributeSet.java
new file mode 100644
index 00000000000..2fe9ad50f67
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/MutableAttributeSet.java
@@ -0,0 +1,85 @@
+/* MutableAttributeSet.java --
+ Copyright (C) 2002, 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.util.Enumeration;
+
+/**
+ * MutableAttributeSet
+ * @author Andrew Selkirk
+ * @version 1.0
+ */
+public interface MutableAttributeSet extends AttributeSet
+{
+ /**
+ * addAttribute
+ * @param name TODO
+ * @param value TODO
+ */
+ void addAttribute(Object name, Object value);
+
+ /**
+ * addAttributes
+ * @param attributes TODO
+ */
+ void addAttributes(AttributeSet attributes);
+
+ /**
+ * removeAttribute
+ * @param name TODO
+ */
+ void removeAttribute(Object name);
+
+ /**
+ * removeAttributes
+ * @param names TODO
+ */
+ void removeAttributes(Enumeration names);
+
+ /**
+ * removeAttributes
+ * @param attributes TODO
+ */
+ void removeAttributes(AttributeSet attributes);
+
+ /**
+ * setResolveParent
+ * @param parent TODO
+ */
+ void setResolveParent(AttributeSet parent);
+}
diff --git a/libjava/classpath/javax/swing/text/NavigationFilter.java b/libjava/classpath/javax/swing/text/NavigationFilter.java
new file mode 100644
index 00000000000..45f58f9e229
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/NavigationFilter.java
@@ -0,0 +1,71 @@
+/* NavigationFilter.java --
+ Copyright (C) 2003, 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;
+
+public class NavigationFilter
+{
+ public abstract static class FilterBypass
+ {
+ public FilterBypass()
+ {
+ // Do nothing here.
+ }
+
+ public abstract Caret getCaret();
+ public abstract void moveDot(int dot, Position.Bias bias);
+ public abstract void setDot(int dot, Position.Bias bias);
+ }
+
+ public NavigationFilter()
+ {
+ // Do nothing here.
+ }
+
+ public void moveDot(NavigationFilter.FilterBypass fb, int dot,
+ Position.Bias bias)
+ {
+ fb.moveDot(dot, bias);
+ }
+
+ public void setDot(NavigationFilter.FilterBypass fb, int dot,
+ Position.Bias bias)
+ {
+ fb.setDot(dot, bias);
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/PasswordView.java b/libjava/classpath/javax/swing/text/PasswordView.java
new file mode 100644
index 00000000000..229fd2b508d
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/PasswordView.java
@@ -0,0 +1,170 @@
+/* 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. */
+
+
+package javax.swing.text;
+
+import java.awt.Color;
+import java.awt.Graphics;
+
+import javax.swing.JPasswordField;
+
+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);
+ }
+
+ /**
+ * Draws one echo character at a given position.
+ *
+ * @param g the <code>Graphics</code> object to draw to
+ * @param x the x-position
+ * @param y the y-position
+ * @param ch the echo character
+ *
+ * @return the next x position right of the drawn character
+ */
+ protected int drawEchoCharacter(Graphics g, int x, int y, char ch)
+ {
+ // Update font metrics.
+ updateMetrics();
+
+ // Draw character.
+ oneCharBuffer[0] = ch;
+ g.drawChars(oneCharBuffer, 0, 1, x, y);
+
+ // Return new x position right of drawn character.
+ return x + metrics.charWidth(ch);
+ }
+
+ private char getEchoChar()
+ {
+ char ch = ((JPasswordField) getContainer()).getEchoChar();
+
+ if (ch == 0)
+ ch = '*';
+
+ return ch;
+ }
+
+ /**
+ * Draws selected text at a given position.
+ *
+ * @param g the <code>Graphics</code> object to draw to
+ * @param x the x-position
+ * @param y the y-position
+ * @param p0 the position of the first character to draw
+ * @param p1 the position of the first character not to draw
+ *
+ * @return the next x position right of the drawn character
+ */
+ protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1)
+ throws BadLocationException
+ {
+ // FIXME: Throw BadLocationException somehow.
+
+ // Update font metrics.
+ updateMetrics();
+
+ // Get echo character.
+ char ch = getEchoChar();
+
+ // Set color for selected text.
+ g.setColor(selectedColor);
+ g.setColor(Color.BLACK);
+
+ // Initialize buffer for faster drawing of all characters.
+ int len = p1 - p0;
+ 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);
+
+ // Return new x position right of all drawn characters.
+ return x + len * metrics.charWidth(ch);
+ }
+
+ /**
+ * Draws unselected text at a given position.
+ *
+ * @param g the <code>Graphics</code> object to draw to
+ * @param x the x-position
+ * @param y the y-position
+ * @param p0 the position of the first character to draw
+ * @param p1 the position of the first character not to draw
+ *
+ * @return the next x position right of the drawn character
+ */
+ protected int drawUnselectedText(Graphics g, int x, int y, int p0, int p1)
+ throws BadLocationException
+ {
+ // FIXME: Throw BadLocationException somehow.
+
+ // Update font metrics.
+ updateMetrics();
+
+ // Get echo character.
+ char ch = getEchoChar();
+
+ // Set color for unselected text.
+ g.setColor(unselectedColor);
+ g.setColor(Color.BLACK);
+
+ // Initialize buffer for faster drawing of all characters.
+ int len = p1 - p0;
+ 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);
+
+ // Return new x position right of all drawn characters.
+ return x + len * metrics.charWidth(ch);
+ }
+}
+
diff --git a/libjava/classpath/javax/swing/text/PlainDocument.java b/libjava/classpath/javax/swing/text/PlainDocument.java
new file mode 100644
index 00000000000..c3f59e436cb
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/PlainDocument.java
@@ -0,0 +1,166 @@
+/* PlainDocument.java --
+ Copyright (C) 2002, 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.util.ArrayList;
+
+public class PlainDocument extends AbstractDocument
+{
+ private static final long serialVersionUID = 4758290289196893664L;
+
+ public static final String lineLimitAttribute = "lineLimit";
+ public static final String tabSizeAttribute = "tabSize";
+
+ private BranchElement rootElement;
+ private int tabSize;
+
+ public PlainDocument()
+ {
+ this(new GapContent());
+ }
+
+ public PlainDocument(AbstractDocument.Content content)
+ {
+ super(content);
+ tabSize = 8;
+ rootElement = (BranchElement) createDefaultRoot();
+ }
+
+ private void reindex()
+ {
+ Element[] lines;
+ try
+ {
+ String str = content.getString(0, content.length());
+
+ ArrayList elts = new ArrayList();
+ int j = 0;
+ for (int i = str.indexOf('\n', 0); i != -1; i = str.indexOf('\n', i + 1))
+ {
+ elts.add(createLeafElement(rootElement, SimpleAttributeSet.EMPTY, j, i + 1));
+ j = i + 1;
+ }
+
+ if (j < content.length())
+ elts.add(createLeafElement(rootElement, SimpleAttributeSet.EMPTY, j, content.length()));
+
+ lines = new Element[elts.size()];
+ for (int i = 0; i < elts.size(); ++i)
+ lines[i] = (Element) elts.get(i);
+ }
+ catch (BadLocationException e)
+ {
+ lines = new Element[1];
+ lines[0] = createLeafElement(rootElement, SimpleAttributeSet.EMPTY, 0, 1);
+ }
+
+ ((BranchElement) rootElement).replace(0, rootElement.getElementCount(), lines);
+ }
+
+ protected AbstractDocument.AbstractElement createDefaultRoot()
+ {
+ BranchElement root =
+ (BranchElement) createBranchElement(null, SimpleAttributeSet.EMPTY);
+
+ Element[] array = new Element[1];
+ array[0] = createLeafElement(root, SimpleAttributeSet.EMPTY, 0, 1);
+ root.replace(0, 0, array);
+
+ return root;
+ }
+
+ protected void insertUpdate(DefaultDocumentEvent event, AttributeSet attributes)
+ {
+ reindex();
+
+ super.insertUpdate(event, attributes);
+ }
+
+ protected void removeUpdate(DefaultDocumentEvent event)
+ {
+ super.removeUpdate(event);
+
+ int p0 = event.getOffset();
+ int len = event.getLength();
+ int p1 = len + p0;
+
+ // check if we must collapse some elements
+ int i1 = rootElement.getElementIndex(p0);
+ int i2 = rootElement.getElementIndex(p1);
+ if (i1 != i2)
+ {
+ Element el1 = rootElement.getElement(i1);
+ Element el2 = rootElement.getElement(i2);
+ int start = el1.getStartOffset();
+ int end = el2.getEndOffset();
+ // collapse elements if the removal spans more than 1 line
+ Element newEl = createLeafElement(rootElement,
+ SimpleAttributeSet.EMPTY,
+ 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()
+ {
+ return rootElement;
+ }
+
+ public Element getParagraphElement(int pos)
+ {
+ Element root = getDefaultRootElement();
+ return root.getElement(root.getElementIndex(pos));
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/PlainView.java b/libjava/classpath/javax/swing/text/PlainView.java
new file mode 100644
index 00000000000..5d1fab00032
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/PlainView.java
@@ -0,0 +1,241 @@
+/* PlainView.java --
+ Copyright (C) 2004, 2005 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.Component;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+public class PlainView extends View
+ implements TabExpander
+{
+ Color selectedColor;
+ Color unselectedColor;
+ Font font;
+
+ protected FontMetrics metrics;
+
+ public PlainView(Element elem)
+ {
+ super(elem);
+ }
+
+ /**
+ * @since 1.4
+ */
+ protected void updateMetrics()
+ {
+ Component component = getContainer();
+ Font font = component.getFont();
+
+ if (this.font != font)
+ {
+ this.font = font;
+ metrics = component.getFontMetrics(font);
+ }
+ }
+
+ /**
+ * @since 1.4
+ */
+ protected Rectangle lineToRect(Shape a, int line)
+ {
+ // Ensure metrics are up-to-date.
+ updateMetrics();
+
+ Rectangle rect = a.getBounds();
+ int fontHeight = metrics.getHeight();
+ return new Rectangle(rect.x, rect.y + (line * fontHeight),
+ rect.width, fontHeight);
+ }
+
+ public Shape modelToView(int position, Shape a, Position.Bias b)
+ throws BadLocationException
+ {
+ // Ensure metrics are up-to-date.
+ updateMetrics();
+
+ Document document = getDocument();
+
+ // Get rectangle of the line containing position.
+ int lineIndex = getElement().getElementIndex(position);
+ Rectangle rect = lineToRect(a, lineIndex);
+
+ // Get the rectangle for position.
+ Element line = getElement().getElement(lineIndex);
+ int lineStart = line.getStartOffset();
+ Segment segment = new Segment();
+ document.getText(lineStart, position - lineStart, segment);
+ int xoffset = Utilities.getTabbedTextWidth(segment, metrics, rect.x,
+ this, lineStart);
+
+ // Calc the real rectangle.
+ rect.x += xoffset;
+ rect.width = 1;
+ rect.height = metrics.getHeight();
+
+ return rect;
+ }
+
+ protected void drawLine(int lineIndex, Graphics g, int x, int y)
+ {
+ try
+ {
+ metrics = g.getFontMetrics();
+ // FIXME: Selected text are not drawn yet.
+ Element line = getElement().getElement(lineIndex);
+ drawUnselectedText(g, x, y, line.getStartOffset(), line.getEndOffset());
+ //drawSelectedText(g, , , , );
+ }
+ catch (BadLocationException e)
+ {
+ // This should never happen.
+ }
+ }
+
+ protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1)
+ throws BadLocationException
+ {
+ g.setColor(selectedColor);
+ Segment segment = new Segment();
+ getDocument().getText(p0, p1 - p0, segment);
+ return Utilities.drawTabbedText(segment, x, y, g, this, 0);
+ }
+
+ protected int drawUnselectedText(Graphics g, int x, int y, int p0, int p1)
+ throws BadLocationException
+ {
+ g.setColor(unselectedColor);
+ Segment segment = new Segment();
+ getDocument().getText(p0, p1 - p0, segment);
+ return Utilities.drawTabbedText(segment, x, y, g, this, segment.offset);
+ }
+
+ public void paint(Graphics g, Shape s)
+ {
+ // Ensure metrics are up-to-date.
+ updateMetrics();
+
+ JTextComponent textComponent = (JTextComponent) getContainer();
+
+ g.setFont(textComponent.getFont());
+ selectedColor = textComponent.getSelectedTextColor();
+ unselectedColor = textComponent.getForeground();
+
+ Rectangle rect = s.getBounds();
+
+ // FIXME: Text may be scrolled.
+ Document document = textComponent.getDocument();
+ Element root = document.getDefaultRootElement();
+ int y = rect.y;
+
+ for (int i = 0; i < root.getElementCount(); i++)
+ {
+ drawLine(i, g, rect.x, y);
+ y += metrics.getHeight();
+ }
+ }
+
+ protected int getTabSize()
+ {
+ return 8;
+ }
+
+ /**
+ * Returns the next tab stop position after a given reference position.
+ *
+ * This implementation ignores the <code>tabStop</code> argument.
+ *
+ * @param x the current x position in pixels
+ * @param tabStop the position within the text stream that the tab occured at
+ */
+ public float nextTabStop(float x, int tabStop)
+ {
+ float tabSizePixels = getTabSize() + metrics.charWidth('m');
+ return (float) (Math.floor(x / tabSizePixels) + 1) * tabSizePixels;
+ }
+
+ public float getPreferredSpan(int axis)
+ {
+ if (axis != X_AXIS && axis != Y_AXIS)
+ throw new IllegalArgumentException();
+
+ // make sure we have the metrics
+ updateMetrics();
+
+ float span = 0;
+ Element el = getElement();
+ Document doc = el.getDocument();
+ Segment seg = new Segment();
+
+ switch (axis)
+ {
+ case X_AXIS:
+ // calculate the maximum of the line's widths
+ for (int i = 0; i < el.getElementCount(); i++)
+ {
+ Element child = el.getElement(i);
+ int start = child.getStartOffset();
+ int end = child.getEndOffset();
+ try {
+ doc.getText(start, start + end, seg);
+ }
+ catch (BadLocationException ex)
+ {
+ // throw new ClasspathAssertionError
+ // ("no BadLocationException should be thrown here");
+ }
+ int width = metrics.charsWidth(seg.array, seg.offset, seg.count);
+ span = Math.max(span, width);
+ }
+ break;
+ case Y_AXIS:
+ default:
+ span = metrics.getHeight() * el.getElementCount();
+ break;
+ }
+
+ return span;
+ }
+}
+
diff --git a/libjava/classpath/javax/swing/text/Position.java b/libjava/classpath/javax/swing/text/Position.java
new file mode 100644
index 00000000000..a9d3d09d764
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/Position.java
@@ -0,0 +1,62 @@
+/* Position.java --
+ Copyright (C) 2002, 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;
+
+
+public interface Position
+{
+ static class Bias
+ {
+ public static final Bias Backward = new Bias("backward");
+ public static final Bias Forward = new Bias("forward");
+
+ private String name;
+
+ private Bias(String n)
+ {
+ name = n;
+ }
+
+ public String toString()
+ {
+ return name;
+ }
+ }
+
+ int getOffset();
+}
diff --git a/libjava/classpath/javax/swing/text/Segment.java b/libjava/classpath/javax/swing/text/Segment.java
new file mode 100644
index 00000000000..92d850016d9
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/Segment.java
@@ -0,0 +1,176 @@
+/* Segment.java --
+ Copyright (C) 2002, 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.text.CharacterIterator;
+
+public class Segment
+ implements Cloneable, CharacterIterator
+{
+ private boolean partialReturn;
+ private int current;
+
+ public char[] array;
+ public int count;
+ public int offset;
+
+ public Segment()
+ {
+ }
+
+ public Segment(char[] array, int offset, int count)
+ {
+ this.array = array;
+ this.offset = offset;
+ this.count = count;
+ }
+
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ return null;
+ }
+ }
+
+ public char current()
+ {
+ if (count == 0
+ || current >= getEndIndex())
+ return DONE;
+
+ return array[current];
+ }
+
+ public char first()
+ {
+ if (count == 0)
+ return DONE;
+
+ current = getBeginIndex();
+ return array[current];
+ }
+
+ public int getBeginIndex()
+ {
+ return offset;
+ }
+
+ public int getEndIndex()
+ {
+ return offset + count;
+ }
+
+ public int getIndex()
+ {
+ return current;
+ }
+
+ public char last()
+ {
+ if (count == 0)
+ return DONE;
+
+ current = getEndIndex() - 1;
+ return array[current];
+ }
+
+ public char next()
+ {
+ if (count == 0)
+ return DONE;
+
+ if ((current + 1) >= getEndIndex())
+ {
+ current = getEndIndex();
+ return DONE;
+ }
+
+ current++;
+ return array[current];
+ }
+
+ public char previous()
+ {
+ if (count == 0
+ || current == getBeginIndex())
+ return DONE;
+
+ current--;
+ return array[current];
+ }
+
+ public char setIndex(int position)
+ {
+ if (position < getBeginIndex()
+ || position > getEndIndex())
+ throw new IllegalArgumentException();
+
+ current = position;
+
+ if (position == getEndIndex())
+ return DONE;
+
+ return array[current];
+ }
+
+ public String toString()
+ {
+ return new String(array, offset, count);
+ }
+
+ /**
+ * @since 1.4
+ */
+ public void setPartialReturn(boolean p)
+ {
+ partialReturn = p;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public boolean isPartialReturn()
+ {
+ return partialReturn;
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/SimpleAttributeSet.java b/libjava/classpath/javax/swing/text/SimpleAttributeSet.java
new file mode 100644
index 00000000000..3ef5db61d43
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/SimpleAttributeSet.java
@@ -0,0 +1,193 @@
+/* SimpleAttributeSet.java --
+ Copyright (C) 2004, 2005 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.io.Serializable;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+public class SimpleAttributeSet
+ implements MutableAttributeSet, Serializable, Cloneable
+{
+ public static final AttributeSet EMPTY = new SimpleAttributeSet();
+
+ Hashtable tab;
+
+ public SimpleAttributeSet()
+ {
+ this(null);
+ }
+
+ public SimpleAttributeSet(AttributeSet a)
+ {
+ tab = new Hashtable();
+ if (a != null)
+ addAttributes(a);
+ }
+
+ public void addAttribute(Object name, Object value)
+ {
+ tab.put(name, value);
+ }
+
+ public void addAttributes(AttributeSet attributes)
+ {
+ Enumeration e = attributes.getAttributeNames();
+ while (e.hasMoreElements())
+ {
+ Object name = e.nextElement();
+ Object val = attributes.getAttribute(name);
+ tab.put(name, val);
+ }
+ }
+
+ public Object clone()
+ {
+ SimpleAttributeSet s = new SimpleAttributeSet();
+ s.tab = (Hashtable) tab.clone();
+ return s;
+ }
+
+ public boolean containsAttribute(Object name, Object value)
+ {
+ return tab.containsKey(name)
+ && tab.get(name).equals(value);
+ }
+
+ public boolean containsAttributes(AttributeSet attributes)
+ {
+ Enumeration e = attributes.getAttributeNames();
+ while (e.hasMoreElements())
+ {
+ Object name = e.nextElement();
+ Object val = attributes.getAttribute(name);
+ if (! containsAttribute(name, val))
+ return false;
+ }
+ return true;
+ }
+
+ public AttributeSet copyAttributes()
+ {
+ return (AttributeSet) clone();
+ }
+
+ public boolean equals(Object obj)
+ {
+ return (obj != null)
+ && (obj instanceof SimpleAttributeSet)
+ && ((SimpleAttributeSet)obj).tab.equals(this.tab);
+ }
+
+ public Object getAttribute(Object name)
+ {
+ Object val = tab.get(name);
+ if (val != null)
+ return val;
+
+ Object p = getResolveParent();
+ if (p != null && p instanceof AttributeSet)
+ return (((AttributeSet)p).getAttribute(name));
+
+ return null;
+ }
+
+ public int getAttributeCount()
+ {
+ return tab.size();
+ }
+
+ public Enumeration getAttributeNames()
+ {
+ return tab.keys();
+ }
+
+ public AttributeSet getResolveParent()
+ {
+ return (AttributeSet) tab.get(ResolveAttribute);
+ }
+
+ public int hashCode()
+ {
+ return tab.hashCode();
+ }
+
+ public boolean isDefined(Object attrName)
+ {
+ return tab.containsKey(attrName);
+ }
+
+ public boolean isEmpty()
+ {
+ return tab.isEmpty();
+ }
+
+ public boolean isEqual(AttributeSet attr)
+ {
+ return this.equals(attr);
+ }
+
+ public void removeAttribute(Object name)
+ {
+ tab.remove(name);
+ }
+
+ public void removeAttributes(AttributeSet attributes)
+ {
+ removeAttributes(attributes.getAttributeNames());
+ }
+
+ public void removeAttributes(Enumeration names)
+ {
+ while (names.hasMoreElements())
+ {
+ removeAttribute(names.nextElement());
+ }
+ }
+
+ public void setResolveParent(AttributeSet parent)
+ {
+ addAttribute(ResolveAttribute, parent);
+ }
+
+ public String toString()
+ {
+ return tab.toString();
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/StringContent.java b/libjava/classpath/javax/swing/text/StringContent.java
new file mode 100644
index 00000000000..bedf480d4ec
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/StringContent.java
@@ -0,0 +1,307 @@
+/* StringContent.java --
+ Copyright (C) 2005 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.io.Serializable;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.swing.undo.AbstractUndoableEdit;
+import javax.swing.undo.CannotRedoException;
+import javax.swing.undo.CannotUndoException;
+import javax.swing.undo.UndoableEdit;
+
+/**
+ * An implementation of the <code>AbstractDocument.Content</code>
+ * interface useful for small documents or debugging. The character
+ * content is a simple character array. It's not really efficient.
+ *
+ * <p>Do not use this class for large size.</p>
+ */
+public final class StringContent implements AbstractDocument.Content, Serializable
+{
+ // This is package-private to avoid an accessor method.
+ char[] content;
+
+ private int count;
+
+ private Vector positions = new Vector();
+
+ private class InsertUndo extends AbstractUndoableEdit
+ {
+ private int start;
+
+ private int length;
+
+ private String redoContent;
+
+ public InsertUndo(int start, int length)
+ {
+ super();
+ this.start = start;
+ this.length = length;
+ }
+
+ public void undo()
+ {
+ super.undo();
+ try
+ {
+ StringContent.this.checkLocation(this.start, this.length);
+ this.redoContent = new String(StringContent.this.content, this.start, this.length);
+ StringContent.this.remove(this.start, this.length);
+ }
+ catch (BadLocationException b)
+ {
+ throw new CannotUndoException();
+ }
+ }
+
+ public void redo()
+ {
+ super.redo();
+ try
+ {
+ StringContent.this.insertString(this.start, this.redoContent);
+ }
+ catch (BadLocationException b)
+ {
+ throw new CannotRedoException();
+ }
+ }
+ }
+
+ private class RemoveUndo extends AbstractUndoableEdit
+ {
+ private int start;
+
+ private String undoString;
+
+ public RemoveUndo(int start, String str)
+ {
+ super();
+ this.start = start;
+ this.undoString = str;
+ }
+
+ public void undo()
+ {
+ super.undo();
+ try
+ {
+ StringContent.this.insertString(this.start, this.undoString);
+ }
+ catch (BadLocationException bad)
+ {
+ throw new CannotUndoException();
+ }
+ }
+
+ public void redo()
+ {
+ super.redo();
+ try
+ {
+ int end = this.undoString.length();
+ StringContent.this.remove(this.start, end);
+ }
+ catch (BadLocationException bad)
+ {
+ throw new CannotRedoException();
+ }
+ }
+ }
+
+ private class StickyPosition implements Position
+ {
+ private int offset = -1;
+
+ public StickyPosition(int offset)
+ {
+ this.offset = offset;
+ }
+
+ // This is package-private to avoid an accessor method.
+ void setOffset(int offset)
+ {
+ this.offset = this.offset >= 0 ? offset : -1;
+ }
+
+ /**
+ * Should be >=0.
+ */
+ public int getOffset()
+ {
+ return offset < 0 ? 0 : offset;
+ }
+ }
+
+ public StringContent()
+ {
+ this(1);
+ }
+
+ public StringContent(int initialLength)
+ {
+ super();
+ if (initialLength < 1)
+ initialLength = 1;
+ this.content = new char[initialLength];
+ this.content[0] = '\n';
+ this.count = 1;
+ }
+
+ protected Vector getPositionsInRange(Vector v,
+ int offset,
+ int length)
+ {
+ Vector refPos = new Vector();
+ Iterator iter = this.positions.iterator();
+ while(iter.hasNext())
+ {
+ Position p = (Position)iter.next();
+ if ((offset <= p.getOffset())
+ && (p.getOffset() <= (offset + length)))
+ refPos.add(p);
+ }
+ return refPos;
+ }
+
+ public Position createPosition(int offset) throws BadLocationException
+ {
+ if (offset < this.count || offset > this.count)
+ checkLocation(offset, 0);
+ StickyPosition sp = new StickyPosition(offset);
+ this.positions.add(sp);
+ return sp;
+ }
+
+ public int length()
+ {
+ return this.count;
+ }
+
+ public UndoableEdit insertString(int where, String str)
+ throws BadLocationException
+ {
+ checkLocation(where, 0);
+ if (where == this.count)
+ throw new BadLocationException("Invalid location", 1);
+ if (str == null)
+ throw new NullPointerException();
+ char[] insert = str.toCharArray();
+ char[] temp = new char[this.content.length + insert.length];
+ this.count += insert.length;
+ // Copy array and insert the string.
+ if (where > 0)
+ System.arraycopy(this.content, 0, temp, 0, where);
+ System.arraycopy(insert, 0, temp, where, insert.length);
+ System.arraycopy(this.content, where, temp, (where + insert.length), (temp.length - where - insert.length));
+ if (this.content.length < temp.length)
+ this.content = new char[temp.length];
+ // Copy the result in the original char array.
+ System.arraycopy(temp, 0, this.content, 0, temp.length);
+ // Move all the positions.
+ Vector refPos = getPositionsInRange(this.positions, where, temp.length - where);
+ Iterator iter = refPos.iterator();
+ while (iter.hasNext())
+ {
+ StickyPosition p = (StickyPosition)iter.next();
+ p.setOffset(p.getOffset() + str.length());
+ }
+ InsertUndo iundo = new InsertUndo(where, insert.length);
+ return iundo;
+ }
+
+ public UndoableEdit remove(int where, int nitems) throws BadLocationException
+ {
+ checkLocation(where, nitems);
+ char[] temp = new char[(this.content.length - nitems)];
+ this.count = this.count - nitems;
+ RemoveUndo rundo = new RemoveUndo(where, new String(this.content, where, nitems));
+ // Copy array.
+ System.arraycopy(this.content, 0, temp, 0, where);
+ System.arraycopy(this.content, where + nitems, temp, where, this.content.length - where - nitems);
+ this.content = new char[temp.length];
+ // Then copy the result in the original char array.
+ System.arraycopy(temp, 0, this.content, 0, this.content.length);
+ // Move all the positions.
+ Vector refPos = getPositionsInRange(this.positions, where, this.content.length + nitems - where);
+ Iterator iter = refPos.iterator();
+ while (iter.hasNext())
+ {
+ StickyPosition p = (StickyPosition)iter.next();
+ int result = p.getOffset() - nitems;
+ p.setOffset(result);
+ if (result < 0)
+ this.positions.remove(p);
+ }
+ return rundo;
+ }
+
+ public String getString(int where, int len) throws BadLocationException
+ {
+ checkLocation(where, len);
+ return new String (this.content, where, len);
+ }
+
+ public void getChars(int where, int len, Segment txt) throws BadLocationException
+ {
+ checkLocation(where, len);
+ if (txt != null)
+ {
+ txt.array = this.content;
+ txt.offset = where;
+ txt.count = len;
+ }
+ }
+
+ // This is package-private to avoid an accessor method.
+ void checkLocation(int where, int len) throws BadLocationException
+ {
+ if (where < 0)
+ throw new BadLocationException("Invalid location", 1);
+ else if (where > this.count)
+ throw new BadLocationException("Invalid location", this.count);
+ else if ((where + len)>this.count)
+ throw new BadLocationException("Invalid range", this.count);
+ }
+
+}
+
diff --git a/libjava/classpath/javax/swing/text/Style.java b/libjava/classpath/javax/swing/text/Style.java
new file mode 100644
index 00000000000..851ac021947
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/Style.java
@@ -0,0 +1,64 @@
+/* Style.java --
+ Copyright (C) 2002, 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 javax.swing.event.ChangeListener;
+
+public interface Style extends MutableAttributeSet
+{
+ /**
+ * Returns the name of the style.
+ *
+ * @return the name
+ */
+ String getName();
+
+ /**
+ * Adds a <code>ChangeListener</code> object to the style.
+ *
+ * @param listener the listener object to add
+ */
+ void addChangeListener(ChangeListener listener);
+
+ /**
+ * Removes a <code>ChangeListener</code> from to the style.
+ *
+ * @param listener the listener object to remove,
+ */
+ void removeChangeListener(ChangeListener listener);
+}
diff --git a/libjava/classpath/javax/swing/text/StyleConstants.java b/libjava/classpath/javax/swing/text/StyleConstants.java
new file mode 100644
index 00000000000..3f973f22631
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/StyleConstants.java
@@ -0,0 +1,443 @@
+/* StyleConstants.java --
+ Copyright (C) 2004, 2005 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.Component;
+
+import javax.swing.Icon;
+
+public class StyleConstants
+{
+ public static final int ALIGN_LEFT = 0;
+ public static final int ALIGN_CENTER = 1;
+ public static final int ALIGN_RIGHT = 2;
+ public static final int ALIGN_JUSTIFIED = 3;
+
+ public static final Object Background = CharacterConstants.Background;
+ public static final Object BidiLevel = CharacterConstants.BidiLevel;
+ public static final Object Bold = CharacterConstants.Bold;
+ public static final Object ComponentAttribute = CharacterConstants.ComponentAttribute;
+ public static final Object FontFamily = CharacterConstants.Family;
+ public static final Object FontSize = CharacterConstants.Size;
+ public static final Object Foreground = CharacterConstants.Foreground;
+ public static final Object IconAttribute = CharacterConstants.IconAttribute;
+ public static final Object Italic = CharacterConstants.Italic;
+ public static final Object StrikeThrough = CharacterConstants.StrikeThrough;
+ public static final Object Subscript = CharacterConstants.Subscript;
+ public static final Object Superscript = CharacterConstants.Superscript;
+ public static final Object Underline = CharacterConstants.Underline;
+
+ public static final Object Alignment = ParagraphConstants.Alignment;
+ public static final Object FirstLineIndent = ParagraphConstants.FirstLineIndent;
+ public static final Object LeftIndent = ParagraphConstants.LeftIndent;
+ public static final Object LineSpacing = ParagraphConstants.LineSpacing;
+ public static final Object Orientation = ParagraphConstants.Orientation;
+ public static final Object RightIndent = ParagraphConstants.RightIndent;
+ public static final Object SpaceAbove = ParagraphConstants.SpaceAbove;
+ public static final Object SpaceBelow = ParagraphConstants.SpaceBelow;
+ public static final Object TabSet = ParagraphConstants.TabSet;
+
+ public static final String ComponentElementName = "component";
+ public static final String IconElementName = "icon";
+
+ public static final Object ComposedTextAttribute = new StyleConstants("composed text");
+ public static final Object ModelAttribute = new StyleConstants("model");
+ public static final Object NameAttribute = new StyleConstants("name");
+ public static final Object ResolveAttribute = new StyleConstants("resolver");
+
+ String keyname;
+
+ // Package-private to avoid accessor constructor for use by
+ // subclasses.
+ StyleConstants(String k)
+ {
+ keyname = k;
+ }
+
+ public String toString()
+ {
+ return keyname;
+ }
+
+ public static int getAlignment(AttributeSet a)
+ {
+ if (a.isDefined(Alignment))
+ return ((Integer)a.getAttribute(Alignment)).intValue();
+ else
+ return ALIGN_LEFT;
+ }
+
+ public static Color getBackground(AttributeSet a)
+ {
+ if (a.isDefined(Background))
+ return (Color) a.getAttribute(Background);
+ else
+ return Color.BLACK;
+ }
+
+ public static int getBidiLevel(AttributeSet a)
+ {
+ if (a.isDefined(BidiLevel))
+ return ((Integer)a.getAttribute(BidiLevel)).intValue();
+ else
+ return 0;
+ }
+
+ public static Component getComponent(AttributeSet a)
+ {
+ if (a.isDefined(ComponentAttribute))
+ return (Component) a.getAttribute(ComponentAttribute);
+ else
+ return (Component) null;
+ }
+
+ public static float getFirstLineIndent(AttributeSet a)
+ {
+ if (a.isDefined(FirstLineIndent))
+ return ((Float)a.getAttribute(FirstLineIndent)).floatValue();
+ else
+ return 0.f;
+ }
+
+ public static String getFontFamily(AttributeSet a)
+ {
+ if (a.isDefined(FontFamily))
+ return (String) a.getAttribute(FontFamily);
+ else
+ return "Monospaced";
+ }
+
+ public static int getFontSize(AttributeSet a)
+ {
+ if (a.isDefined(FontSize))
+ return ((Integer)a.getAttribute(FontSize)).intValue();
+ else
+ return 12;
+ }
+
+ public static Color getForeground(AttributeSet a)
+ {
+ if (a.isDefined(Foreground))
+ return (Color) a.getAttribute(Foreground);
+ else
+ return Color.BLACK;
+ }
+
+ public static Icon getIcon(AttributeSet a)
+ {
+ if (a.isDefined(IconAttribute))
+ return (Icon) a.getAttribute(IconAttribute);
+ else
+ return (Icon) null;
+ }
+
+ public static float getLeftIndent(AttributeSet a)
+ {
+ if (a.isDefined(LeftIndent))
+ return ((Float)a.getAttribute(LeftIndent)).floatValue();
+ else
+ return 0.f;
+ }
+
+ public static float getLineSpacing(AttributeSet a)
+ {
+ if (a.isDefined(LineSpacing))
+ return ((Float)a.getAttribute(LineSpacing)).floatValue();
+ else
+ return 0.f;
+ }
+
+ public static float getRightIndent(AttributeSet a)
+ {
+ if (a.isDefined(RightIndent))
+ return ((Float)a.getAttribute(RightIndent)).floatValue();
+ else
+ return 0.f;
+ }
+
+ public static float getSpaceAbove(AttributeSet a)
+ {
+ if (a.isDefined(SpaceAbove))
+ return ((Float)a.getAttribute(SpaceAbove)).floatValue();
+ else
+ return 0.f;
+ }
+
+ public static float getSpaceBelow(AttributeSet a)
+ {
+ if (a.isDefined(SpaceBelow))
+ return ((Float)a.getAttribute(SpaceBelow)).floatValue();
+ else
+ return 0.f;
+ }
+
+ public static javax.swing.text.TabSet getTabSet(AttributeSet a)
+ {
+ if (a.isDefined(StyleConstants.TabSet))
+ return (javax.swing.text.TabSet) a.getAttribute(StyleConstants.TabSet);
+ else
+ return (javax.swing.text.TabSet) null;
+ }
+
+ public static boolean isBold(AttributeSet a)
+ {
+ if (a.isDefined(Bold))
+ return ((Boolean) a.getAttribute(Bold)).booleanValue();
+ else
+ return false;
+ }
+
+ public static boolean isItalic(AttributeSet a)
+ {
+ if (a.isDefined(Italic))
+ return ((Boolean) a.getAttribute(Italic)).booleanValue();
+ else
+ return false;
+ }
+
+ public static boolean isStrikeThrough(AttributeSet a)
+ {
+ if (a.isDefined(StrikeThrough))
+ return ((Boolean) a.getAttribute(StrikeThrough)).booleanValue();
+ else
+ return false;
+ }
+
+ public static boolean isSubscript(AttributeSet a)
+ {
+ if (a.isDefined(Subscript))
+ return ((Boolean) a.getAttribute(Subscript)).booleanValue();
+ else
+ return false;
+ }
+
+ public static boolean isSuperscript(AttributeSet a)
+ {
+ if (a.isDefined(Superscript))
+ return ((Boolean) a.getAttribute(Superscript)).booleanValue();
+ else
+ return false;
+ }
+
+ public static boolean isUnderline(AttributeSet a)
+ {
+ if (a.isDefined(Underline))
+ return ((Boolean) a.getAttribute(Underline)).booleanValue();
+ else
+ return false;
+ }
+
+ public static void setAlignment(MutableAttributeSet a, int align)
+ {
+ a.addAttribute(Alignment, new Integer(align));
+ }
+
+ public static void setBackground(MutableAttributeSet a, Color fg)
+ {
+ a.addAttribute(Background, fg);
+ }
+
+ public static void setBidiLevel(MutableAttributeSet a, int lev)
+ {
+ a.addAttribute(BidiLevel, new Integer(lev));
+ }
+
+ public static void setBold(MutableAttributeSet a, boolean b)
+ {
+ a.addAttribute(Bold, Boolean.valueOf(b));
+ }
+
+ public static void setComponent(MutableAttributeSet a, Component c)
+ {
+ a.addAttribute(ComponentAttribute, c);
+ }
+
+ public static void setFirstLineIndent(MutableAttributeSet a, float i)
+ {
+ a.addAttribute(FirstLineIndent, new Float(i));
+ }
+
+ public static void setFontFamily(MutableAttributeSet a, String fam)
+ {
+ a.addAttribute(FontFamily, fam);
+ }
+
+ public static void setFontSize(MutableAttributeSet a, int s)
+ {
+ a.addAttribute(FontSize, new Integer(s));
+ }
+
+ public static void setForeground(MutableAttributeSet a, Color fg)
+ {
+ a.addAttribute(Foreground, fg);
+ }
+
+ public static void setIcon(MutableAttributeSet a, Icon c)
+ {
+ a.addAttribute(IconAttribute, c);
+ }
+
+ public static void setItalic(MutableAttributeSet a, boolean b)
+ {
+ a.addAttribute(Italic, Boolean.valueOf(b));
+ }
+
+ public static void setLeftIndent(MutableAttributeSet a, float i)
+ {
+ a.addAttribute(LeftIndent, new Float(i));
+ }
+
+ public static void setLineSpacing(MutableAttributeSet a, float i)
+ {
+ a.addAttribute(LineSpacing, new Float(i));
+ }
+
+ public static void setRightIndent(MutableAttributeSet a, float i)
+ {
+ a.addAttribute(RightIndent, new Float(i));
+ }
+
+ public static void setSpaceAbove(MutableAttributeSet a, float i)
+ {
+ a.addAttribute(SpaceAbove, new Float(i));
+ }
+
+ public static void setSpaceBelow(MutableAttributeSet a, float i)
+ {
+ a.addAttribute(SpaceBelow, new Float(i));
+ }
+
+ public static void setStrikeThrough(MutableAttributeSet a, boolean b)
+ {
+ a.addAttribute(StrikeThrough, Boolean.valueOf(b));
+ }
+
+ public static void setSubscript(MutableAttributeSet a, boolean b)
+ {
+ a.addAttribute(Subscript, Boolean.valueOf(b));
+ }
+
+ public static void setSuperscript(MutableAttributeSet a, boolean b)
+ {
+ a.addAttribute(Superscript, Boolean.valueOf(b));
+ }
+
+ public static void setTabSet(MutableAttributeSet a, javax.swing.text.TabSet tabs)
+ {
+ a.addAttribute(StyleConstants.TabSet, tabs);
+ }
+
+ public static void setUnderline(MutableAttributeSet a, boolean b)
+ {
+ a.addAttribute(Underline, Boolean.valueOf(b));
+ }
+
+ // The remainder are so-called "typesafe enumerations" which
+ // alias subsets of the above constants.
+ public static class CharacterConstants
+ extends StyleConstants
+ implements AttributeSet.CharacterAttribute
+ {
+ private CharacterConstants(String k)
+ {
+ super(k);
+ }
+
+ public static Object Background = ColorConstants.Background;
+ public static Object BidiLevel = new CharacterConstants("bidiLevel");
+ public static Object Bold = FontConstants.Bold;
+ public static Object ComponentAttribute = new CharacterConstants("component");
+ public static Object Family = FontConstants.Family;
+ public static Object Size = FontConstants.Size;
+ public static Object Foreground = ColorConstants.Foreground;
+ public static Object IconAttribute = new CharacterConstants("icon");
+ public static Object Italic = FontConstants.Italic;
+ public static Object StrikeThrough = new CharacterConstants("strikethrough");
+ public static Object Subscript = new CharacterConstants("subscript");
+ public static Object Superscript = new CharacterConstants("superscript");
+ public static Object Underline = new CharacterConstants("underline");
+ }
+
+ public static class ColorConstants
+ extends StyleConstants
+ implements AttributeSet.ColorAttribute, AttributeSet.CharacterAttribute
+ {
+ private ColorConstants(String k)
+ {
+ super(k);
+ }
+ public static Object Foreground = new ColorConstants("foreground");
+ public static Object Background = new ColorConstants("background");
+ }
+
+ public static class FontConstants
+ extends StyleConstants
+ implements AttributeSet.FontAttribute, AttributeSet.CharacterAttribute
+ {
+ private FontConstants(String k)
+ {
+ super(k);
+ }
+ public static Object Bold = new FontConstants("bold");
+ public static Object Family = new FontConstants("family");
+ public static Object Italic = new FontConstants("italic");
+ public static Object Size = new FontConstants("size");
+ }
+
+ public static class ParagraphConstants
+ extends StyleConstants
+ implements AttributeSet.ParagraphAttribute
+ {
+ private ParagraphConstants(String k)
+ {
+ super(k);
+ }
+ public static Object Alignment = new ParagraphConstants("Alignment");
+ public static Object FirstLineIndent = new ParagraphConstants("FirstLineIndent");
+ public static Object LeftIndent = new ParagraphConstants("LeftIndent");
+ public static Object LineSpacing = new ParagraphConstants("LineSpacing");
+ public static Object Orientation = new ParagraphConstants("Orientation");
+ public static Object RightIndent = new ParagraphConstants("RightIndent");
+ public static Object SpaceAbove = new ParagraphConstants("SpaceAbove");
+ public static Object SpaceBelow = new ParagraphConstants("SpaceBelow");
+ public static Object TabSet = new ParagraphConstants("TabSet");
+ }
+
+}
diff --git a/libjava/classpath/javax/swing/text/StyleContext.java b/libjava/classpath/javax/swing/text/StyleContext.java
new file mode 100644
index 00000000000..ae11622ffc6
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/StyleContext.java
@@ -0,0 +1,730 @@
+/* StyleContext.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. */
+
+
+package javax.swing.text;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Toolkit;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.Hashtable;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+
+public class StyleContext
+ implements Serializable, AbstractDocument.AttributeContext
+{
+ public class NamedStyle
+ implements Serializable, Style
+ {
+ protected ChangeEvent changeEvent;
+ protected EventListenerList listenerList;
+
+ AttributeSet attributes;
+ String name;
+
+ public NamedStyle()
+ {
+ this(null, null);
+ }
+
+ public NamedStyle(Style parent)
+ {
+ this(null, parent);
+ }
+
+ public NamedStyle(String name, Style parent)
+ {
+ this.name = name;
+ this.attributes = getEmptySet();
+ this.changeEvent = new ChangeEvent(this);
+ this.listenerList = new EventListenerList();
+ setResolveParent(parent);
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String n)
+ {
+ name = n;
+ fireStateChanged();
+ }
+
+ public void addChangeListener(ChangeListener l)
+ {
+ listenerList.add(ChangeListener.class, l);
+ }
+
+ public void removeChangeListener(ChangeListener l)
+ {
+ listenerList.remove(ChangeListener.class, l);
+ }
+
+ public EventListener[] getListeners(Class listenerType)
+ {
+ return listenerList.getListeners(listenerType);
+ }
+
+ public ChangeListener[] getChangeListeners()
+ {
+ return (ChangeListener[]) getListeners(ChangeListener.class);
+ }
+
+ protected void fireStateChanged()
+ {
+ ChangeListener[] listeners = getChangeListeners();
+ for (int i = 0; i < listeners.length; ++i)
+ {
+ listeners[i].stateChanged(changeEvent);
+ }
+ }
+
+ public void addAttribute(Object name, Object value)
+ {
+ attributes = StyleContext.this.addAttribute(attributes, name, value);
+ fireStateChanged();
+ }
+
+ public void addAttributes(AttributeSet attr)
+ {
+ attributes = StyleContext.this.addAttributes(attributes, attr);
+ fireStateChanged();
+ }
+
+ public boolean containsAttribute(Object name, Object value)
+ {
+ return attributes.containsAttribute(name, value);
+ }
+
+ public boolean containsAttributes(AttributeSet attrs)
+ {
+ return attributes.containsAttributes(attrs);
+ }
+
+ public AttributeSet copyAttributes()
+ {
+ return attributes.copyAttributes();
+ }
+
+ public Object getAttribute(Object attrName)
+ {
+ return attributes.getAttribute(attrName);
+ }
+
+ public int getAttributeCount()
+ {
+ return attributes.getAttributeCount();
+ }
+
+ public Enumeration getAttributeNames()
+ {
+ return attributes.getAttributeNames();
+ }
+
+ public boolean isDefined(Object attrName)
+ {
+ return attributes.isDefined(attrName);
+ }
+
+ public boolean isEqual(AttributeSet attr)
+ {
+ return attributes.isEqual(attr);
+ }
+
+ public void removeAttribute(Object name)
+ {
+ attributes = StyleContext.this.removeAttribute(attributes, name);
+ fireStateChanged();
+ }
+
+ public void removeAttributes(AttributeSet attrs)
+ {
+ attributes = StyleContext.this.removeAttributes(attributes, attrs);
+ fireStateChanged();
+ }
+
+ public void removeAttributes(Enumeration names)
+ {
+ attributes = StyleContext.this.removeAttributes(attributes, names);
+ fireStateChanged();
+ }
+
+
+ public AttributeSet getResolveParent()
+ {
+ return attributes.getResolveParent();
+ }
+
+ public void setResolveParent(AttributeSet parent)
+ {
+ if (parent != null)
+ {
+ attributes = StyleContext.this.addAttribute
+ (attributes, ResolveAttribute, parent);
+ }
+ fireStateChanged();
+ }
+
+ public String toString()
+ {
+ return ("[NamedStyle: name=" + name + ", attrs=" + attributes.toString() + "]");
+ }
+ }
+
+ public class SmallAttributeSet
+ implements AttributeSet
+ {
+ final Object [] attrs;
+ public SmallAttributeSet(AttributeSet a)
+ {
+ if (a == null)
+ attrs = new Object[0];
+ else
+ {
+ int n = a.getAttributeCount();
+ int i = 0;
+ attrs = new Object[n * 2];
+ Enumeration e = a.getAttributeNames();
+ while (e.hasMoreElements())
+ {
+ Object name = e.nextElement();
+ attrs[i++] = name;
+ attrs[i++] = a.getAttribute(name);
+ }
+ }
+ }
+
+ public SmallAttributeSet(Object [] a)
+ {
+ if (a == null)
+ attrs = new Object[0];
+ else
+ {
+ attrs = new Object[a.length];
+ System.arraycopy(a, 0, attrs, 0, a.length);
+ }
+ }
+
+ public Object clone()
+ {
+ return new SmallAttributeSet(this.attrs);
+ }
+
+ public boolean containsAttribute(Object name, Object value)
+ {
+ for (int i = 0; i < attrs.length; i += 2)
+ {
+ if (attrs[i].equals(name) &&
+ attrs[i+1].equals(value))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean containsAttributes(AttributeSet a)
+ {
+ Enumeration e = a.getAttributeNames();
+ while (e.hasMoreElements())
+ {
+ Object name = e.nextElement();
+ Object val = a.getAttribute(name);
+ if (!containsAttribute(name, val))
+ return false;
+ }
+ return true;
+ }
+
+ public AttributeSet copyAttributes()
+ {
+ return (AttributeSet) clone();
+ }
+
+ public boolean equals(Object obj)
+ {
+ return
+ (obj instanceof SmallAttributeSet)
+ && this.isEqual((AttributeSet)obj);
+ }
+
+ public Object getAttribute(Object key)
+ {
+ for (int i = 0; i < attrs.length; i += 2)
+ {
+ if (attrs[i].equals(key))
+ return attrs[i+1];
+ }
+
+ Object p = getResolveParent();
+ if (p != null && p instanceof AttributeSet)
+ return (((AttributeSet)p).getAttribute(key));
+
+ return null;
+ }
+
+ public int getAttributeCount()
+ {
+ return attrs.length / 2;
+ }
+
+ public Enumeration getAttributeNames()
+ {
+ return new Enumeration()
+ {
+ int i = 0;
+ public boolean hasMoreElements()
+ {
+ return i < attrs.length;
+ }
+ public Object nextElement()
+ {
+ i += 2;
+ return attrs[i-2];
+ }
+ };
+ }
+
+ public AttributeSet getResolveParent()
+ {
+ return (AttributeSet) getAttribute(ResolveAttribute);
+ }
+
+ public int hashCode()
+ {
+ return java.util.Arrays.asList(attrs).hashCode();
+ }
+
+ public boolean isDefined(Object key)
+ {
+ for (int i = 0; i < attrs.length; i += 2)
+ {
+ if (attrs[i].equals(key))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isEqual(AttributeSet attr)
+ {
+ return attr != null
+ && attr.containsAttributes(this)
+ && this.containsAttributes(attr);
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("[StyleContext.SmallattributeSet:");
+ for (int i = 0; i < attrs.length; ++i)
+ {
+ sb.append(" (");
+ sb.append(attrs[i].toString());
+ sb.append("=");
+ sb.append(attrs[i+1].toString());
+ sb.append(")");
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+ }
+
+ // FIXME: official javadocs suggest that these might be more usefully
+ // implemented using a WeakHashMap, but not sure if that works most
+ // places or whether it really matters anyways.
+ //
+ // FIXME: also not sure if these tables ought to be static (singletons),
+ // shared across all StyleContexts. I think so, but it's not clear in
+ // docs. revert to non-shared if you think it matters.
+
+ /**
+ * The name of the default style.
+ */
+ public static final String DEFAULT_STYLE = "default";
+
+ /**
+ * The default style for this style context.
+ */
+ NamedStyle defaultStyle = new NamedStyle(DEFAULT_STYLE, null);
+
+ static Hashtable sharedAttributeSets = new Hashtable();
+ static Hashtable sharedFonts = new Hashtable();
+
+ static StyleContext defaultStyleContext = new StyleContext();
+ static final int compressionThreshold = 9;
+
+ EventListenerList listenerList;
+ Hashtable styleTable;
+
+ /**
+ * Creates a new instance of the style context. Add the default style
+ * to the style table.
+ */
+ public StyleContext()
+ {
+ listenerList = new EventListenerList();
+ styleTable = new Hashtable();
+ styleTable.put(DEFAULT_STYLE, defaultStyle);
+ }
+
+ protected SmallAttributeSet createSmallAttributeSet(AttributeSet a)
+ {
+ return new SmallAttributeSet(a);
+ }
+
+ protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
+ {
+ return new SimpleAttributeSet(a);
+ }
+
+ public void addChangeListener(ChangeListener listener)
+ {
+ listenerList.add(ChangeListener.class, listener);
+ }
+
+ public void removeChangeListener(ChangeListener listener)
+ {
+ listenerList.remove(ChangeListener.class, listener);
+ }
+
+ public ChangeListener[] getChangeListeners()
+ {
+ return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+ }
+
+ public Style addStyle(String name, Style parent)
+ {
+ Style newStyle = new NamedStyle(name, parent);
+ if (name != null)
+ styleTable.put(name, newStyle);
+ return newStyle;
+ }
+
+ public void removeStyle(String name)
+ {
+ styleTable.remove(name);
+ }
+
+ /**
+ * Get the style from the style table. If the passed name
+ * matches {@link #DEFAULT_STYLE}, returns the default style.
+ * Otherwise returns the previously defined style of
+ * <code>null</code> if the style with the given name is not defined.
+ *
+ * @param name the name of the style.
+ *
+ * @return the style with the given name or null if no such defined.
+ */
+ public Style getStyle(String name)
+ {
+ return (Style) styleTable.get(name);
+ }
+
+ /**
+ * Get the names of the style. The returned enumeration always
+ * contains at least one member, the default style.
+ */
+ public Enumeration getStyleNames()
+ {
+ return styleTable.keys();
+ }
+
+ //
+ // StyleContexts only understand the "simple" model of fonts present in
+ // pre-java2d systems: fonts are a family name, a size (integral number
+ // of points), and a mask of style parameters (plain, bold, italic, or
+ // bold|italic). We have an inner class here called SimpleFontSpec which
+ // holds such triples.
+ //
+ // A SimpleFontSpec can be built for *any* AttributeSet because the size,
+ // family, and style keys in an AttributeSet have default values (defined
+ // over in StyleConstants).
+ //
+ // We keep a static cache mapping SimpleFontSpecs to java.awt.Fonts, so
+ // that we reuse Fonts between styles and style contexts.
+ //
+
+ private static class SimpleFontSpec
+ {
+ String family;
+ int style;
+ int size;
+ public SimpleFontSpec(String family,
+ int style,
+ int size)
+ {
+ this.family = family;
+ this.style = style;
+ this.size = size;
+ }
+ public boolean equals(Object obj)
+ {
+ return (obj != null)
+ && (obj instanceof SimpleFontSpec)
+ && (((SimpleFontSpec)obj).family.equals(this.family))
+ && (((SimpleFontSpec)obj).style == this.style)
+ && (((SimpleFontSpec)obj).size == this.size);
+ }
+ public int hashCode()
+ {
+ return family.hashCode() + style + size;
+ }
+ }
+
+ public Font getFont(AttributeSet attr)
+ {
+ String family = StyleConstants.getFontFamily(attr);
+ int style = Font.PLAIN;
+ if (StyleConstants.isBold(attr))
+ style += Font.BOLD;
+ if (StyleConstants.isItalic(attr))
+ style += Font.ITALIC;
+ int size = StyleConstants.getFontSize(attr);
+ return getFont(family, style, size);
+ }
+
+ public Font getFont(String family, int style, int size)
+ {
+ SimpleFontSpec spec = new SimpleFontSpec(family, style, size);
+ if (sharedFonts.containsKey(spec))
+ return (Font) sharedFonts.get(spec);
+ else
+ {
+ Font tmp = new Font(family, style, size);
+ sharedFonts.put(spec, tmp);
+ return tmp;
+ }
+ }
+
+ public FontMetrics getFontMetrics(Font f)
+ {
+ return Toolkit.getDefaultToolkit().getFontMetrics(f);
+ }
+
+ public Color getForeground(AttributeSet a)
+ {
+ return StyleConstants.getForeground(a);
+ }
+
+ public Color getBackground(AttributeSet a)
+ {
+ return StyleConstants.getBackground(a);
+ }
+
+ protected int getCompressionThreshold()
+ {
+ return compressionThreshold;
+ }
+
+ public static StyleContext getDefaultStyleContext()
+ {
+ return defaultStyleContext;
+ }
+
+ public AttributeSet addAttribute(AttributeSet old, Object name, Object value)
+ {
+ if (old instanceof MutableAttributeSet)
+ {
+ ((MutableAttributeSet)old).addAttribute(name, value);
+ return old;
+ }
+ else
+ {
+ MutableAttributeSet mutable = createLargeAttributeSet(old);
+ mutable.addAttribute(name, value);
+ if (mutable.getAttributeCount() >= getCompressionThreshold())
+ return mutable;
+ else
+ {
+ SmallAttributeSet small = createSmallAttributeSet(mutable);
+ if (sharedAttributeSets.containsKey(small))
+ small = (SmallAttributeSet) sharedAttributeSets.get(small);
+ else
+ sharedAttributeSets.put(small,small);
+ return small;
+ }
+ }
+ }
+
+ public AttributeSet addAttributes(AttributeSet old, AttributeSet attributes)
+ {
+ if (old instanceof MutableAttributeSet)
+ {
+ ((MutableAttributeSet)old).addAttributes(attributes);
+ return old;
+ }
+ else
+ {
+ MutableAttributeSet mutable = createLargeAttributeSet(old);
+ mutable.addAttributes(attributes);
+ if (mutable.getAttributeCount() >= getCompressionThreshold())
+ return mutable;
+ else
+ {
+ SmallAttributeSet small = createSmallAttributeSet(mutable);
+ if (sharedAttributeSets.containsKey(small))
+ small = (SmallAttributeSet) sharedAttributeSets.get(small);
+ else
+ sharedAttributeSets.put(small,small);
+ return small;
+ }
+ }
+ }
+
+ public AttributeSet getEmptySet()
+ {
+ AttributeSet e = createSmallAttributeSet(null);
+ if (sharedAttributeSets.containsKey(e))
+ e = (AttributeSet) sharedAttributeSets.get(e);
+ else
+ sharedAttributeSets.put(e, e);
+ return e;
+ }
+
+ public void reclaim(AttributeSet attributes)
+ {
+ if (sharedAttributeSets.containsKey(attributes))
+ sharedAttributeSets.remove(attributes);
+ }
+
+ public AttributeSet removeAttribute(AttributeSet old, Object name)
+ {
+ if (old instanceof MutableAttributeSet)
+ {
+ ((MutableAttributeSet)old).removeAttribute(name);
+ if (old.getAttributeCount() < getCompressionThreshold())
+ {
+ SmallAttributeSet small = createSmallAttributeSet(old);
+ if (!sharedAttributeSets.containsKey(small))
+ sharedAttributeSets.put(small,small);
+ old = (AttributeSet) sharedAttributeSets.get(small);
+ }
+ return old;
+ }
+ else
+ {
+ MutableAttributeSet mutable = createLargeAttributeSet(old);
+ mutable.removeAttribute(name);
+ SmallAttributeSet small = createSmallAttributeSet(mutable);
+ if (sharedAttributeSets.containsKey(small))
+ small = (SmallAttributeSet) sharedAttributeSets.get(small);
+ else
+ sharedAttributeSets.put(small,small);
+ return small;
+ }
+ }
+
+ public AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes)
+ {
+ return removeAttributes(old, attributes.getAttributeNames());
+ }
+
+ public AttributeSet removeAttributes(AttributeSet old, Enumeration names)
+ {
+ if (old instanceof MutableAttributeSet)
+ {
+ ((MutableAttributeSet)old).removeAttributes(names);
+ if (old.getAttributeCount() < getCompressionThreshold())
+ {
+ SmallAttributeSet small = createSmallAttributeSet(old);
+ if (!sharedAttributeSets.containsKey(small))
+ sharedAttributeSets.put(small,small);
+ old = (AttributeSet) sharedAttributeSets.get(small);
+ }
+ return old;
+ }
+ else
+ {
+ MutableAttributeSet mutable = createLargeAttributeSet(old);
+ mutable.removeAttributes(names);
+ SmallAttributeSet small = createSmallAttributeSet(mutable);
+ if (sharedAttributeSets.containsKey(small))
+ small = (SmallAttributeSet) sharedAttributeSets.get(small);
+ else
+ sharedAttributeSets.put(small,small);
+ return small;
+ }
+ }
+
+
+ // FIXME: there's some sort of quasi-serialization stuff in here which I
+ // have left incomplete; I'm not sure I understand the intent properly.
+
+ public static Object getStaticAttribute(Object key)
+ {
+ throw new InternalError("not implemented");
+ }
+
+ public static Object getStaticAttributeKey(Object key)
+ {
+ throw new InternalError("not implemented");
+ }
+
+ public static void readAttributeSet(ObjectInputStream in, MutableAttributeSet a)
+ throws ClassNotFoundException, IOException
+ {
+ throw new InternalError("not implemented");
+ }
+
+ public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
+ throws IOException
+ {
+ throw new InternalError("not implemented");
+ }
+
+ public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
+ throws ClassNotFoundException, IOException
+ {
+ throw new InternalError("not implemented");
+ }
+
+ public void writeAttributes(ObjectOutputStream out, AttributeSet a)
+ throws IOException
+ {
+ throw new InternalError("not implemented");
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/StyledDocument.java b/libjava/classpath/javax/swing/text/StyledDocument.java
new file mode 100644
index 00000000000..ea277540f23
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/StyledDocument.java
@@ -0,0 +1,145 @@
+/* StyledDcoument.java --
+ Copyright (C) 2002, 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.Font;
+
+/**
+ * StyledDocument
+ * @author Andrew Selkirk
+ * @version 1.0
+ */
+public interface StyledDocument extends Document {
+
+ //-------------------------------------------------------------
+ // Methods ----------------------------------------------------
+ //-------------------------------------------------------------
+
+ /**
+ * addStyle
+ * @param nm TODO
+ * @param rent TODO
+ * @returns Style
+ */
+ Style addStyle(String nm, Style parent);
+
+ /**
+ * removeStyle
+ * @param nm TODO
+ */
+ void removeStyle(String nm);
+
+ /**
+ * getStyle
+ * @param nm TODO
+ * @returns Style
+ */
+ Style getStyle(String nm);
+
+ /**
+ * setCharacterAttributes
+ * @param offset TODO
+ * @param length TODO
+ * @param set TODO
+ * @param replace TODO
+ */
+ void setCharacterAttributes(int offset, int length,
+ AttributeSet set, boolean replace);
+
+ /**
+ * setParagraphAttributes
+ * @param offset TODO
+ * @param length TODO
+ * @param set TODO
+ * @param replace TODO
+ */
+ void setParagraphAttributes(int offset, int length,
+ AttributeSet set, boolean replace);
+
+ /**
+ * getLogicalStyle
+ * @param position TODO
+ * @returns Style
+ */
+ Style getLogicalStyle(int position);
+
+ /**
+ * setLogicalStyle
+ * @param position TODO
+ * @param style TODO
+ */
+ void setLogicalStyle(int position, Style style);
+
+ /**
+ * getParagraphElement
+ * @param position TODO
+ * @returns Element
+ */
+ Element getParagraphElement(int position);
+
+ /**
+ * getCharacterElement
+ * @param position TODO
+ * @returns Element
+ */
+ Element getCharacterElement(int position);
+
+ /**
+ * getForeground
+ * @param set TODO
+ * @returns Color
+ */
+ Color getForeground(AttributeSet set);
+
+ /**
+ * getBackground
+ * @param set TODO
+ * @returns Color
+ */
+ Color getBackground(AttributeSet set);
+
+ /**
+ * getFont
+ * @param set TODO
+ * @returns Font
+ */
+ Font getFont(AttributeSet set);
+
+
+} // StyledDocument
diff --git a/libjava/classpath/javax/swing/text/StyledEditorKit.java b/libjava/classpath/javax/swing/text/StyledEditorKit.java
new file mode 100644
index 00000000000..459f2438679
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/StyledEditorKit.java
@@ -0,0 +1,503 @@
+/* StyledEditorKit.java --
+ Copyright (C) 2002, 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.event.ActionEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.Serializable;
+
+import javax.swing.Action;
+import javax.swing.JEditorPane;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+
+/**
+ * StyledEditorKit
+ *
+ * @author Andrew Selkirk
+ */
+public class StyledEditorKit extends DefaultEditorKit
+{
+ private static final long serialVersionUID = 7002391892985555948L;
+
+ /**
+ * UnderlineAction
+ */
+ public static class UnderlineAction extends StyledEditorKit.StyledTextAction
+ {
+ /**
+ * Constructor UnderlineAction
+ */
+ public UnderlineAction()
+ {
+ super("TODO");
+ // TODO
+ }
+
+ /**
+ * actionPerformed
+ * @param event TODO
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ // TODO
+ }
+ }
+
+ /**
+ * ItalicAction
+ */
+ public static class ItalicAction extends StyledEditorKit.StyledTextAction
+ {
+ /**
+ * Constructor ItalicAction
+ */
+ public ItalicAction()
+ {
+ super("TODO");
+ // TODO
+ }
+
+ /**
+ * actionPerformed
+ * @param event TODO
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ // TODO
+ }
+ }
+
+ /**
+ * BoldAction
+ */
+ public static class BoldAction extends StyledEditorKit.StyledTextAction
+ {
+ /**
+ * Constructor BoldAction
+ */
+ public BoldAction()
+ {
+ super("TODO");
+ // TODO
+ }
+
+ /**
+ * actionPerformed
+ * @param event TODO
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ // TODO
+ }
+ }
+
+ /**
+ * AlignmentAction
+ */
+ public static class AlignmentAction extends StyledEditorKit.StyledTextAction
+ {
+ /**
+ * a
+ */
+ private int a;
+
+ /**
+ * Constructor AlignmentAction
+ * @param nm TODO
+ * @param a TODO
+ */
+ public AlignmentAction(String nm, int a)
+ {
+ super("TODO");
+ // TODO
+ }
+
+ /**
+ * actionPerformed
+ * @param event TODO
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ // TODO
+ }
+ }
+
+ /**
+ * ForegroundAction
+ */
+ public static class ForegroundAction extends StyledEditorKit.StyledTextAction
+ {
+ /**
+ * fg
+ */
+ private Color fg;
+
+ /**
+ * Constructor ForegroundAction
+ * @param nm TODO
+ * @param fg TODO
+ */
+ public ForegroundAction(String nm, Color fg)
+ {
+ super("TODO");
+ // TODO
+ }
+
+ /**
+ * actionPerformed
+ * @param event TODO
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ // TODO
+ }
+ }
+
+ /**
+ * FontSizeAction
+ */
+ public static class FontSizeAction extends StyledEditorKit.StyledTextAction
+ {
+ /**
+ * size
+ */
+ private int size;
+
+ /**
+ * Constructor FontSizeAction
+ * @param nm TODO
+ * @param size TODO
+ */
+ public FontSizeAction(String nm, int size)
+ {
+ super("TODO");
+ // TODO
+ }
+
+ /**
+ * actionPerformed
+ * @param event TODO
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ // TODO
+ }
+ }
+
+ /**
+ * FontFamilyAction
+ */
+ public static class FontFamilyAction extends StyledEditorKit.StyledTextAction
+ {
+ /**
+ * family
+ */
+ private String family;
+
+ /**
+ * Constructor FontFamilyAction
+ * @param nm TODO
+ * @param family TODO
+ */
+ public FontFamilyAction(String nm, String family)
+ {
+ super("TODO");
+ // TODO
+ }
+
+ /**
+ * actionPerformed
+ * @param event TODO
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ // TODO
+ }
+ }
+
+ /**
+ * StyledTextAction
+ */
+ public abstract static class StyledTextAction extends TextAction
+ {
+ /**
+ * Constructor StyledTextAction
+ * @param nm TODO
+ */
+ public StyledTextAction(String nm)
+ {
+ super(nm);
+ // TODO
+ }
+
+ /**
+ * getEditor
+ * @param event TODO
+ * @returns JEditorPane
+ */
+ protected final JEditorPane getEditor(ActionEvent event)
+ {
+ return null; // TODO
+ }
+
+ /**
+ * setCharacterAttributes
+ * @param value0 TODO
+ * @param value1 TODO
+ * @param value2 TODO
+ */
+ protected final void setCharacterAttributes(JEditorPane value0,
+ AttributeSet value1,
+ boolean value2)
+ {
+ // TODO
+ }
+
+ /**
+ * getStyledDocument
+ * @param value0 TODO
+ * @returns StyledDocument
+ */
+ protected final StyledDocument getStyledDocument(JEditorPane value0)
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getStyledEditorKit
+ * @param value0 TODO
+ * @returns StyledEditorKit
+ */
+ protected final StyledEditorKit getStyledEditorKit(JEditorPane value0)
+ {
+ return null; // TODO
+ }
+
+ /**
+ * setParagraphAttributes
+ * @param value0 TODO
+ * @param value1 TODO
+ * @param value2 TODO
+ */
+ protected final void setParagraphAttributes(JEditorPane value0,
+ AttributeSet value1,
+ boolean value2)
+ {
+ // TODO
+ }
+ }
+
+ /**
+ * StyledViewFactory
+ */
+ static class StyledViewFactory
+ implements ViewFactory
+ {
+ /**
+ * Constructor StyledViewFactory
+ */
+ StyledViewFactory()
+ {
+ // TODO
+ }
+
+ /**
+ * create
+ * @param value0 TODO
+ * @returns View
+ */
+ public View create(Element value0)
+ {
+ return null; // TODO
+ }
+ }
+
+ /**
+ * AttributeTracker
+ */
+ class AttributeTracker
+ implements CaretListener, PropertyChangeListener, Serializable
+ {
+ /**
+ * Constructor AttributeTracker
+ * @param value0 TODO
+ */
+ AttributeTracker(StyledEditorKit value0)
+ {
+ // TODO
+ }
+
+ /**
+ * updateInputAttributes
+ * @param value0 TODO
+ * @param value1 TODO
+ * @param value2 TODO
+ */
+ void updateInputAttributes(int value0, int value1, JTextComponent value2)
+ {
+ // TODO
+ }
+
+ /**
+ * propertyChange
+ * @param value0 TODO
+ */
+ public void propertyChange(PropertyChangeEvent value0)
+ {
+ // TODO
+ }
+
+ /**
+ * caretUpdate
+ * @param value0 TODO
+ */
+ public void caretUpdate(CaretEvent value0)
+ {
+ // TODO
+ }
+ }
+
+ /**
+ * currentRun
+ */
+ Element currentRun;
+
+ /**
+ * currentParagraph
+ */
+ Element currentParagraph;
+
+ /**
+ * inputAttributes
+ */
+ MutableAttributeSet inputAttributes;
+
+ /**
+ * Constructor StyledEditorKit
+ */
+ public StyledEditorKit()
+ {
+ // TODO
+ }
+
+ /**
+ * clone
+ * @returns Object
+ */
+ public Object clone()
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getActions
+ * @returns Action[]
+ */
+ public Action[] getActions()
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getInputAttributes
+ * @returns MutableAttributeSet
+ */
+ public MutableAttributeSet getInputAttributes()
+ {
+ return null; // TODO
+ }
+
+ /**
+ * getCharacterAttributeRun
+ * @returns Element
+ */
+ public Element getCharacterAttributeRun()
+ {
+ return null; // TODO
+ }
+
+ /**
+ * createDefaultDocument
+ * @returns Document
+ */
+ public Document createDefaultDocument()
+ {
+ return null; // TODO
+ }
+
+ /**
+ * install
+ * @param component TODO
+ */
+ public void install(JEditorPane component)
+ {
+ // TODO
+ }
+
+ /**
+ * deinstall
+ * @param component TODO
+ */
+ public void deinstall(JEditorPane component)
+ {
+ // TODO
+ }
+
+ /**
+ * getViewFactory
+ * @returns ViewFactory
+ */
+ public ViewFactory getViewFactory()
+ {
+ return null; // TODO
+ }
+
+ /**
+ * createInputAttributes
+ * @param element TODO
+ * @param set TODO
+ */
+ protected void createInputAttributes(Element element, MutableAttributeSet set)
+ {
+ // TODO
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/TabExpander.java b/libjava/classpath/javax/swing/text/TabExpander.java
new file mode 100644
index 00000000000..d70dd4604e5
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/TabExpander.java
@@ -0,0 +1,43 @@
+/* TabExpander.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. */
+
+package javax.swing.text;
+
+public interface TabExpander
+{
+ float nextTabStop(float x, int tabOffset);
+} \ No newline at end of file
diff --git a/libjava/classpath/javax/swing/text/TabSet.java b/libjava/classpath/javax/swing/text/TabSet.java
new file mode 100644
index 00000000000..146f545aac7
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/TabSet.java
@@ -0,0 +1,102 @@
+/* TabSet.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. */
+
+package javax.swing.text;
+
+import java.io.Serializable;
+
+public class TabSet implements Serializable
+{
+ TabStop[] tabs;
+
+ public TabSet(TabStop[] t)
+ {
+ tabs = t;
+ }
+
+ public TabStop getTab(int i)
+ {
+ return tabs[i];
+ }
+
+ public TabStop getTabAfter(float location)
+ {
+ int idx = getTabIndexAfter(location);
+ if (idx == -1)
+ return null;
+ else
+ return tabs[idx];
+ }
+
+ public int getTabCount()
+ {
+ return tabs.length;
+ }
+
+ public int getTabIndex(TabStop tab)
+ {
+ for (int i = 0; i < tabs.length; ++i)
+ if (tabs[i] == tab)
+ return i;
+ return -1;
+ }
+
+ public int getTabIndexAfter(float location)
+ {
+ int idx = -1;
+ for (int i = 0; i < tabs.length; ++i)
+ {
+ if (location < tabs[i].getPosition())
+ idx = i;
+ }
+ return idx;
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("[");
+ for (int i = 0; i < tabs.length; ++i)
+ {
+ if (i != 0)
+ sb.append(" - ");
+ sb.append(tabs[i].toString());
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/TabStop.java b/libjava/classpath/javax/swing/text/TabStop.java
new file mode 100644
index 00000000000..032da8bca46
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/TabStop.java
@@ -0,0 +1,133 @@
+/* TabSet.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. */
+
+package javax.swing.text;
+
+import java.io.Serializable;
+
+public class TabStop implements Serializable
+{
+ public static final int ALIGN_LEFT = 0;
+ public static final int ALIGN_RIGHT = 1;
+ public static final int ALIGN_CENTER = 2;
+ public static final int ALIGN_DECIMAL = 4;
+ public static final int ALIGN_BAR = 5;
+
+ public static final int LEAD_NONE = 0;
+ public static final int LEAD_DOTS = 1;
+ public static final int LEAD_HYPHENS = 2;
+ public static final int LEAD_UNDERLINE = 3;
+ public static final int LEAD_THICKLINE = 4;
+ public static final int LEAD_EQUALS = 5;
+
+ float pos;
+ int align;
+ int leader;
+
+ public TabStop(float pos)
+ {
+ this(pos, ALIGN_LEFT, LEAD_NONE);
+ }
+
+ public TabStop(float pos, int align, int leader)
+ {
+ this.pos = pos;
+ this.align = align;
+ this.leader = leader;
+ }
+
+ public boolean equals(Object other)
+ {
+ return (other != null)
+ && (other instanceof TabStop)
+ && (((TabStop)other).getPosition() == this.getPosition())
+ && (((TabStop)other).getLeader() == this.getLeader())
+ && (((TabStop)other).getAlignment() == this.getAlignment());
+ }
+
+ public int getAlignment()
+ {
+ return align;
+ }
+
+ public int getLeader()
+ {
+ return leader;
+ }
+
+ public float getPosition()
+ {
+ return pos;
+ }
+
+ public int hashCode()
+ {
+ return (int) pos + (int) leader + (int) align;
+ }
+
+ public String toString()
+ {
+ String prefix = "";
+ switch (align)
+ {
+ case ALIGN_LEFT:
+ prefix = "left ";
+ break;
+ case ALIGN_RIGHT:
+ prefix = "right ";
+ break;
+
+ case ALIGN_CENTER:
+ prefix = "center ";
+ break;
+
+ case ALIGN_DECIMAL:
+ prefix = "decimal ";
+ break;
+
+ case ALIGN_BAR:
+ prefix = "bar ";
+ break;
+
+ default:
+ break;
+ }
+
+ return (prefix + "tab @" + pos + ((leader == LEAD_NONE) ? "" : "(w/leaders)"));
+ }
+
+}
diff --git a/libjava/classpath/javax/swing/text/TabableView.java b/libjava/classpath/javax/swing/text/TabableView.java
new file mode 100644
index 00000000000..2a96ea94d81
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/TabableView.java
@@ -0,0 +1,44 @@
+/* TabableView.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. */
+
+package javax.swing.text;
+
+public interface TabableView
+{
+ float getPartialSpan(int p0, int p1);
+ float getTabbedSpan(float x, TabExpander expander);
+}
diff --git a/libjava/classpath/javax/swing/text/TextAction.java b/libjava/classpath/javax/swing/text/TextAction.java
new file mode 100644
index 00000000000..8588e3cd202
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/TextAction.java
@@ -0,0 +1,111 @@
+/* TextAction.java --
+ Copyright (C) 2002, 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.event.ActionEvent;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+
+/**
+ * TextAction
+ * @author Andrew Selkirk
+ */
+public abstract class TextAction extends AbstractAction
+{
+ /**
+ * Constructor TextAction
+ * @param name TODO
+ */
+ public TextAction(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Returns the <code>JTextComponent</code> object associated with the given
+ * <code>ActionEvent</code>. If the source of the event is not a
+ * <code>JTextComponent</code> the currently focused text component is returned.
+ *
+ * @param event the action event
+ *
+ * @return the <code>JTextComponent</code>
+ */
+ protected final JTextComponent getTextComponent(ActionEvent event)
+ {
+ if (event.getSource() instanceof JTextComponent)
+ return (JTextComponent) event.getSource();
+
+ return getFocusedComponent();
+ }
+
+ /**
+ * Creates a new array of <code>Action</code> containing both given arrays.
+ *
+ * @param list1 the first action array
+ * @param list2 the second action array
+ *
+ * @return the augmented array of actions
+ */
+ public static final Action[] augmentList(Action[] list1, Action[] list2)
+ {
+ HashSet actionSet = new HashSet();
+
+ for (int i = 0; i < list1.length; ++i)
+ actionSet.add(list1[i]);
+
+ for (int i = 0; i < list2.length; ++i)
+ actionSet.add(list2[i]);
+
+ ArrayList list = new ArrayList(actionSet);
+ return (Action[]) list.toArray(new Action[actionSet.size()]);
+ }
+
+ /**
+ * Returns the current focused <code>JTextComponent</code> object.
+ *
+ * @return the <code>JTextComponent</code>
+ */
+ protected final JTextComponent getFocusedComponent()
+ {
+ return null; // TODO
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/Utilities.java b/libjava/classpath/javax/swing/text/Utilities.java
new file mode 100644
index 00000000000..d40408ddc3f
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/Utilities.java
@@ -0,0 +1,198 @@
+/* Utilities.java --
+ Copyright (C) 2004, 2005 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.FontMetrics;
+import java.awt.Graphics;
+
+/**
+ * A set of utilities to deal with text. This is used by several other classes
+ * inside this package.
+ *
+ * @author Roman Kennke (roman@ontographics.com)
+ */
+public class Utilities
+{
+ /**
+ * The length of the char buffer that holds the characters to be drawn.
+ */
+ private static final int BUF_LENGTH = 64;
+
+ /**
+ * Creates a new <code>Utilities</code> object.
+ */
+ public Utilities()
+ {
+ // Nothing to be done here.
+ }
+
+ /**
+ * Draws the given text segment. Contained tabs and newline characters
+ * are taken into account. Tabs are expanded using the
+ * specified {@link TabExpander}.
+ *
+ * @param s the text fragment to be drawn.
+ * @param x the x position for drawing.
+ * @param y the y position for drawing.
+ * @param g the {@link Graphics} context for drawing.
+ * @param e the {@link TabExpander} which specifies the Tab-expanding
+ * technique.
+ * @param startOffset starting offset in the text.
+ * @return the x coordinate at the end of the drawn text.
+ */
+ public static final int drawTabbedText(Segment s, int x, int y, Graphics g,
+ TabExpander e, int startOffset)
+ {
+ // This buffers the chars to be drawn.
+ char[] buffer = s.array;
+
+
+ // The current x and y pixel coordinates.
+ int pixelX = x;
+ int pixelY = y;
+
+ // The font metrics of the current selected font.
+ FontMetrics metrics = g.getFontMetrics();
+ int ascent = metrics.getAscent();
+
+ int pixelWidth = 0;
+ int pos = s.offset;
+ int len = 0;
+
+ for (int offset = s.offset; offset < (s.offset + s.count); ++offset)
+ {
+ char c = buffer[offset];
+ if (c == '\t' || c == '\n')
+ {
+ if (len > 0) {
+ g.drawChars(buffer, pos, len, pixelX, pixelY + ascent);
+ pixelX += pixelWidth;
+ pixelWidth = 0;
+ }
+ pos = offset+1;
+ len = 0;
+ }
+
+ switch (c)
+ {
+ case '\t':
+ // In case we have a tab, we just 'jump' over the tab.
+ // When we have no tab expander we just use the width of ' '.
+ if (e != null)
+ pixelX = (int) e.nextTabStop((float) pixelX,
+ startOffset + offset - s.offset);
+ else
+ pixelX += metrics.charWidth(' ');
+ break;
+ case '\n':
+ // In case we have a newline, we must jump to the next line.
+ pixelY += metrics.getHeight();
+ pixelX = x;
+ break;
+ default:
+ ++len;
+ pixelWidth += metrics.charWidth(buffer[offset]);
+ break;
+ }
+ }
+
+ if (len > 0)
+ g.drawChars(buffer, pos, len, pixelX, pixelY + ascent);
+
+ return pixelX;
+ }
+
+ /**
+ * Determines the width, that the given text <code>s</code> would take
+ * if it was printed with the given {@link java.awt.FontMetrics} on the
+ * specified screen position.
+ * @param s the text fragment
+ * @param metrics the font metrics of the font to be used
+ * @param x the x coordinate of the point at which drawing should be done
+ * @param e the {@link TabExpander} to be used
+ * @param startOffset the index in <code>s</code> where to start
+ * @returns the width of the given text s. This takes tabs and newlines
+ * into account.
+ */
+ public static final int getTabbedTextWidth(Segment s, FontMetrics metrics,
+ int x, TabExpander e,
+ int startOffset)
+ {
+ // This buffers the chars to be drawn.
+ char[] buffer = s.array;
+
+ // The current x coordinate.
+ int pixelX = x;
+
+ // The current maximum width.
+ int maxWidth = 0;
+
+ for (int offset = s.offset; offset < (s.offset + s.count); ++offset)
+ {
+ switch (buffer[offset])
+ {
+ case '\t':
+ // In case we have a tab, we just 'jump' over the tab.
+ // When we have no tab expander we just use the width of 'm'.
+ if (e != null)
+ pixelX = (int) e.nextTabStop((float) pixelX,
+ startOffset + offset - s.offset);
+ else
+ pixelX += metrics.charWidth(' ');
+ break;
+ case '\n':
+ // In case we have a newline, we must 'draw'
+ // the buffer and jump on the next line.
+ pixelX += metrics.charWidth(buffer[offset]);
+ maxWidth = Math.max(maxWidth, pixelX - x);
+ pixelX = x;
+ break;
+ default:
+ // Here we draw the char.
+ pixelX += metrics.charWidth(buffer[offset]);
+ break;
+ }
+ }
+
+ // Take the last line into account.
+ maxWidth = Math.max(maxWidth, pixelX - x);
+
+ return maxWidth;
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/View.java b/libjava/classpath/javax/swing/text/View.java
new file mode 100644
index 00000000000..4d9ed7b3122
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/View.java
@@ -0,0 +1,463 @@
+/* View.java --
+ Copyright (C) 2002, 2004, 2005 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.Container;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+import javax.swing.JComponent;
+import javax.swing.SwingConstants;
+import javax.swing.event.DocumentEvent;
+
+public abstract class View implements SwingConstants
+{
+ public static final int BadBreakWeight = 0;
+ public static final int ExcellentBreakWeight = 2000;
+ public static final int ForcedBreakWeight = 3000;
+ public static final int GoodBreakWeight = 1000;
+
+ public static final int X_AXIS = 0;
+ public static final int Y_AXIS = 1;
+
+ private float width, height;
+ private Element elt;
+ private View parent;
+
+ /**
+ * The child views.
+ */
+ View[] children;
+
+ /**
+ * Creates a new <code>View</code> instance.
+ *
+ * @param elem an <code>Element</code> value
+ */
+ public View(Element elem)
+ {
+ elt = elem;
+ children = new View[0];
+ }
+
+ public abstract void paint(Graphics g, Shape s);
+
+ public void setParent(View parent)
+ {
+ this.parent = parent;
+ }
+
+ public View getParent()
+ {
+ return parent;
+ }
+
+ public Container getContainer()
+ {
+ View parent = getParent();
+ return parent != null ? parent.getContainer() : null;
+ }
+
+ public Document getDocument()
+ {
+ return getElement().getDocument();
+ }
+
+ public Element getElement()
+ {
+ return elt;
+ }
+
+ public abstract float getPreferredSpan(int axis);
+
+ public int getResizeWeight(int axis)
+ {
+ return 0;
+ }
+
+ public float getMaximumSpan(int axis)
+ {
+ if (getResizeWeight(axis) <= 0)
+ return getPreferredSpan(axis);
+
+ return Integer.MAX_VALUE;
+ }
+
+ public float getMinimumSpan(int axis)
+ {
+ if (getResizeWeight(axis) <= 0)
+ return getPreferredSpan(axis);
+
+ return Integer.MAX_VALUE;
+ }
+
+ public void setSize(float width, float height)
+ {
+ // The default implementation does nothing.
+ }
+
+ public float getAlignment(int axis)
+ {
+ return 0.5f;
+ }
+
+ public AttributeSet getAttributes()
+ {
+ return getElement().getAttributes();
+ }
+
+ public boolean isVisible()
+ {
+ return true;
+ }
+
+ public int getViewCount()
+ {
+ return 0;
+ }
+
+ public View getView(int index)
+ {
+ return null;
+ }
+
+ public ViewFactory getViewFactory()
+ {
+ View parent = getParent();
+ return parent != null ? parent.getViewFactory() : null;
+ }
+
+ public void replace(int offset, int length, View[] views)
+ {
+ // Default implementation does nothing.
+ }
+
+ public void insert(int offset, View view)
+ {
+ View[] array = { view };
+ replace(offset, 1, array);
+ }
+
+ public void append(View view)
+ {
+ View[] array = { view };
+ replace(getViewCount(), 1, array);
+ }
+
+ public void removeAll()
+ {
+ replace(0, getViewCount(), null);
+ }
+
+ public void remove(int index)
+ {
+ replace(index, 1, null);
+ }
+
+ public View createFragment(int p0, int p1)
+ {
+ // The default implementation doesn't support fragmentation.
+ return this;
+ }
+
+ public int getStartOffset()
+ {
+ return getElement().getStartOffset();
+ }
+
+ public int getEndOffset()
+ {
+ return getElement().getEndOffset();
+ }
+
+ public Shape getChildAllocation(int index, Shape a)
+ {
+ return null;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public int getViewIndex(float x, float y, Shape allocation)
+ {
+ return -1;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public String getToolTipText(float x, float y, Shape allocation)
+ {
+ int index = getViewIndex(x, y, allocation);
+
+ if (index < -1)
+ return null;
+
+ Shape childAllocation = getChildAllocation(index, allocation);
+
+ if (childAllocation.getBounds().contains(x, y))
+ return getView(index).getToolTipText(x, y, childAllocation);
+
+ return null;
+ }
+
+ /**
+ * @since 1.3
+ */
+ public Graphics getGraphics()
+ {
+ return getContainer().getGraphics();
+ }
+
+ public void preferenceChanged(View child, boolean width, boolean height)
+ {
+ if (parent != null)
+ parent.preferenceChanged(this, width, height);
+ else
+ ((JComponent) getContainer()).revalidate();
+ }
+
+ public int getBreakWeight(int axis, float pos, float len)
+ {
+ return BadBreakWeight;
+ }
+
+ public View breakView(int axis, int offset, float pos, float len)
+ {
+ return this;
+ }
+
+ /**
+ * @since 1.3
+ */
+ public int getViewIndex(int pos, Position.Bias b)
+ {
+ return -1;
+ }
+
+ /**
+ * Receive notification about an insert update to the text model.
+ *
+ * The default implementation of this method does the following:
+ * <ul>
+ * <li>Call {@link #updateChildren} if the element that this view is
+ * responsible for has changed. This makes sure that the children can
+ * correctly represent the model.<li>
+ * <li>Call {@link #forwardUpdate}. This forwards the DocumentEvent to
+ * the child views.<li>
+ * <li>Call {@link #updateLayout}. Gives the view a chance to either
+ * repair its layout, reschedule layout or do nothing at all.</li>
+ * </ul>
+ *
+ * @param ev the DocumentEvent that describes the change
+ * @param shape the shape of the view
+ * @param vf the ViewFactory for creating child views
+ */
+ public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
+ {
+ Element el = getElement();
+ DocumentEvent.ElementChange ec = ev.getChange(el);
+ if (ec != null)
+ updateChildren(ec, ev, vf);
+ forwardUpdate(ec, ev, shape, vf);
+ updateLayout(ec, ev, shape);
+ }
+
+ /**
+ * Receive notification about a remove update to the text model.
+ *
+ * The default implementation of this method does the following:
+ * <ul>
+ * <li>Call {@link #updateChildren} if the element that this view is
+ * responsible for has changed. This makes sure that the children can
+ * correctly represent the model.<li>
+ * <li>Call {@link #forwardUpdate}. This forwards the DocumentEvent to
+ * the child views.<li>
+ * <li>Call {@link #updateLayout}. Gives the view a chance to either
+ * repair its layout, reschedule layout or do nothing at all.</li>
+ * </ul>
+ *
+ * @param ev the DocumentEvent that describes the change
+ * @param shape the shape of the view
+ * @param vf the ViewFactory for creating child views
+ */
+ public void removeUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
+ {
+ Element el = getElement();
+ DocumentEvent.ElementChange ec = ev.getChange(el);
+ if (ec != null)
+ updateChildren(ec, ev, vf);
+ forwardUpdate(ec, ev, shape, vf);
+ updateLayout(ec, ev, shape);
+ }
+
+ /**
+ * Receive notification about a change update to the text model.
+ *
+ * The default implementation of this method does the following:
+ * <ul>
+ * <li>Call {@link #updateChildren} if the element that this view is
+ * responsible for has changed. This makes sure that the children can
+ * correctly represent the model.<li>
+ * <li>Call {@link #forwardUpdate}. This forwards the DocumentEvent to
+ * the child views.<li>
+ * <li>Call {@link #updateLayout}. Gives the view a chance to either
+ * repair its layout, reschedule layout or do nothing at all.</li>
+ * </ul>
+ *
+ * @param ev the DocumentEvent that describes the change
+ * @param shape the shape of the view
+ * @param vf the ViewFactory for creating child views
+ */
+ public void changedUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
+ {
+ Element el = getElement();
+ DocumentEvent.ElementChange ec = ev.getChange(el);
+ if (ec != null)
+ updateChildren(ec, ev, vf);
+ forwardUpdate(ec, ev, shape, vf);
+ updateLayout(ec, ev, shape);
+ }
+
+ /**
+ * Updates the list of children that is returned by {@link #getView}
+ * and {@link #getViewCount}.
+ *
+ * Element that are specified as beeing added in the ElementChange record are
+ * assigned a view for using the ViewFactory. Views of Elements that
+ * are specified as beeing removed are removed from the list.
+ *
+ * @param ec the ElementChange record that describes the change of the
+ * element
+ * @param ev the DocumentEvent describing the change of the document model
+ * @param vf the ViewFactory to use for creating new views
+ *
+ * @return whether or not the child views represent the child elements of
+ * the element that this view is responsible for. Some views may
+ * create views that are responsible only for parts of the element
+ * that they are responsible for and should then return false.
+ *
+ * @since 1.3
+ */
+ protected boolean updateChildren(DocumentEvent.ElementChange ec,
+ DocumentEvent ev,
+ ViewFactory vf)
+ {
+ 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;
+
+ return true;
+ }
+
+ /**
+ * Forwards the DocumentEvent to child views that need to get notified
+ * of the change to the model. This calles {@link #forwardUpdateToView}
+ * for each View that must be forwarded to.
+ *
+ * @param ec the ElementChange describing the element changes (may be
+ * <code>null</code> if there were no changes)
+ * @param ev the DocumentEvent describing the changes to the model
+ * @param shape the current allocation of the view
+ * @param vf the ViewFactory used to create new Views
+ *
+ * @since 1.3
+ */
+ protected void forwardUpdate(DocumentEvent.ElementChange ec,
+ DocumentEvent ev, Shape shape, ViewFactory vf)
+ {
+ for (int i = 0; i < children.length; i++)
+ {
+ View child = children[i];
+ forwardUpdateToView(child, ev, shape, vf);
+ }
+ }
+
+ /**
+ * Forwards an update event to the given child view. This calls
+ * {@link #insertUpdate}, {@link #removeUpdate} or {@link #changedUpdate},
+ * depending on the type of document event.
+ *
+ * @param view the View to forward the event to
+ * @param ev the DocumentEvent to forward
+ * @param shape the current allocation of the View
+ * @param vf the ViewFactory used to create new Views
+ *
+ * @since 1.3
+ */
+ protected void forwardUpdateToView(View view, DocumentEvent ev, Shape shape,
+ ViewFactory vf)
+ {
+ DocumentEvent.EventType type = ev.getType();
+ if (type == DocumentEvent.EventType.INSERT)
+ view.insertUpdate(ev, shape, vf);
+ else if (type == DocumentEvent.EventType.REMOVE)
+ view.removeUpdate(ev, shape, vf);
+ else if (type == DocumentEvent.EventType.CHANGE)
+ view.changedUpdate(ev, shape, vf);
+ }
+
+ /**
+ * Updates the layout.
+ *
+ * @param ec the ElementChange that describes the changes to the element
+ * @param ev the DocumentEvent that describes the changes to the model
+ * @param shape the current allocation for this view
+ *
+ * @since 1.3
+ */
+ protected void updateLayout(DocumentEvent.ElementChange ec,
+ DocumentEvent ev, Shape shape)
+ {
+ Rectangle b = shape.getBounds();
+ if (ec != null)
+ preferenceChanged(this, true, true);
+ }
+}
+
diff --git a/libjava/classpath/javax/swing/text/ViewFactory.java b/libjava/classpath/javax/swing/text/ViewFactory.java
new file mode 100644
index 00000000000..079488017b6
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/ViewFactory.java
@@ -0,0 +1,50 @@
+/* ViewFactory.java --
+ Copyright (C) 2002, 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;
+
+public interface ViewFactory
+{
+ /**
+ * Creates a view for a given element.
+ *
+ * @param elem them element to create view for
+ *
+ * @return a new created view
+ */
+ View create(Element elem);
+}
diff --git a/libjava/classpath/javax/swing/text/html/HTML.java b/libjava/classpath/javax/swing/text/html/HTML.java
new file mode 100644
index 00000000000..3c03a63a471
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/HTML.java
@@ -0,0 +1,1309 @@
+/* HTML.java -- HTML document tag constants
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html;
+
+import java.io.Serializable;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.swing.text.AttributeSet;
+
+/**
+ * HTML attribute and tag definitions.
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
+ */
+public class HTML
+{
+ /**
+ * Represents a HTML attribute.
+ */
+ public static class Attribute
+ implements Serializable
+ {
+ /**
+ * The action attribute
+ */
+ public static final Attribute ACTION = new Attribute("action");
+
+ /**
+ * The align attribute
+ */
+ public static final Attribute ALIGN = new Attribute("align");
+
+ /**
+ * The alink attribute
+ */
+ public static final Attribute ALINK = new Attribute("alink");
+
+ /**
+ * The alt attribute
+ */
+ public static final Attribute ALT = new Attribute("alt");
+
+ /**
+ * The archive attribute
+ */
+ public static final Attribute ARCHIVE = new Attribute("archive");
+
+ /**
+ * The background attribute
+ */
+ public static final Attribute BACKGROUND = new Attribute("background");
+
+ /**
+ * The bgcolor attribute
+ */
+ public static final Attribute BGCOLOR = new Attribute("bgcolor");
+
+ /**
+ * The border attribute
+ */
+ public static final Attribute BORDER = new Attribute("border");
+
+ /**
+ * The cellpadding attribute
+ */
+ public static final Attribute CELLPADDING = new Attribute("cellpadding");
+
+ /**
+ * The cellspacing attribute
+ */
+ public static final Attribute CELLSPACING = new Attribute("cellspacing");
+
+ /**
+ * The checked attribute
+ */
+ public static final Attribute CHECKED = new Attribute("checked");
+
+ /**
+ * The class attribute
+ */
+ public static final Attribute CLASS = new Attribute("class");
+
+ /**
+ * The classid attribute
+ */
+ public static final Attribute CLASSID = new Attribute("classid");
+
+ /**
+ * The clear attribute
+ */
+ public static final Attribute CLEAR = new Attribute("clear");
+
+ /**
+ * The code attribute
+ */
+ public static final Attribute CODE = new Attribute("code");
+
+ /**
+ * The codebase attribute
+ */
+ public static final Attribute CODEBASE = new Attribute("codebase");
+
+ /**
+ * The codetype attribute
+ */
+ public static final Attribute CODETYPE = new Attribute("codetype");
+
+ /**
+ * The color attribute
+ */
+ public static final Attribute COLOR = new Attribute("color");
+
+ /**
+ * The cols attribute
+ */
+ public static final Attribute COLS = new Attribute("cols");
+
+ /**
+ * The colspan attribute
+ */
+ public static final Attribute COLSPAN = new Attribute("colspan");
+
+ /**
+ * The comment attribute
+ */
+ public static final Attribute COMMENT = new Attribute("comment");
+
+ /**
+ * The compact attribute
+ */
+ public static final Attribute COMPACT = new Attribute("compact");
+
+ /**
+ * The content attribute
+ */
+ public static final Attribute CONTENT = new Attribute("content");
+
+ /**
+ * The coords attribute
+ */
+ public static final Attribute COORDS = new Attribute("coords");
+
+ /**
+ * The data attribute
+ */
+ public static final Attribute DATA = new Attribute("data");
+
+ /**
+ * The declare attribute
+ */
+ public static final Attribute DECLARE = new Attribute("declare");
+
+ /**
+ * The dir attribute
+ */
+ public static final Attribute DIR = new Attribute("dir");
+
+ /**
+ * The dummy attribute
+ */
+ public static final Attribute DUMMY = new Attribute("dummy");
+
+ /**
+ * The enctype attribute
+ */
+ public static final Attribute ENCTYPE = new Attribute("enctype");
+
+ /**
+ * The endtag attribute
+ */
+ public static final Attribute ENDTAG = new Attribute("endtag");
+
+ /**
+ * The face attribute
+ */
+ public static final Attribute FACE = new Attribute("face");
+
+ /**
+ * The frameborder attribute
+ */
+ public static final Attribute FRAMEBORDER = new Attribute("frameborder");
+
+ /**
+ * The halign attribute
+ */
+ public static final Attribute HALIGN = new Attribute("halign");
+
+ /**
+ * The height attribute
+ */
+ public static final Attribute HEIGHT = new Attribute("height");
+
+ /**
+ * The href attribute
+ */
+ public static final Attribute HREF = new Attribute("href");
+
+ /**
+ * The hspace attribute
+ */
+ public static final Attribute HSPACE = new Attribute("hspace");
+
+ /**
+ * The http-equiv attribute
+ */
+ public static final Attribute HTTPEQUIV = new Attribute("http-equiv");
+
+ /**
+ * The id attribute
+ */
+ public static final Attribute ID = new Attribute("id");
+
+ /**
+ * The ismap attribute
+ */
+ public static final Attribute ISMAP = new Attribute("ismap");
+
+ /**
+ * The lang attribute
+ */
+ public static final Attribute LANG = new Attribute("lang");
+
+ /**
+ * The language attribute
+ */
+ public static final Attribute LANGUAGE = new Attribute("language");
+
+ /**
+ * The link attribute
+ */
+ public static final Attribute LINK = new Attribute("link");
+
+ /**
+ * The lowsrc attribute
+ */
+ public static final Attribute LOWSRC = new Attribute("lowsrc");
+
+ /**
+ * The marginheight attribute
+ */
+ public static final Attribute MARGINHEIGHT = new Attribute("marginheight");
+
+ /**
+ * The marginwidth attribute
+ */
+ public static final Attribute MARGINWIDTH = new Attribute("marginwidth");
+
+ /**
+ * The maxlength attribute
+ */
+ public static final Attribute MAXLENGTH = new Attribute("maxlength");
+
+ /**
+ * The media attribute
+ */
+ public static final Attribute MEDIA = new Attribute("media");
+
+ /**
+ * The method attribute
+ */
+ public static final Attribute METHOD = new Attribute("method");
+
+ /**
+ * The multiple attribute
+ */
+ public static final Attribute MULTIPLE = new Attribute("multiple");
+
+ /**
+ * The n attribute
+ */
+ public static final Attribute N = new Attribute("n");
+
+ /**
+ * The name attribute
+ */
+ public static final Attribute NAME = new Attribute("name");
+
+ /**
+ * The nohref attribute
+ */
+ public static final Attribute NOHREF = new Attribute("nohref");
+
+ /**
+ * The noresize attribute
+ */
+ public static final Attribute NORESIZE = new Attribute("noresize");
+
+ /**
+ * The noshade attribute
+ */
+ public static final Attribute NOSHADE = new Attribute("noshade");
+
+ /**
+ * The nowrap attribute
+ */
+ public static final Attribute NOWRAP = new Attribute("nowrap");
+
+ /**
+ * The prompt attribute
+ */
+ public static final Attribute PROMPT = new Attribute("prompt");
+
+ /**
+ * The rel attribute
+ */
+ public static final Attribute REL = new Attribute("rel");
+
+ /**
+ * The rev attribute
+ */
+ public static final Attribute REV = new Attribute("rev");
+
+ /**
+ * The rows attribute
+ */
+ public static final Attribute ROWS = new Attribute("rows");
+
+ /**
+ * The rowspan attribute
+ */
+ public static final Attribute ROWSPAN = new Attribute("rowspan");
+
+ /**
+ * The scrolling attribute
+ */
+ public static final Attribute SCROLLING = new Attribute("scrolling");
+
+ /**
+ * The selected attribute
+ */
+ public static final Attribute SELECTED = new Attribute("selected");
+
+ /**
+ * The shape attribute
+ */
+ public static final Attribute SHAPE = new Attribute("shape");
+
+ /**
+ * The shapes attribute
+ */
+ public static final Attribute SHAPES = new Attribute("shapes");
+
+ /**
+ * The size attribute
+ */
+ public static final Attribute SIZE = new Attribute("size");
+
+ /**
+ * The src attribute
+ */
+ public static final Attribute SRC = new Attribute("src");
+
+ /**
+ * The standby attribute
+ */
+ public static final Attribute STANDBY = new Attribute("standby");
+
+ /**
+ * The start attribute
+ */
+ public static final Attribute START = new Attribute("start");
+
+ /**
+ * The style attribute
+ */
+ public static final Attribute STYLE = new Attribute("style");
+
+ /**
+ * The target attribute
+ */
+ public static final Attribute TARGET = new Attribute("target");
+
+ /**
+ * The text attribute
+ */
+ public static final Attribute TEXT = new Attribute("text");
+
+ /**
+ * The title attribute
+ */
+ public static final Attribute TITLE = new Attribute("title");
+
+ /**
+ * The type attribute
+ */
+ public static final Attribute TYPE = new Attribute("type");
+
+ /**
+ * The usemap attribute
+ */
+ public static final Attribute USEMAP = new Attribute("usemap");
+
+ /**
+ * The valign attribute
+ */
+ public static final Attribute VALIGN = new Attribute("valign");
+
+ /**
+ * The value attribute
+ */
+ public static final Attribute VALUE = new Attribute("value");
+
+ /**
+ * The valuetype attribute
+ */
+ public static final Attribute VALUETYPE = new Attribute("valuetype");
+
+ /**
+ * The version attribute
+ */
+ public static final Attribute VERSION = new Attribute("version");
+
+ /**
+ * The vlink attribute
+ */
+ public static final Attribute VLINK = new Attribute("vlink");
+
+ /**
+ * The vspace attribute
+ */
+ public static final Attribute VSPACE = new Attribute("vspace");
+
+ /**
+ * The width attribute
+ */
+ public static final Attribute WIDTH = new Attribute("width");
+ private final String name;
+
+ /**
+ * Creates the attribute with the given name.
+ */
+ protected Attribute(String a_name)
+ {
+ name = a_name;
+ }
+
+ /**
+ * Calls compareTo on the tag names (Strings)
+ */
+ public int compareTo(Object other)
+ {
+ return name.compareTo(((Attribute) other).name);
+ }
+
+ /**
+ * The attributes are equal if the names are equal
+ * (ignoring case)
+ */
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ return true;
+
+ if (!(other instanceof Attribute))
+ return false;
+
+ Attribute that = (Attribute) other;
+
+ return that.name.equalsIgnoreCase(name);
+ }
+
+ /**
+ * Returns the hash code which corresponds to the string for this tag.
+ */
+ public int hashCode()
+ {
+ return name == null ? 0 : name.hashCode();
+ }
+
+ /**
+ * Returns the attribute name. The names of the built-in attributes
+ * are always returned in lowercase.
+ */
+ public String toString()
+ {
+ return name;
+ }
+
+ /**
+ * Return an array of all attributes, declared in the HTML.Attribute
+ * class. WARNING: attributes are the only public fields,
+ * expected in this class.
+ */
+ static Attribute[] getAllAttributes()
+ {
+ Field[] f = Attribute.class.getFields();
+ Attribute[] attrs = new Attribute[ f.length ];
+ Field x;
+ int p = 0;
+ Attribute a;
+
+ for (int i = 0; i < f.length; i++)
+ {
+ x = f [ i ];
+
+ if ((x.getModifiers() & Modifier.STATIC) != 0)
+ {
+ if (x.getType().equals(Attribute.class))
+ {
+ try
+ {
+ a = (Attribute) x.get(null);
+ attrs [ p++ ] = a;
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace(System.err);
+ throw new Error("This should never happen, report a bug");
+ }
+ }
+ }
+ }
+
+ return attrs;
+ }
+ }
+
+ /**
+ * Represents a HTML tag.
+ */
+ public static class Tag
+ implements Comparable, Serializable
+ {
+ /**
+ * The &lt;a&gt; tag
+ */
+ public static final Tag A = new Tag("a");
+
+ /**
+ * The &lt;address&gt; tag
+ */
+ public static final Tag ADDRESS = new Tag("address");
+
+ /**
+ * The &lt;applet&gt; tag
+ */
+ public static final Tag APPLET = new Tag("applet");
+
+ /**
+ * The &lt;area&gt; tag
+ */
+ public static final Tag AREA = new Tag("area");
+
+ /**
+ * The &lt;b&gt; tag
+ */
+ public static final Tag B = new Tag("b");
+
+ /**
+ * The &lt;base&gt; tag
+ */
+ public static final Tag BASE = new Tag("base");
+
+ /**
+ * The &lt;basefont&gt; tag
+ */
+ public static final Tag BASEFONT = new Tag("basefont");
+
+ /**
+ * The &lt;big&gt; tag
+ */
+ public static final Tag BIG = new Tag("big");
+
+ /**
+ * The &lt;blockquote&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag BLOCKQUOTE = new Tag("blockquote", BREAKS | BLOCK);
+
+ /**
+ * The &lt;body&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag BODY = new Tag("body", BREAKS | BLOCK);
+
+ /**
+ * The &lt;br&gt; tag , breaks flow.
+ */
+ public static final Tag BR = new Tag("br", BREAKS);
+
+ /**
+ * The &lt;caption&gt; tag
+ */
+ public static final Tag CAPTION = new Tag("caption");
+
+ /**
+ * The &lt;center&gt; tag , breaks flow.
+ */
+ public static final Tag CENTER = new Tag("center", BREAKS);
+
+ /**
+ * The &lt;cite&gt; tag
+ */
+ public static final Tag CITE = new Tag("cite");
+
+ /**
+ * The &lt;code&gt; tag
+ */
+ public static final Tag CODE = new Tag("code");
+
+ /**
+ * The &lt;dd&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag DD = new Tag("dd", BREAKS | BLOCK);
+
+ /**
+ * The &lt;dfn&gt; tag
+ */
+ public static final Tag DFN = new Tag("dfn");
+
+ /**
+ * The &lt;dir&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag DIR = new Tag("dir", BREAKS | BLOCK);
+
+ /**
+ * The &lt;div&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag DIV = new Tag("div", BREAKS | BLOCK);
+
+ /**
+ * The &lt;dl&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag DL = new Tag("dl", BREAKS | BLOCK);
+
+ /**
+ * The &lt;dt&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag DT = new Tag("dt", BREAKS | BLOCK);
+
+ /**
+ * The &lt;em&gt; tag
+ */
+ public static final Tag EM = new Tag("em");
+
+ /**
+ * The &lt;font&gt; tag
+ */
+ public static final Tag FONT = new Tag("font");
+
+ /**
+ * The &lt;form&gt; tag , breaks flow.
+ */
+ public static final Tag FORM = new Tag("form", BREAKS);
+
+ /**
+ * The &lt;frame&gt; tag
+ */
+ public static final Tag FRAME = new Tag("frame");
+
+ /**
+ * The &lt;frameset&gt; tag
+ */
+ public static final Tag FRAMESET = new Tag("frameset");
+
+ /**
+ * The &lt;h1&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag H1 = new Tag("h1", BREAKS | BLOCK);
+
+ /**
+ * The &lt;h2&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag H2 = new Tag("h2", BREAKS | BLOCK);
+
+ /**
+ * The &lt;h3&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag H3 = new Tag("h3", BREAKS | BLOCK);
+
+ /**
+ * The &lt;h4&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag H4 = new Tag("h4", BREAKS | BLOCK);
+
+ /**
+ * The &lt;h5&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag H5 = new Tag("h5", BREAKS | BLOCK);
+
+ /**
+ * The &lt;h6&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag H6 = new Tag("h6", BREAKS | BLOCK);
+
+ /**
+ * The &lt;head&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag HEAD = new Tag("head", BREAKS | BLOCK);
+
+ /**
+ * The &lt;hr&gt; tag , breaks flow.
+ */
+ public static final Tag HR = new Tag("hr", BREAKS);
+
+ /**
+ * The &lt;html&gt; tag , breaks flow.
+ */
+ public static final Tag HTML = new Tag("html", BREAKS);
+
+ /**
+ * The &lt;i&gt; tag
+ */
+ public static final Tag I = new Tag("i");
+
+ /**
+ * The &lt;img&gt; tag
+ */
+ public static final Tag IMG = new Tag("img");
+
+ /**
+ * The &lt;input&gt; tag
+ */
+ public static final Tag INPUT = new Tag("input");
+
+ /**
+ * The &lt;isindex&gt; tag , breaks flow.
+ */
+ public static final Tag ISINDEX = new Tag("isindex", BREAKS);
+
+ /**
+ * The &lt;kbd&gt; tag
+ */
+ public static final Tag KBD = new Tag("kbd");
+
+ /**
+ * The &lt;li&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag LI = new Tag("li", BREAKS | BLOCK);
+
+ /**
+ * The &lt;link&gt; tag
+ */
+ public static final Tag LINK = new Tag("link");
+
+ /**
+ * The &lt;map&gt; tag
+ */
+ public static final Tag MAP = new Tag("map");
+
+ /**
+ * The &lt;menu&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag MENU = new Tag("menu", BREAKS | BLOCK);
+
+ /**
+ * The &lt;meta&gt; tag
+ */
+ public static final Tag META = new Tag("meta");
+
+ /**
+ * The &lt;nobr&gt; tag
+ */
+ public static final Tag NOBR = new Tag("nobr");
+
+ /**
+ * The &lt;noframes&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag NOFRAMES = new Tag("noframes", BREAKS | BLOCK);
+
+ /**
+ * The &lt;object&gt; tag
+ */
+ public static final Tag OBJECT = new Tag("object");
+
+ /**
+ * The &lt;ol&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag OL = new Tag("ol", BREAKS | BLOCK);
+
+ /**
+ * The &lt;option&gt; tag
+ */
+ public static final Tag OPTION = new Tag("option");
+
+ /**
+ * The &lt;p&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag P = new Tag("p", BREAKS | BLOCK);
+
+ /**
+ * The &lt;param&gt; tag
+ */
+ public static final Tag PARAM = new Tag("param");
+
+ /**
+ * The &lt;pre&gt; tag , breaks flow, block tag, preformatted.
+ */
+ public static final Tag PRE = new Tag("pre", BREAKS | BLOCK | PREFORMATTED);
+
+ /**
+ * The &lt;s&gt; tag
+ */
+ public static final Tag S = new Tag("s");
+
+ /**
+ * The &lt;samp&gt; tag
+ */
+ public static final Tag SAMP = new Tag("samp");
+
+ /**
+ * The &lt;script&gt; tag
+ */
+ public static final Tag SCRIPT = new Tag("script");
+
+ /**
+ * The &lt;select&gt; tag
+ */
+ public static final Tag SELECT = new Tag("select");
+
+ /**
+ * The &lt;small&gt; tag
+ */
+ public static final Tag SMALL = new Tag("small");
+
+ /**
+ * The &lt;span&gt; tag
+ */
+ public static final Tag SPAN = new Tag("span");
+
+ /**
+ * The &lt;strike&gt; tag
+ */
+ public static final Tag STRIKE = new Tag("strike");
+
+ /**
+ * The &lt;strong&gt; tag
+ */
+ public static final Tag STRONG = new Tag("strong");
+
+ /**
+ * The &lt;style&gt; tag
+ */
+ public static final Tag STYLE = new Tag("style");
+
+ /**
+ * The &lt;sub&gt; tag
+ */
+ public static final Tag SUB = new Tag("sub");
+
+ /**
+ * The &lt;sup&gt; tag
+ */
+ public static final Tag SUP = new Tag("sup");
+
+ /**
+ * The &lt;table&gt; tag , block tag.
+ */
+ public static final Tag TABLE = new Tag("table", BLOCK);
+
+ /**
+ * The &lt;td&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag TD = new Tag("td", BREAKS | BLOCK);
+
+ /**
+ * The &lt;textarea&gt; tag , preformatted.
+ */
+ public static final Tag TEXTAREA = new Tag("textarea", PREFORMATTED);
+
+ /**
+ * The &lt;th&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag TH = new Tag("th", BREAKS | BLOCK);
+
+ /**
+ * The &lt;title&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag TITLE = new Tag("title", BREAKS | BLOCK);
+
+ /**
+ * The &lt;tr&gt; tag , block tag.
+ */
+ public static final Tag TR = new Tag("tr", BLOCK);
+
+ /**
+ * The &lt;tt&gt; tag
+ */
+ public static final Tag TT = new Tag("tt");
+
+ /**
+ * The &lt;u&gt; tag
+ */
+ public static final Tag U = new Tag("u");
+
+ /**
+ * The &lt;ul&gt; tag , breaks flow, block tag.
+ */
+ public static final Tag UL = new Tag("ul", BREAKS | BLOCK);
+
+ /**
+ * The &lt;var&gt; tag
+ */
+ public static final Tag VAR = new Tag("var");
+
+ /* Special tags */
+
+ /**
+ * Total number of syntetic tags, delared in the Tag class.
+ * This must be adjusted if the new synthetic tags are declared.
+ * Otherwise the HTML.getAllTags() will not work as expected.
+ */
+ private static final int TOTAL_SYNTHETIC_TAGS = 3;
+
+ /**
+ * All comments are labeled with this tag.
+ * This tag is not included into the array, returned by getAllTags().
+ * toString() returns 'comment'. HTML reader synthesizes this tag.
+ */
+ public static final Tag COMMENT = new Tag("comment", SYNTETIC);
+
+ /**
+ * All text content is labeled with this tag.
+ * This tag is not included into the array, returned by getAllTags().
+ * toString() returns 'content'. HTML reader synthesizes this tag.
+ */
+ public static final Tag CONTENT = new Tag("content", SYNTETIC);
+
+ /**
+ * All text content must be in a paragraph element.
+ * If a paragraph didn't exist when content was encountered,
+ * a paragraph is manufactured.
+ * toString() returns 'implied'. HTML reader synthesizes this tag.
+ */
+ public static final Tag IMPLIED = new Tag("implied", SYNTETIC);
+ final String name;
+ final int flags;
+
+ /**
+ * Create the unitialised instance of HTML.Tag.
+ *
+ * The {@link #breaksFlow()}, {@link #isBlock()}
+ * and {@link #isPreformatted()} will always return false.
+ * The {@link #toString()} will return <code>null</code>.
+ *
+ * @since 1.3
+ */
+ public Tag()
+ {
+ name = null;
+ flags = 0;
+ }
+
+ /**
+ * Creates a new Tag with the specified id, and with causesBreak
+ * and isBlock set to false.
+ */
+ protected Tag(String id)
+ {
+ name = id;
+ flags = 0;
+ }
+
+ /**
+ * Creates a new Tag with the specified tag name and
+ * causesBreak and isBlock properties.
+ */
+ protected Tag(String id, boolean causesBreak, boolean isBlock)
+ {
+ int f = 0;
+
+ if (causesBreak)
+ {
+ f |= BREAKS;
+ }
+
+ if (isBlock)
+ {
+ f |= BLOCK;
+ }
+
+ flags = f;
+ name = id;
+ }
+
+ /**
+ * Create a tag taking flags.
+ */
+ Tag(String id, int a_flags)
+ {
+ name = id;
+ flags = a_flags;
+ }
+
+ /**
+ * Returns true if this tag is a block tag, which is a tag used to
+ * add structure to a document.
+ */
+ public boolean isBlock()
+ {
+ return (flags & BLOCK) != 0;
+ }
+
+ /**
+ * Returns true if this tag is pre-formatted, which is true if
+ * the tag is either PRE or TEXTAREA
+ */
+ public boolean isPreformatted()
+ {
+ return (flags & PREFORMATTED) != 0;
+ }
+
+ /**
+ * Returns true if this tag causes a line break to the flow of text
+ */
+ public boolean breaksFlow()
+ {
+ return (flags & BREAKS) != 0;
+ }
+
+ /**
+ * Calls compareTo on the tag names (Strings)
+ */
+ public int compareTo(Object other)
+ {
+ return name.compareTo(((Tag) other).name);
+ }
+
+ /**
+ * The tags are equal if the names are equal (ignoring case).
+ */
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof Tag))
+ {
+ return false;
+ }
+
+ Tag that = (Tag) other;
+
+ return that.name.equalsIgnoreCase(name);
+ }
+
+ /**
+ * Returns the hash code which corresponds to the string for this tag.
+ */
+ public int hashCode()
+ {
+ return name == null ? 0 : name.hashCode();
+ }
+
+ /**
+ * Returns the tag name. The names of the built-in tags are always
+ * returned in lowercase.
+ */
+ public String toString()
+ {
+ return name;
+ }
+
+ /**
+ * Return an array of HTML tags, declared in HTML.Tag class.
+ * WARNING: This method expects that the Tags are the only
+ * public fields declared in the Tag class.
+ */
+ static Tag[] getAllTags()
+ {
+ Field[] f = Tag.class.getFields();
+ Field x;
+
+ // The syntetic tags are not included.
+ Tag[] tags = new Tag[ f.length - TOTAL_SYNTHETIC_TAGS ];
+ int p = 0;
+ Tag t;
+
+ for (int i = 0; i < f.length; i++)
+ {
+ x = f [ i ];
+
+ if ((x.getModifiers() & Modifier.STATIC) != 0)
+ {
+ if (x.getType().equals(Tag.class))
+ {
+ try
+ {
+ t = (Tag) x.get(null);
+
+ if (!t.isSyntetic())
+ {
+ tags [ p++ ] = t;
+ }
+ }
+ catch (IllegalAccessException ex)
+ {
+ unexpected(ex);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ unexpected(ex);
+ }
+ }
+ }
+ }
+
+ return tags;
+ }
+
+ /**
+ * Returns true for tags, generated by the html reader
+ * (COMMENT, CONTENT and IMPLIED).
+ */
+ boolean isSyntetic()
+ {
+ return (flags & SYNTETIC) != 0;
+ }
+
+ private static void unexpected(Exception ex)
+ throws Error
+ {
+ throw new Error("This should never happen, report a bug", ex);
+ }
+ }
+
+ /**
+ * Represents an unknown HTML tag.
+ * @author Mark Wielaard (mark@klomp.org)
+ */
+ public static class UnknownTag
+ extends Tag
+ implements Serializable
+ {
+ private static final long serialVersionUID = -1534369342247250625L;
+
+ /**
+ * Creates a new UnknownTag with the specified name
+ * @param name The tag name.
+ *
+ */
+ public UnknownTag(String name)
+ {
+ super(name);
+ }
+ }
+
+ /**
+ * This value is returned for attributes without value that have no
+ * default value defined in the DTD.
+ */
+ public static final String NULL_ATTRIBUTE_VALUE = "#DEFAULT";
+
+ /* Package level html tag flags */
+ static final int BREAKS = 1;
+ static final int BLOCK = 2;
+ static final int PREFORMATTED = 4;
+ static final int SYNTETIC = 8;
+ private static Map tagMap;
+ private static Map attrMap;
+
+ /**
+ * The public constructor (does nothing). It it seldom required to have
+ * an instance of this class, because all public fields and methods
+ * are static.
+ */
+ public HTML()
+ {
+ }
+
+ /**
+ * Returns the set of the recognized HTML attributes.
+ */
+ public static HTML.Attribute[] getAllAttributeKeys()
+ {
+ return Attribute.getAllAttributes();
+ }
+
+ /**
+ * Returns the set of actual HTML tags that are recognized by
+ * the default HTML reader. The returned array does not include the
+ * COMMENT, CONTENT and IMPLIED tags.
+ */
+ public static HTML.Tag[] getAllTags()
+ {
+ return Tag.getAllTags();
+ }
+
+ /**
+ * Returns an htl attribute constant for the given attribute name.
+ * @param attName the attribute name, case insensitive
+ */
+ public static Attribute getAttributeKey(String attName)
+ {
+ if (attrMap == null)
+ {
+ // Create the map on demand.
+ attrMap = new TreeMap();
+
+ Attribute[] attrs = getAllAttributeKeys();
+
+ for (int i = 0; i < attrs.length; i++)
+ {
+ attrMap.put(attrs [ i ].toString(), attrs [ i ]);
+ }
+ }
+
+ return (Attribute) attrMap.get(attName.toLowerCase());
+ }
+
+ /**
+ * Searches the value of given attribute in the provided set.
+ * If the value is found (String type expected), tries to parse it as
+ * an integer value. If succeded, returns the obtained integer value.
+ *
+ * For example:<p><code>
+ * SimpleAttributeSet ase = new SimpleAttributeSet();
+ * ase.addAttribute(HTML.getAttributeKey("size"),"222");
+ * System.out.println(
+ * HTML.getIntegerAttributeValue
+ * (ase, HTML.getAttributeKey("size"), 333)); // prints "222"
+ * System.out.println(
+ * HTML.getIntegerAttributeValue
+ * (ase, HTML.getAttributeKey("width"), 333)); // prints "333".
+ * </code></p>
+ *
+ *
+ * @param set The attribute set to search in. If the set contains the
+ * given attribute, it must by a type of String.
+ * @param attribute The html attribute to search in
+ * @param defaultValue The value that is returned if the attribute is not
+ * found in the given set or if the NumberFormatException was thrown
+ * during the parsing.
+ */
+ public static int getIntegerAttributeValue(AttributeSet set,
+ HTML.Attribute attribute,
+ int defaultValue
+ )
+ {
+ Object v = set.getAttribute(attribute);
+
+ if (v == null)
+ {
+ return defaultValue;
+ }
+
+ try
+ {
+ return Integer.parseInt(v.toString().trim());
+ }
+ catch (Exception ex)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns a HTML tag constant for the given HTML attribute name.
+ * If the tag is unknown, the null is returned.
+ * @param tagName the tag name, case insensitive
+ */
+ public static Tag getTag(String tagName)
+ {
+ if (tagMap == null)
+ {
+ // Create the mao on demand.
+ tagMap = new TreeMap();
+
+ Tag[] tags = getAllTags();
+
+ for (int i = 0; i < tags.length; i++)
+ {
+ tagMap.put(tags [ i ].toString(), tags [ i ]);
+ }
+ }
+
+ return (Tag) tagMap.get(tagName.toLowerCase());
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/HTMLDocument.java b/libjava/classpath/javax/swing/text/html/HTMLDocument.java
new file mode 100644
index 00000000000..a95e496ec4d
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/HTMLDocument.java
@@ -0,0 +1,53 @@
+/* HTMLDocument.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html;
+
+import javax.swing.text.DefaultStyledDocument;
+
+/**
+ * TODO: This class is not yet completetely implemented.
+ *
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public class HTMLDocument extends DefaultStyledDocument
+{
+ public void processHTMLFrameHyperlinkEvent(HTMLFrameHyperlinkEvent event)
+ {
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
new file mode 100644
index 00000000000..7ae78ec0725
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
@@ -0,0 +1,249 @@
+/* HTMLEditorKit.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html;
+
+import java.io.Reader;
+import java.io.Serializable;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.StyledEditorKit;
+
+/**
+ * This class is NOT implemented. This file currently holds only
+ * declarations of the two enclosing classes, necessary for testing
+ * the implemented javax.swing.text.html.parser package.
+ *
+ * @author No authorship is taken, implement the class and be!
+ * TODO: replace this header after implementing the class.
+ */
+public class HTMLEditorKit
+ extends StyledEditorKit
+ implements Serializable, Cloneable
+{
+ /**
+ * The abstract HTML parser declaration.
+ */
+ public abstract static class Parser
+ {
+ /**
+ * Parse the HTML text, calling various methods of the provided callback
+ * in response to the occurence of the corresponding HTML constructions.
+ * @param reader The reader to read the source HTML from.
+ * @param callback The callback to receive information about the parsed
+ * HTML structures
+ * @param ignoreCharSet If true, the parser ignores all charset information
+ * that may be present in HTML documents.
+ * @throws IOException, normally if the reader throws one.
+ */
+ public abstract void parse(Reader reader, ParserCallback callback,
+ boolean ignoreCharSet
+ )
+ throws java.io.IOException;
+ }
+
+ /**
+ * The "hook" that receives all information about the HTML document
+ * structure while parsing it. The methods are invoked by parser
+ * and should be normally overridden.
+ */
+ public static class ParserCallback
+ {
+ /**
+ * If the tag does not occurs in the html stream directly, but
+ * is supposed by parser, the tag attribute set contains this additional
+ * attribute, having value Boolean.True.
+ */
+ public static final Object IMPLIED = "_implied_";
+
+ /**
+ * The parser calls this method after it finishes parsing the document.
+ */
+ public void flush()
+ throws BadLocationException
+ {
+ }
+
+ /**
+ * Handle HTML comment, present in the given position.
+ * @param comment the comment
+ * @position the position of the comment in the text being parsed.
+ */
+ public void handleComment(char[] comment, int position)
+ {
+ }
+
+ /**
+ * Notifies about the character sequences, used to separate lines in
+ * this document. The parser calls this method after it finishes
+ * parsing the document, but before flush().
+ * @param end_of_line The "end of line sequence", one of: \r or \n or \r\n.
+ */
+ public void handleEndOfLineString(String end_of_line)
+ {
+ }
+
+ /**
+ * 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.
+ */
+ public void handleEndTag(HTML.Tag tag, int position)
+ {
+ }
+
+ /**
+ * Handle the error.
+ * @param message The message, explaining the error.
+ * @param position The starting position of the fragment that has caused
+ * the error in the html document being parsed.
+ */
+ public void handleError(String message, int position)
+ {
+ }
+
+ /**
+ * 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 tag The tag being handled.
+ * @param position The tag position in the text being parsed.
+ */
+ public void handleSimpleTag(HTML.Tag tag, MutableAttributeSet attributes,
+ int position
+ )
+ {
+ }
+
+ /**
+ * 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 tag The tag being handled
+ * @param position The tag position in the text being parsed
+ */
+ public void handleStartTag(HTML.Tag tag, MutableAttributeSet attributes,
+ int position
+ )
+ {
+ }
+
+ /**
+ * Handle the text section.
+ * @param text A section text.
+ * @param position The text position in the HTML document text being parsed.
+ */
+ public void handleText(char[] text, int position)
+ {
+ }
+ }
+
+ /**
+ * Use serialVersionUID (v1.4) for interoperability.
+ */
+ private static final long serialVersionUID = 8751997116710384592L;
+
+ /**
+ * Default cascading stylesheed file ("default.css").
+ */
+ public static final String DEFAULT_CSS = "default.css";
+
+ /**
+ * The <b>bold</b> action identifier.
+ */
+ public static final String BOLD_ACTION = "html-bold-action";
+
+ /**
+ * The <i>italic</i> action identifier.
+ */
+ public static final String ITALIC_ACTION = "html-italic-action";
+
+ /**
+ * The <font color="#FF0000">color</font> action indentifier
+ * (passing the color as an argument).
+ */
+ public static final String COLOR_ACTION = "html-color-action";
+
+ /**
+ * The <font size="+1">increase</font> font action identifier.
+ */
+ public static final String FONT_CHANGE_BIGGER = "html-font-bigger";
+
+ /**
+ * The <font size="-1">decrease</font> font action identifier.
+ */
+ public static final String FONT_CHANGE_SMALLER = "html-font-smaller";
+
+ /**
+ * Align images at the bottom.
+ */
+ public static final String IMG_ALIGN_BOTTOM = "html-image-align-bottom";
+
+ /**
+ * Align images at the middle.
+ */
+ public static final String IMG_ALIGN_MIDDLE = "html-image-align-middle";
+
+ /**
+ * Align images at the top.
+ */
+ public static final String IMG_ALIGN_TOP = "html-image-align-top";
+
+ /**
+ * Align images at the border.
+ */
+ public static final String IMG_BORDER = "html-image-border";
+
+ /**
+ * The "logical style" action identifier, passing that style as parameter.
+ */
+ public static final String LOGICAL_STYLE_ACTION = "html-logical-style-action";
+
+ /**
+ * The "ident paragraph left" action.
+ */
+ public static final String PARA_INDENT_LEFT = "html-para-indent-left";
+
+ /**
+ * The "ident paragraph right" action.
+ */
+ public static final String PARA_INDENT_RIGHT = "html-para-indent-right";
+} \ No newline at end of file
diff --git a/libjava/classpath/javax/swing/text/html/HTMLFrameHyperlinkEvent.java b/libjava/classpath/javax/swing/text/html/HTMLFrameHyperlinkEvent.java
new file mode 100644
index 00000000000..dc0ab10a8f7
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/HTMLFrameHyperlinkEvent.java
@@ -0,0 +1,132 @@
+/* HTMLFrameHyperlinkEvent.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html;
+
+import java.net.URL;
+
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkEvent.EventType;
+import javax.swing.text.Element;
+
+/**
+ * HTMLFrameHyperlinkEvent transfers information about the link that was
+ * activated in a frame.
+ *
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public class HTMLFrameHyperlinkEvent
+ extends HyperlinkEvent
+{
+ private final String target_frame;
+
+ /**
+ * Creates a new hypertext link event.
+ *
+ * @param source The object this link is associated to.
+ * @param type The type of event.
+ * @param url The URL this link pointing too.
+ * @param element The element in the document representing the anchor.
+ * @param frame - the Frame to display the document in.
+ */
+ public HTMLFrameHyperlinkEvent(Object source, EventType type, URL url,
+ Element element, String frame)
+ {
+ super(source, type, url, frame, element);
+ target_frame = frame;
+ }
+
+ /**
+ * Creates a new hypertext link event.
+ *
+ * @param source The object this link is associated to.
+ * @param type The type of event.
+ * @param url The URL this link pointing too.
+ * @param frame - the Frame to display the document in.
+ */
+ public HTMLFrameHyperlinkEvent(Object source, EventType type, URL url,
+ String frame)
+ {
+ super(source, type, url, frame);
+ target_frame = frame;
+ }
+
+ /**
+ * Creates a new hypertext link event.
+ *
+ * @param source The object this link is associated to.
+ * @param type The type of event.
+ * @param url The URL this link pointing too.
+ * @param description The description for this link.
+ * @param element The element in the document representing the anchor.
+ * @param frame - the Frame to display the document in.
+ */
+ public HTMLFrameHyperlinkEvent(Object source, EventType type, URL url,
+ String description, Element element,
+ String frame)
+ {
+ super(source, type, url, description, element);
+ target_frame = frame;
+ }
+
+ /**
+ * Creates a new hypertext link event.
+ *
+ * @param source The object this link is associated to.
+ * @param type The type of event.
+ * @param url The URL this link pointing too.
+ * @param description The description for this link.
+ * @param frame - the Frame to display the document in.
+ */
+ public HTMLFrameHyperlinkEvent(Object source, EventType type, URL url,
+ String description, String frame)
+ {
+ super(source, type, url, description);
+ target_frame = frame;
+ }
+
+ /**
+ * Gets the string, passed as the target frame identifier.
+ *
+ * @return the target for the link.
+ */
+ public String getTarget()
+ {
+ return target_frame;
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/package.html b/libjava/classpath/javax/swing/text/html/package.html
new file mode 100644
index 00000000000..c7e7744282c
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/package.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.swing.text.html package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - javax.swing.text.html</title></head>
+
+<body>
+<p> Provides supporting classes for web browsers,
+ web robots, web page content analysers, web editors and
+ other applications applications working with Hypertext
+ Markup Language (HTML).
+</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/javax/swing/text/html/parser/AttributeList.java b/libjava/classpath/javax/swing/text/html/parser/AttributeList.java
new file mode 100644
index 00000000000..5bca0bfa7db
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/AttributeList.java
@@ -0,0 +1,294 @@
+/* AttributeList.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html.parser;
+
+import gnu.javax.swing.text.html.parser.support.gnuStringIntMapper;
+
+import java.io.Serializable;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * <p>
+ * Stores the attribute information, obtained by parsing SGML (DTD) tag
+ * <code>&lt;!ATTLIST .. &gt;</code></p>
+ * <p>
+ * Elements can have a associated named properties (attributes) having the
+ * assigned values. The element start tag can have any number of attribute
+ * value pairs, separated by spaces. They can appear in any order.
+ * SGML requires you to delimit the attribute values using either double (")
+ * or single (') quotation marks. In HTML, it is possible
+ * (but not recommended) to specify the value of an attribute without
+ * quotation marks. Such attribute value may only contain
+ * letters, digits, hyphens (-) and periods (.) .
+ * </p>
+ * <p>
+ * The <code>AttributeList</code> defines a single attribute that additionally
+ * has a pointer referencing the possible subsequent attribute.
+ * The whole structure is just a simple linked list, storing all attributes of
+ * some <code>Element</code>.
+ * Use the <code>getNext()</code> method repeatedly to see all attributes in
+ * the list.
+ * </p>
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public final class AttributeList
+ implements DTDConstants, Serializable
+{
+ /** Maps between type names and they string values. */
+ private static final gnuStringIntMapper mapper =
+ new gnuStringIntMapper()
+ {
+ protected void create()
+ {
+ add("CDATA", DTDConstants.CDATA);
+ add("ENTITY", DTDConstants.ENTITY);
+ add("ENTITIES", DTDConstants.ENTITIES);
+ add("ID", DTDConstants.ID);
+ add("IDREF", DTDConstants.IDREF);
+ add("IDREFS", DTDConstants.IDREFS);
+ add("NAME", DTDConstants.NAME);
+ add("NAMES", DTDConstants.NAMES);
+ add("NMTOKEN", DTDConstants.NMTOKEN);
+ add("NMTOKENS", DTDConstants.NMTOKENS);
+ add("NOTATION", DTDConstants.NOTATION);
+ add("NUMBER", DTDConstants.NUMBER);
+ add("NUMBERS", DTDConstants.NUMBERS);
+ add("NUTOKEN", DTDConstants.NUTOKEN);
+ add("NUTOKENS", DTDConstants.NUTOKENS);
+ }
+ };
+
+ /** Use serialVersionUID for interoperability. */
+ private static final long serialVersionUID = -1361214058742015233L;
+
+ /**
+ * The value of ( = pointer to ) the next attribute in the linked list,
+ * storing all attributes of some Element. Contains null for the
+ * last attribute.
+ */
+ public AttributeList next;
+
+ /**
+ * The name of the attribute. The attribute names are case insensitive.
+ */
+ public String name;
+
+ /**
+ * The default value of this attribute. Equals to null if no default value
+ * is specified.
+ */
+ public String value;
+
+ /**
+ * The explicit set of the allowed values of this attribute. Equals to
+ * null, if this parameter was not specified.
+ * Values, defined in DTD, are case insensitive.
+ */
+ public Vector values;
+
+ /**
+ * The modifier of this attribute. This field contains one of the
+ * following DTD constants:
+ * <ul>
+ * <li> REQUIRED if the attribute value is always required,</li>
+ * <li> IMPLIED if the user agent must supply the default value itself,</li>
+ * <li> FIXED if the attribute value is fixed to some value and cannot
+ * be changed.</li>
+ * <li> DEFAULT if the attribute default value has been supplied.</li>
+ * <li> CURRENT the value that at any point in the document is
+ * the last value supplied for that element. A value is required to be
+ * supplied for the first* occurrence of an element</li>
+ * <li> CONREF specifies the IDREF value of
+ * the reference to content in another location of the document.
+ * The element with this attribute is empty, the content from
+ * that another location must be used instead.</li>
+ * </ul>
+ */
+ public int modifier;
+
+ /**
+ * The type of the attribute. The possible values of this field
+ * (NUMBER, NAME, ID, CDATA and so on) are defined in DTDConstants.
+ */
+ public int type;
+
+ /**
+ * Creates the attribute with the given name, initializing other fields
+ * to the default values ( 0 and null ).
+ *
+ * @param a_name The name of the attribute.
+ */
+ public AttributeList(String a_name)
+ {
+ name = a_name;
+ }
+
+ /**
+ * Creates the attribute with the given properties.
+ * @param a_name The name of the attribute
+ * @param a_type The type of the attribute. The possible values are defined
+ * in <code> DTDConstants</code>.
+ * @param a_modifier The modifier of this attribute. The possible values
+ * are defined in <code> DTDConstants</code>.
+ * @param a_default The default value of this attribute
+ * @param allowed_values The explicit set of the allowed values of
+ * this attribute
+ * @param a_next The value of the subsequent instance of the AttributeList,
+ * representing the next attribute definition for the same element.
+ * Equals to null for the last attribute definition.
+ */
+ public AttributeList(String a_name, int a_type, int a_modifier,
+ String a_default, Vector allowed_values,
+ AttributeList a_next
+ )
+ {
+ this(a_name);
+ type = a_type;
+ modifier = a_modifier;
+ value = a_default;
+ values = allowed_values;
+ next = a_next;
+ }
+
+ /**
+ * Get the modifier of this attribute. This field contains one of the
+ * following DTD constants:
+ * <ul>
+ * <li> REQUIRED if the attribute value is always required,</li>
+ * <li> IMPLIED if the user agent must supply the default value itself,</li>
+ * <li> FIXED if the attribute value is fixed to some value and cannot
+ * be changed.</li>
+ * <li> DEFAULT if the attribute default value has been supplied.</li>
+ * <li> CURRENT the value that at any point in the document is
+ * the last value supplied for that element. A value is required to be
+ * supplied for the first* occurrence of an element</li>
+ * <li> CONREF specifies the IDREF value of
+ * the reference to content in another location of the document.
+ * The element with this attribute is empty, the content from
+ * that another location must be used instead.</li>
+ * </ul>
+ */
+ public int getModifier()
+ {
+ return modifier;
+ }
+
+ /**
+ * Get the name of the attribute.
+ * The value is returned as it was supplied to a
+ * constructor, preserving the character case.
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Get the value of ( = pointer to ) the next attribute in the linked list,
+ * storing all attributes of some Element. Contains null for the
+ * last attribute.
+ */
+ public AttributeList getNext()
+ {
+ return next;
+ }
+
+ /**
+ * Get the type of the attribute. The possible values of this field
+ * (NUMBER, NAME, ID, CDATA and so on) are defined in DTDConstants.
+ */
+ public int getType()
+ {
+ return type;
+ }
+
+ /**
+ * Get the default value of this attribute.
+ */
+ public String getValue()
+ {
+ return value;
+ }
+
+ /**
+ * Get the allowed values of this attribute.
+ */
+ public Enumeration getValues()
+ {
+ return values.elements();
+ }
+
+ /**
+ * Converts a string value, representing a valid SGLM attribute type,
+ * into the corresponding value, defined in DTDConstants.
+ * @param typeName the name of the type (character case is ignored).
+ * @return a value from DTDConstants or DTDConstants.ANY if the
+ * string is not representing a known type. The known attribute types
+ * in this implementation are CDATA, ENTITY, ENTITIES, ID, IDREF, IDREFS,
+ * NAME, NAMES, NMTOKEN, NMTOKENS, NOTATION, NUMBER, NUMBERS, NUTOKEN and
+ * NUTOKENS.
+ * @throws NullPointerException if the passed parameter is null.
+ */
+ public static int name2type(String typeName)
+ {
+ return mapper.get(typeName.toUpperCase());
+ }
+
+ /**
+ * Returns the attribute name.
+ */
+ public String toString()
+ {
+ return name;
+ }
+
+ /**
+ * Converts a value from DTDConstants into the string representation.
+ * @param type - an integer value of the public static integer field,
+ * defined in the DTDConstants class.
+ * @return a corresponding SGML DTD keyword (UPPERCASE) or null if there
+ * are no attribute type constant having the given value.
+ */
+ public static String type2name(int type)
+ {
+ return mapper.get(type);
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/parser/ContentModel.java b/libjava/classpath/javax/swing/text/html/parser/ContentModel.java
new file mode 100644
index 00000000000..deb7b1602bb
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/ContentModel.java
@@ -0,0 +1,218 @@
+/* ContentModel.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html.parser;
+
+import gnu.javax.swing.text.html.parser.models.transformer;
+
+import java.io.Serializable;
+
+import java.util.Vector;
+
+/**
+ * A representation of the element content. The instances of this class
+ * can be arranged into the linked list, representing a BNF expression.
+ * The content model is constructed as a branched tree structure in the
+ * following way:
+ * <pre>
+ * a = new ContentModel('+', A, null); // a reprensents A+
+ * b = new ContentModel('&amp;', B, a); // b represents B &amp; A+
+ * c = new ContentModel('*', b, null); // c represents ( B &amp; A+) *
+ * d = new ContentModel('|', new ContentModel('*', A, null),
+ * new ContentModel('?', B, null)); // d represents ( A* | B? )
+ * </pre>
+ * where the valid operations are:
+ * <ul>
+ * <li><code>E* </code> E occurs zero or more times</li>
+ * <li><code>E+ </code> E occurs one or more times</li>
+ * <li><code>E? </code> E occurs once or not atl all</li>
+ * <li><code>A,B</code> A occurs before B</li>
+ * <li><code>A|B</code> both A and B are permitted in any order.
+ * The '|' alone does not permit the repetetive occurence of A or B
+ * (use <code>(A|B)*</code>.</li>
+ * <li><code>A&amp;B</code> both A and B must occur once (in any order)</li>
+ * </ul>
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public final class ContentModel
+ implements Serializable
+{
+ /** Use serialVersionUID for interoperability. */
+ private static final long serialVersionUID = -1130825523866321257L;
+
+ /**
+ * The next content model model ( = pointer to the next element of
+ * the linked list) for the binary expression (',','&amp;' or '|'). Null
+ * for the last element in the list.
+ */
+ public ContentModel next;
+
+ /**
+ * The document content, containing either Element or the enclosed
+ * content model (that would be in the parentheses in BNF expression).
+ */
+ public Object content;
+
+ /**
+ * Specifies the BNF operation between this node and the node,
+ * stored in the field <code>next</code> (or for this node, if it is
+ * an unary operation.
+ */
+ public int type;
+
+ /** Create a content model initializing all fields to default values. */
+ public ContentModel()
+ {
+ }
+
+ /**
+ * Create a content model, consisting of the single element.
+ * Examples:
+ *<code>
+ * a = new ContentModel('+', A, null); // a reprensents A+
+ * b = new ContentModel('&amp;', B, a); // b represents B &amp; A+
+ * c = new ContentModel('*', b, null); // c represents ( B &amp; A+) *
+ * d = new ContentModel('|', A,
+ * new ContentModel('?',b, null);
+ * // d represents
+ * </code>
+ */
+ public ContentModel(Element a_content)
+ {
+ content = a_content;
+ }
+
+ /**
+ * Create a content model, involving expression of the given type.
+ * @param a_type The expression operation type ('*','?' or '+'
+ * @param a_content The content for that the expression is applied.
+ */
+ public ContentModel(int a_type, ContentModel a_content)
+ {
+ content = a_content;
+ type = a_type;
+ }
+
+ /**
+ * Create a content model, involving binary expression of the given type.
+ * @param a_type The expression operation type ( ',', '|' or '&amp;').
+ * @param a_content The content of the left part of the expression.
+ * @param a_next The content model, representing the right part of the
+ * expression.
+ */
+ public ContentModel(int a_type, Object a_content, ContentModel a_next)
+ {
+ content = a_content;
+ type = a_type;
+ next = a_next;
+ }
+
+ /**
+ * Adds all list elements to the given vector, ignoring the
+ * operations between the elements. The old vector values are not
+ * discarded.
+ * @param elements - a vector to add the values to.
+ */
+ public void getElements(Vector elements)
+ {
+ ContentModel c = this;
+
+ while (c != null)
+ {
+ elements.add(c.content);
+ c = c.next;
+ }
+ }
+
+ /**
+ * Checks if the content model matches an empty input stream.
+ * The empty content is created using SGML DTD keyword EMPTY.
+ * The empty model is a model with the content field equal to null.
+ *
+ * @return true if the content field is equal to null.
+ */
+ public boolean empty()
+ {
+ return content == null;
+ }
+
+ /**
+ * Get the element, stored in the <code>next.content</code>.
+ * The method is programmed as the part of the standard API, but not
+ * used in this implementation.
+ * @return the value of the field <code>next</code>.
+ */
+ public Element first()
+ {
+ return (Element) next.content;
+ }
+
+ /**
+ * Checks if this object can potentially be the first token in the
+ * ContenModel list. The method is programmed as the part of the
+ * standard API, but not used in this implementation.
+ */
+ public boolean first(Object token)
+ {
+ ContentModel c = this;
+ while (c.next != null)
+ {
+ if (c.content != null && c.content.toString().equals(token.toString()) &&
+ c.type != ','
+ )
+
+ // Agree if the operation with the preceeding element
+ // is not the comma operation.
+ return true;
+ c = c.next;
+ }
+ return false;
+ }
+
+ /**
+ * Returns a string representation (an expression) of this content model.
+ * The expression has BNF-like syntax, except the absence of the
+ * unary operator is additionally indicated by " ' ". It is
+ * advisable to check the created models for correctness using this
+ * method.
+ */
+ public String toString()
+ {
+ return transformer.transform(this).toString();
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/parser/DTD.java b/libjava/classpath/javax/swing/text/html/parser/DTD.java
new file mode 100644
index 00000000000..63d03eaccf0
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/DTD.java
@@ -0,0 +1,607 @@
+/* DTD.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html.parser;
+
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.BitSet;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * <p>Representation or the SGML DTD document.
+ * Provides basis for describing a syntax of the
+ * HTML documents. The fields of this class are NOT initialized in
+ * constructor. You need to do this separately before passing this data
+ * structure to the HTML parser. The subclasses with the fields, pre-
+ * initialized, for example, for HTML 4.01, can be available only between
+ * the implementation specific classes
+ * ( for example, {@link gnu.javax.swing.text.html.parser.HTML_401F }
+ * in this 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}.
+ * We also recommend Goldfarb C.F (1991) <i>The SGML Handbook</i>,
+ * Oxford University Press, 688 p, ISBN: 0198537379.
+ * </p>
+ * <p>
+ * Warning: the html, head and other tag fields will only be automatically
+ * assigned if the VM has the correctly implemented reflection mechanism.
+ * As these fields are not used anywhere in the implementation, not
+ * exception will be thrown in the opposite case.
+ * </p>
+ *
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public class DTD
+ implements DTDConstants
+{
+ /**
+ * The version of the persistent data format.
+ */
+ public static int FILE_VERSION = 1;
+
+ /**
+ * The table of existing available DTDs.
+ */
+ static Hashtable dtdHash = new Hashtable();
+
+ /**
+ * The applet element for this DTD.
+ */
+ public Element applet;
+
+ /**
+ * The base element for this DTD.
+ */
+ public Element base;
+
+ /**
+ * The body element for this DTD.
+ */
+ public Element body;
+
+ /**
+ * The head element for this DTD.
+ */
+ public Element head;
+
+ /**
+ * The html element for this DTD.
+ */
+ public Element html;
+
+ /**
+ * The isindex element of for this DTD.
+ */
+ public Element isindex;
+
+ /**
+ * The meta element for this DTD.
+ */
+ public Element meta;
+
+ /**
+ * The p element for this DTD.
+ */
+ public Element p;
+
+ /**
+ * The param element for this DTD.
+ */
+ public Element param;
+
+ /**
+ * The pcdata for this DTD.
+ */
+ public Element pcdata;
+
+ /**
+ * The title element for this DTD.
+ */
+ public Element title;
+
+ /**
+ * The element for accessing all DTD elements by name.
+ */
+ public Hashtable elementHash = new Hashtable();
+
+ /**
+ * The entity table for accessing all DTD entities by name.
+ */
+ public Hashtable entityHash = new Hashtable();
+
+ /**
+ * The name of this DTD.
+ */
+ public String name;
+
+ /**
+ * Contains all elements in this DTD. The
+ * javax.swing.text.html.parser.Element#index field of all elements
+ * in this vector is set to the element position in this vector.
+ */
+ public Vector elements = new Vector();
+
+ /** Create a new DTD with the specified name. */
+ protected DTD(String a_name)
+ {
+ name = a_name;
+ }
+
+ /** Get this DTD by name. The current implementation
+ * only looks in the internal table of DTD documents. If no corresponding
+ * entry is found, the new entry is created, placed into
+ * the table and returned. */
+ public static DTD getDTD(String name)
+ throws IOException
+ {
+ DTD d = (DTD) dtdHash.get(name);
+
+ if (d == null)
+ {
+ d = new DTD(name);
+ dtdHash.put(d.name, d);
+ }
+
+ return d;
+ }
+
+ /**
+ * Get the element by the element name. If the element is not yet
+ * defined, it is newly created and placed into the element table.
+ * If the element name matches (ingoring case) a public non static
+ * element field in this class, this field is assigned to the value
+ * of the newly created element.
+ */
+ public Element getElement(String element_name)
+ {
+ return newElement(element_name);
+ }
+
+ /**
+ * Get the element by the value of its
+ * {@link javax.swing.text.html.parser.Element#index} field.
+ */
+ public Element getElement(int index)
+ {
+ return (Element) elements.get(index);
+ }
+
+ /**
+ * Get the entity with the given identifier.
+ * @param id that can be returned by
+ * {@link javax.swing.text.html.parser.Entity#name2type(String an_entity)}
+ * @return The entity from this DTD or null if there is no entity with
+ * such id or such entity is not present in the table of this instance.
+ */
+ public Entity getEntity(int id)
+ {
+ String name = Entity.mapper.get(id);
+
+ if (name != null)
+ return (Entity) entityHash.get(name);
+ else
+ return null;
+ }
+
+ /**
+ * Get the named entity by its name.
+ */
+ public Entity getEntity(String entity_name)
+ {
+ return (Entity) entityHash.get(entity_name);
+ }
+
+ /**
+ * Get the name of this instance of DTD
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Creates, adds into the entity table and returns the
+ * character entity like <code>&amp;lt;</code>
+ * (means '<code>&lt;</code>' );
+ * @param name The entity name (without heading &amp; and closing ;)
+ * @param type The entity type
+ * @param character The entity value (single character)
+ * @return The created entity
+ */
+ public Entity defEntity(String name, int type, int character)
+ {
+ Entity e = newEntity(name, type);
+ e.data = new char[] { (char) character };
+ return e;
+ }
+
+ /**
+ * Define the attributes for the element with the given name.
+ * If the element is not exist, it is created.
+ * @param forElement
+ * @param attributes
+ */
+ public void defineAttributes(String forElement, AttributeList attributes)
+ {
+ Element e = (Element) elementHash.get(forElement.toLowerCase());
+
+ if (e == null)
+ e = newElement(forElement);
+
+ e.atts = attributes;
+ }
+
+ /**
+ * Defines the element and adds it to the element table. Sets the
+ * <code>Element.index</code> field to the value, unique for this
+ * instance of DTD. If the element with the given name already exists,
+ * replaces all other its settings by the method argument values.
+ * @param name the name of the element
+ * @param type the type of the element
+ * @param headless true if the element needs no starting tag
+ * (should not occur in HTML).
+ * @param tailless true if the element needs no ending tag (like
+ * <code>&lt;hr&gt;</code>
+ * @param content the element content
+ * @param exclusions the set of elements that must not occur inside
+ * this element. The <code>Element.index</code> value defines which
+ * bit in this bitset corresponds to that element.
+ * @param inclusions the set of elements that can occur inside this
+ * element. the <code>Element.index</code> value defines which
+ * bit in this bitset corresponds to that element.
+ * @param attributes the element attributes.
+ * @return the newly defined element.
+ */
+ public Element defineElement(String name, int type, boolean headless,
+ boolean tailless, ContentModel content,
+ BitSet exclusions, BitSet inclusions,
+ AttributeList attributes
+ )
+ {
+ Element e = newElement(name);
+ e.type = type;
+ e.oStart = headless;
+ e.oEnd = tailless;
+ e.content = content;
+ e.exclusions = exclusions;
+ e.inclusions = inclusions;
+ e.atts = attributes;
+
+ return e;
+ }
+
+ /**
+ * Creates, intializes and adds to the entity table the new
+ * entity.
+ * @param name the name of the entity
+ * @param type the type of the entity
+ * @param data the data section of the entity
+ * @return the created entity
+ */
+ public Entity defineEntity(String name, int type, char[] data)
+ {
+ Entity e = newEntity(name, type);
+ e.data = data;
+
+ return e;
+ }
+
+ /** Place this DTD into the DTD table. */
+ public static void putDTDHash(String name, DTD dtd)
+ {
+ dtdHash.put(name, dtd);
+ }
+
+ /**
+ * <p>Reads DTD from an archived format. This format is not standardized
+ * and differs between implementations.</p><p> This implementation
+ * reads and defines all entities and elements using
+ * ObjectInputStream. The elements and entities can be written into the
+ * stream in any order. The objects other than elements and entities
+ * are ignored.</p>
+ * @param stream A data stream to read from.
+ * @throws java.io.IOException If one is thrown by the input stream
+ */
+ public void read(DataInputStream stream)
+ throws java.io.IOException
+ {
+ ObjectInputStream oi = new ObjectInputStream(stream);
+ Object def;
+ try
+ {
+ while (true)
+ {
+ def = oi.readObject();
+ if (def instanceof Element)
+ {
+ Element e = (Element) def;
+ elementHash.put(e.name.toLowerCase(), e);
+ assignField(e);
+ }
+ else if (def instanceof Entity)
+ {
+ Entity e = (Entity) def;
+ entityHash.put(e.name, e);
+ }
+ }
+ }
+ catch (ClassNotFoundException ex)
+ {
+ throw new IOException(ex.getMessage());
+ }
+ catch (EOFException ex)
+ {
+ // ok EOF
+ }
+ }
+
+ /**
+ * Returns the name of this instance of DTD.
+ */
+ public String toString()
+ {
+ return name;
+ }
+
+ /**
+ * Creates and returns new attribute (not an attribute list).
+ * @param name the name of this attribute
+ * @param type the type of this attribute (FIXED, IMPLIED or
+ * REQUIRED from <code>DTDConstants</code>).
+ * @param modifier the modifier of this attribute
+ * @param default_value the default value of this attribute
+ * @param allowed_values the allowed values of this attribute. The multiple
+ * possible values in this parameter are supposed to be separated by
+ * '|', same as in SGML DTD <code>&lt;!ATTLIST </code>tag. This parameter
+ * can be null if no list of allowed values is specified.
+ * @param atts the previous attribute of this element. This is
+ * placed to the field
+ * {@link javax.swing.text.html.parser.AttributeList#next },
+ * creating a linked list.
+ * @return
+ */
+ protected AttributeList defAttributeList(String name, int type, int modifier,
+ String default_value,
+ String allowed_values,
+ AttributeList atts
+ )
+ {
+ AttributeList al = new AttributeList(name);
+ al.modifier = modifier;
+ al.value = default_value;
+ al.next = atts;
+
+ if (allowed_values != null)
+ {
+ StringTokenizer st = new StringTokenizer(allowed_values, " \t|");
+ Vector v = new Vector(st.countTokens());
+
+ while (st.hasMoreTokens())
+ v.add(st.nextToken());
+
+ al.values = v;
+ }
+
+ return al;
+ }
+
+ /**
+ * Creates a new content model.
+ * @param type specifies the BNF operation for this content model.
+ * The valid operations are documented in the
+ * {@link javax.swing.text.html.parser.ContentModel#type }.
+ * @param content the content of this content model
+ * @param next if the content model is specified by BNF-like
+ * expression, contains the rest of this expression.
+ * @return The newly created content model.
+ */
+ protected ContentModel defContentModel(int type, Object content,
+ ContentModel next
+ )
+ {
+ ContentModel model = new ContentModel();
+ model.type = type;
+ model.next = next;
+ model.content = content;
+
+ return model;
+ }
+
+ /**
+ * Defines a new element and adds it to the element table.
+ * If the element alredy exists,
+ * overrides it settings with the specified values.
+ * @param name the name of the new element
+ * @param type the type of the element
+ * @param headless true if the element needs no starting tag
+ * @param tailless true if the element needs no closing tag
+ * @param content the element content.
+ * @param exclusions the elements that must be excluded from the
+ * content of this element, in all levels of the hierarchy.
+ * @param inclusions the elements that can be included as the
+ * content of this element.
+ * @param attributes the element attributes.
+ * @return the created or updated element.
+ */
+ protected Element defElement(String name, int type, boolean headless,
+ boolean tailless, ContentModel content,
+ String[] exclusions, String[] inclusions,
+ AttributeList attributes
+ )
+ {
+ // compute the bit sets
+ BitSet exclude = bitSet(exclusions);
+ BitSet include = bitSet(inclusions);
+
+ Element e =
+ defineElement(name, type, headless, tailless, content, exclude, include,
+ attributes
+ );
+
+ return e;
+ }
+
+ /**
+ * Creates, intializes and adds to the entity table the new
+ * entity.
+ * @param name the name of the entity
+ * @param type the type of the entity
+ * @param data the data section of the entity
+ * @return the created entity
+ */
+ protected Entity defEntity(String name, int type, String data)
+ {
+ Entity e = newEntity(name, type);
+ e.data = data.toCharArray();
+
+ return e;
+ }
+
+ private void assignField(Element e)
+ {
+ String element_name = e.name;
+ try
+ {
+ // Assign the field via reflection.
+ Field f = getClass().getField(element_name.toLowerCase());
+ if ((f.getModifiers() & Modifier.PUBLIC) != 0)
+ if ((f.getModifiers() & Modifier.STATIC) == 0)
+ if (f.getType().isAssignableFrom(e.getClass()))
+ f.set(this, e);
+ }
+ catch (IllegalAccessException ex)
+ {
+ unexpected(ex);
+ }
+ catch (NoSuchFieldException ex)
+ {
+ // This is ok.
+ }
+
+ // Some virtual machines may still lack the proper
+ // implementation of reflection. As the tag fields
+ // are not used anywhere in this implementation,
+ // (and this class is also rarely used by the end user),
+ // it may be better not to crash everything by throwing an error
+ // for each case when the HTML parsing is required.
+ catch (Throwable t)
+ {
+ // This VM has no reflection mechanism implemented!
+ if (t instanceof OutOfMemoryError)
+ throw (Error) t;
+ }
+ }
+
+ /**
+ * Create the bit set for this array of elements.
+ * The unknown elements are automatically defined and added
+ * to the element table.
+ * @param elements
+ * @return
+ */
+ private BitSet bitSet(String[] elements)
+ {
+ BitSet b = new BitSet();
+
+ for (int i = 0; i < elements.length; i++)
+ {
+ Element e = getElement(elements [ i ]);
+
+ if (e == null)
+ e = newElement(elements [ i ]);
+
+ b.set(e.index);
+ }
+
+ return b;
+ }
+
+ /**
+ * Find the element with the given name in the element table.
+ * If not find, create a new element with this name and add to the
+ * table.
+ * @param name the name of the element
+ * @return the found or created element.
+ */
+ private Element newElement(String name)
+ {
+ Element e = (Element) elementHash.get(name.toLowerCase());
+
+ if (e == null)
+ {
+ e = new Element();
+ e.name = name;
+ e.index = elements.size();
+ elements.add(e);
+ elementHash.put(e.name.toLowerCase(), e);
+ assignField(e);
+ }
+ return e;
+ }
+
+ /**
+ * Creates and adds to the element table the entity with an
+ * unitialized data section. Used internally.
+ * @param name the name of the entity
+ * @param type the type of the entity, a bitwise combination
+ * of GENERAL, PARAMETER, SYSTEM and PUBLIC.
+ * @throws an error if the parameter is both GENERAL and PARAMETER
+ * of both PUBLIC and SYSTEM.
+ * @return the created entity
+ */
+ private Entity newEntity(String name, int type)
+ {
+ Entity e = new Entity(name, type, null);
+ entityHash.put(e.name, e);
+ return e;
+ }
+
+ private void unexpected(Exception ex)
+ {
+ throw new Error("This should never happen, report a bug", ex);
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java b/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java
new file mode 100644
index 00000000000..a771264a1ad
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java
@@ -0,0 +1,290 @@
+/* DTDConstants.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html.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,
+ * 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}.
+ * We also recommend Goldfarb C.F (1991) <i>The SGML Handbook</i>,
+ * Oxford University Press, 688 p, ISBN: 0198537379.
+ * </p>
+ *
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public interface DTDConstants
+{
+ /* ----- The data types, used in HTML 4.01 SGML definition: ---- */
+
+ /**
+ * The CDATA (Character data) constant, specifes the content model,
+ * consisting of characters only. In SGML for HTML 4.01, the character
+ * entities must be replaced by characters, the line feeds must be
+ * ignored and any number of the subsequent carriage returns or tabs
+ * must be replaced by a single space.
+ */
+ int CDATA = 1;
+
+ /**
+ * The EMPTY constant, means the element with no content.
+ */
+ int EMPTY = 17;
+
+ /**
+ * The ID constant, means that the token is the unique identifier.
+ * This identifier can be referenced by attribute with value of IDREF.
+ * The identifier must begin with letter, followed by any number of
+ * letters, digits, hyphens, underscores, colons and periods.
+ */
+ int ID = 4;
+
+ /**
+ * The IDREF constant, specifies reference to a valid ID within
+ * the document.
+ */
+ int IDREF = 5;
+
+ /**
+ * The IDREFS constant, a space separated list of IDREFs
+ */
+ int IDREFS = 6;
+
+ /**
+ * The NAME constant, means the token that
+ * must begin with letter, followed by any number of
+ * letters, digits, hyphens, underscores, colons and periods.
+ */
+ int NAME = 7;
+
+ /**
+ * The NAMES constant, specifies a space separated of NAMEs.
+ */
+ int NAMES = 8;
+
+ /**
+ * The NMTOKEN constant, specifies the attribute, consisting of
+ * characters that can be either digits or alphabetic characters).
+ */
+ int NMTOKEN = 9;
+
+ /**
+ * The NMTOKENS constant, specifies a list of NMTOKENs.
+ */
+ int NMTOKENS = 10;
+
+ /**
+ * The NOTATION constant, a previously defined data type.
+ */
+ int NOTATION = 11;
+
+ /**
+ * The NUMBER constant (means that the attribute consists of at least
+ * one decimal digit).
+ */
+ int NUMBER = 12;
+
+ /**
+ * The NUMBERS constant, specifies a space separated list of NUMBERs.
+ */
+ int NUMBERS = 13;
+
+ /**
+ * The NUTOKEN constant.
+ */
+ int NUTOKEN = 14;
+
+ /**
+ * The NUTOKENS constant.
+ */
+ int NUTOKENS = 15;
+
+ /* -------
+ The entity scope constants.
+ As these four constants are combined with the bitwise OR,
+ they are defined in the hexadecimal notation.
+ The reason of setting the two bits at once (for PUBLIC and SYSTEM)
+ is probably historical. ----- */
+
+ /**
+ * The PUBLIC constant, specifies the public entity. The PUBLIC entities
+ * are assumed to be known to many systems so that a full declaration
+ * need not be transmitted. For example,
+ * &lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"&gt;
+ */
+ int PUBLIC = 0xA;
+
+ /**
+ * The SYSTEM constant, specifies the system entitiy. The system entities
+ * are assumed to be known but require the clear identifer
+ * (like the file path), where they can be found in the system.
+ * For example, <code>
+ * &lt;DOCTYPE html SYSTEM "/path/to/file.dtd"&gt; </code>.
+ */
+ int SYSTEM = 0x11;
+
+ /**
+ * The PARAMETER constant, specifies that entity is only valid
+ * inside SGML DTD scope.
+ */
+ int PARAMETER = 0x40000;
+
+ /**
+ * The GENERAL constant, specifies theat the entity is valid in the
+ * whole HTML document scope.
+ */
+ int GENERAL = 0x10000;
+
+ /* ---- The constants, defining if the element attribute is required,
+ fixed or implied. ---- */
+
+ /**
+ * The attribute modifier #REQUIRED constant, indicates that the
+ * value must be supplied.
+ */
+ int REQUIRED = 2;
+
+ /**
+ * The attribute modifier #FIXED constant, means that the attribute has
+ * the fixed value that cannot be changed.
+ */
+ int FIXED = 1;
+
+ /**
+ * The attribute modifier #IMPLIED constant,
+ * indicating that for this attribute the user agent must provide
+ * the value itself.
+ */
+ int IMPLIED = 5;
+
+ /**
+ * The attribute modifier #CURRENT constant, specifies the value
+ * that at any point in the document is the last value supplied for
+ * that element. A value is required to be supplied for the first
+ * occurrence of an element
+ */
+ int CURRENT = 3;
+
+ /**
+ * The attribute modifier #CONREF constant, specifies the IDREF value of
+ * the reference to content in another location of the document.
+ * The element with this attribute is empty, the content from
+ * that another location must be used instead.
+ */
+ int CONREF = 4;
+
+ /* ----- Constants, defining if the element
+ start and end tags are required. ---- */
+
+ /**
+ * The STARTTAG, meaning that the element needs a starting tag.
+ */
+ int STARTTAG = 13;
+
+ /**
+ * The ENDTAG constant, meaning that the element needs a closing tag.
+ */
+ int ENDTAG = 14;
+
+ /* ----- Other constants: ----- */
+
+ /**
+ * The ANY constant, specifies
+ * an attribute, consisting from arbitrary characters.
+ */
+ int ANY = 19;
+
+ /**
+ * The DEFAULT constant, specifies the default value.
+ */
+ int DEFAULT = 131072;
+
+ /**
+ * The ENTITIES constant (list of ENTITYes)
+ */
+ int ENTITIES = 3;
+
+ /**
+ * The ENTITY constant, meaning the numeric or symbolic name of some
+ * HTML data.
+ */
+ int ENTITY = 2;
+
+ /**
+ * The MD constant.
+ */
+ int MD = 16;
+
+ /**
+ * The MODEL constant.
+ */
+ int MODEL = 18;
+
+ /**
+ * The MS constant.
+ */
+ int MS = 15;
+
+ /**
+ * The PI (Processing Instruction) constant, specifies a processing
+ * instruction. Processing instructions are used to embed information
+ * intended for specific applications.
+ */
+ int PI = 12;
+
+ /**
+ * The RCDATA constant (Entity References and Character Data), specifies
+ * the content model, consisting of characters AND entities. The
+ * "&lt;" is threated as an ordinary character, but
+ * "<code>&amp;name;</code>" still means the general entity with
+ * the given name.
+ */
+ int RCDATA = 16;
+
+ /**
+ * The SDATA constant. Means that the value contains the entity name
+ * and the replacement value of a character entity reference.
+ */
+ int SDATA = 11;
+}
diff --git a/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java b/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java
new file mode 100644
index 00000000000..c706f4d0f0b
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java
@@ -0,0 +1,261 @@
+/* DocumentParser.java -- A parser for HTML documents.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html.parser;
+
+import gnu.javax.swing.text.html.parser.htmlAttributeSet;
+import javax.swing.text.html.parser.Parser;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.html.HTMLEditorKit;
+
+/**
+ * <p>A simple error-tolerant HTML parser that uses a DTD document
+ * to access data on the possible tokens, arguments and syntax.</p>
+ * <p> The parser reads an HTML content from a Reader and calls various
+ * notifying methods (which should be overridden in a subclass)
+ * when tags or data are encountered.</p>
+ * <p>Some HTML elements need no opening or closing tags. The
+ * task of this parser is to invoke the tag handling methods also when
+ * the tags are not explicitly specified and must be supposed using
+ * information, stored in the DTD.
+ * For example, parsing the document
+ * <p>&lt;table&gt;&lt;tr&gt;&lt;td&gt;a&lt;td&gt;b&lt;td&gt;c&lt;/tr&gt; <br>
+ * will invoke exactly the handling methods exactly in the same order
+ * (and with the same parameters) as if parsing the document: <br>
+ * <em>&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;table&gt;&lt;
+ * tbody&gt;</em>&lt;tr&gt;&lt;td&gt;a<em>&lt;/td&gt;</em>&lt;td&gt;b<em>
+ * &lt;/td&gt;</em>&lt;td&gt;c<em>&lt;/td&gt;&lt;/tr&gt;</em>&lt;
+ * <em>/tbody&gt;&lt;/table&gt;&lt;/body&gt;&lt;/html&gt;</em></p>
+ * (supposed tags are given in italics). The parser also supports
+ * obsolete elements of HTML syntax.<p>
+ * </p>
+ * In this implementation, DocumentParser is directly derived from its
+ * ancestor without changes of functionality.
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public class DocumentParser
+ extends Parser
+ implements DTDConstants
+{
+ /**
+ * The enclosed working parser class.
+ */
+ private class gnuParser
+ extends gnu.javax.swing.text.html.parser.support.Parser
+ {
+ private gnuParser(DTD d)
+ {
+ super(d);
+ }
+
+ protected final void handleComment(char[] comment)
+ {
+ parser.handleComment(comment);
+ callBack.handleComment(comment, hTag.where.startPosition);
+ }
+
+ protected final void handleEmptyTag(TagElement tag)
+ throws javax.swing.text.ChangedCharSetException
+ {
+ parser.handleEmptyTag(tag);
+ callBack.handleSimpleTag(tag.getHTMLTag(), getAttributes(),
+ hTag.where.startPosition
+ );
+ }
+
+ protected final void handleEndTag(TagElement tag)
+ {
+ parser.handleEndTag(tag);
+ callBack.handleEndTag(tag.getHTMLTag(), hTag.where.startPosition);
+ }
+
+ protected final void handleError(int line, String message)
+ {
+ parser.handleError(line, message);
+ callBack.handleError(message, hTag.where.startPosition);
+ }
+
+ protected final void handleStartTag(TagElement tag)
+ {
+ parser.handleStartTag(tag);
+ htmlAttributeSet attributes = gnu.getAttributes();
+
+ if (tag.fictional())
+ attributes.addAttribute(HTMLEditorKit.ParserCallback.IMPLIED,
+ Boolean.TRUE
+ );
+
+ callBack.handleStartTag(tag.getHTMLTag(), attributes,
+ hTag.where.startPosition
+ );
+ }
+
+ protected final void handleText(char[] text)
+ {
+ parser.handleText(text);
+ callBack.handleText(text, hTag.where.startPosition);
+ }
+
+ DTD getDTD()
+ {
+ return dtd;
+ }
+ }
+
+ /**
+ * This field is used to access the identically named
+ * methods of the outer class.
+ * This is package-private to avoid an accessor method.
+ */
+ DocumentParser parser = this;
+
+ /**
+ * The callback.
+ * This is package-private to avoid an accessor method.
+ */
+ HTMLEditorKit.ParserCallback callBack;
+
+ /**
+ * The reference to the working class of HTML parser that is
+ * actually used to parse the document.
+ * This is package-private to avoid an accessor method.
+ */
+ gnuParser gnu;
+
+ /**
+ * Creates a new parser that uses the given DTD to access data on the
+ * possible tokens, arguments and syntax. There is no single - step way
+ * 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() }.
+ * @param a_dtd a DTD to use.
+ */
+ public DocumentParser(DTD a_dtd)
+ {
+ super(a_dtd);
+ gnu = new gnuParser(a_dtd);
+ }
+
+ /**
+ * 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
+ * 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,
+ boolean ignoreCharSet
+ )
+ throws IOException
+ {
+ callBack = a_callback;
+ gnu.parse(reader);
+
+ callBack.handleEndOfLineString(gnu.getEndOfLineSequence());
+ try
+ {
+ callBack.flush();
+ }
+ catch (BadLocationException ex)
+ {
+ // Convert this into the supported type of exception.
+ throw new IOException(ex.getMessage());
+ }
+ }
+
+ /**
+ * Handle HTML comment. The default method returns without action.
+ * @param comment the comment being handled
+ */
+ protected void handleComment(char[] comment)
+ {
+ }
+
+ /**
+ * 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 tag the tag being handled.
+ * @throws javax.swing.text.ChangedCharSetException
+ */
+ protected void handleEmptyTag(TagElement tag)
+ throws javax.swing.text.ChangedCharSetException
+ {
+ }
+
+ /**
+ * 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
+ */
+ protected void handleEndTag(TagElement tag)
+ {
+ }
+
+ /* Handle error that has occured in the given line. */
+ protected void handleError(int line, String message)
+ {
+ }
+
+ /**
+ * 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
+ */
+ protected void handleStartTag(TagElement tag)
+ {
+ }
+
+ /**
+ * Handle the text section.
+ * @param text a section text.
+ */
+ protected void handleText(char[] text)
+ {
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/parser/Element.java b/libjava/classpath/javax/swing/text/html/parser/Element.java
new file mode 100644
index 00000000000..f0a0f3303cb
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/Element.java
@@ -0,0 +1,317 @@
+/* Element.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html.parser;
+
+import gnu.javax.swing.text.html.parser.support.gnuStringIntMapper;
+
+import java.io.Serializable;
+
+import java.util.BitSet;
+
+/**
+ * <p>
+ * Stores the element information, obtained by parsing SGML DTD
+ * tag <code>&lt;!ELEMENT .. &gt;</code>. This class has no public
+ * constructor and can only be instantiated using the
+ * {@link javax.swing.text.html.parser.DTD } methods</p>
+ *
+ * <p>SGML defines elements that represent structures or
+ * behavior. An element typically consists of a start tag, content, and an
+ * end tag. Hence the elements are not tags. The HTML 4.0 definition specifies
+ * that some elements are not required to have the end tags. Also, some
+ * HTML elements (like <code>&lt;hr&gt;</code>) have no content. Element names
+ * are case sensitive.</p>
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public final class Element
+ implements DTDConstants, Serializable
+{
+ /**
+ * Package level mapper between type names and they string values.
+ */
+ static final gnuStringIntMapper mapper =
+ new gnuStringIntMapper()
+ {
+ protected void create()
+ {
+ add("CDATA", DTDConstants.CDATA);
+ add("RCDATA", DTDConstants.RCDATA);
+ add("EMPTY", DTDConstants.EMPTY);
+ add("ANY", DTDConstants.ANY);
+ }
+ };
+
+ /** Use serialVersionUID for interoperability. */
+ private static final long serialVersionUID = -6717939384601675586L;
+
+ /**
+ * The element attributes.
+ */
+ public AttributeList atts;
+
+ /**
+ * Contains refernces to elements that must NOT occur inside this element,
+ * at any level of hierarchy.
+ */
+ public BitSet exclusions;
+
+ /**
+ * Contains refernces to elements that must CAN occur inside this element,
+ * at any level of hierarchy.
+ */
+ public BitSet inclusions;
+
+ /**
+ * The content model, defining elements, entities and DTD text
+ * that may/may not occur inside this element.
+ */
+ public ContentModel content;
+
+ /**
+ * A field to store additional user data for this Element.
+ */
+ public Object data;
+
+ /**
+ * The element name.
+ */
+ public String name;
+
+ /**
+ * True is this element need not to have the closing tag, false
+ * otherwise. The HTML 4.0 definition specifies
+ * that some elements (like <code>&lt;hr&gt;</code>are
+ * not required to have the end tags.
+ */
+ public boolean oEnd;
+
+ /**
+ * True is this element need not to have the starting tag, false
+ * otherwise. The HTML 4.0 definition specifies
+ * that some elements (like <code>&lt;head&gt;</code> or
+ * <code>&lt;body&gt;</code>) are
+ * not required to have the start tags.
+
+ */
+ public boolean oStart;
+
+ /**
+ * This field contains the unique integer identifier of this Element,
+ * used to refer the element (more exactly, the element flag)
+ * in <code>inclusions</code> and <code>exclusions</code> bit set.
+ */
+ public int index;
+
+ /**
+ * The element type, containing value, defined in DTDConstants.
+ * In this implementation, the element type can be
+ * CDATA, RCDATA, EMPTY or ANY.
+ */
+ public int type;
+
+ /**
+ * The default constructor must have package level access in this
+ * class. Use DTD.defineElement(..) to create an element when required.
+ * @todo MAKE THIS PACKAGE in the final version. Now the Parser needs it!
+ */
+ Element()
+ {
+ }
+
+ /**
+ * Converts the string representation of the element type
+ * into its unique integer identifier, defined in DTDConstants.
+ * @param a_type A name of the type
+ * @return DTDConstants.CDATA, DTDConstants.RCDATA, DTDConstants.EMPTY,
+ * DTDConstants.ANY or null if the type name is not
+ * "CDATA", "RCDATA", "EMPTY" or "ANY". This function is case sensitive.
+ * @throws NullPointerException if <code>a_type</code> is null.
+ */
+ public static int name2type(String a_type)
+ {
+ return mapper.get(a_type);
+ }
+
+ /**
+ * Get the element attribute by name.
+ * @param attribute the attribute name, case insensitive.
+ * @return the correspoding attribute of this element. The class,
+ * for storing as attribute list, as a single attribute, is used to
+ * store a single attribute in this case.
+ * @throws NullPointerException if the attribute name is null.
+ */
+ public AttributeList getAttribute(String attribute)
+ {
+ AttributeList a = atts;
+
+ while (a != null && !attribute.equalsIgnoreCase(a.name))
+ a = a.next;
+
+ return a;
+ }
+
+ /**
+ * Get the element attribute by its value.
+ * @param a_value the attribute value, case insensitive.
+ * @return the correspoding attribute of this element. The class,
+ * for storing as attribute list, as a single attribute, is used to
+ * store a single attribute in this case. If there are several
+ * attributes with the same value, there is no garranty, which one
+ * is returned.
+ */
+ public AttributeList getAttributeByValue(String a_value)
+ {
+ AttributeList a = atts;
+
+ if (a_value == null)
+ {
+ while (a != null)
+ {
+ if (a.value == null)
+ return a;
+
+ a = a.next;
+ }
+ }
+ else
+ {
+ while (a != null)
+ {
+ if (a.value != null && a_value.equalsIgnoreCase(a.value))
+ return a;
+
+ a = a.next;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all attributes of this document as an attribute list.
+ * @return
+ */
+ public AttributeList getAttributes()
+ {
+ return atts;
+ }
+
+ /**
+ * Get the content model, defining elements, entities and DTD text
+ * that may/may not occur inside this element.
+ */
+ public ContentModel getContent()
+ {
+ return content;
+ }
+
+ /**
+ * Returns true for the element with no content.
+ * Empty elements are defined with the SGML DTD keyword "EMPTY".
+ * @return true if content model field (content) method is equal to
+ * null or its method empty() returns true.
+ */
+ public boolean isEmpty()
+ {
+ return content == null || content.empty();
+ }
+
+ /**
+ * Get the unique integer identifier of this Element,
+ * used to refer the element (more exactly, the element flag)
+ * in <code>inclusions</code> and <code>exclusions</code> bit set.
+ * WARNING: This value may not be the same between different
+ * implementations.
+ */
+ public int getIndex()
+ {
+ return index;
+ }
+
+ /**
+ * Get the element name.
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Get the element type.
+ * @return one of the values, defined DTDConstants.
+ * In this implementation, the element type can be
+ * CDATA, RCDATA, EMPTY or ANY.
+ */
+ public int getType()
+ {
+ return type;
+ }
+
+ /**
+ * True is this element need not to have the starting tag, false
+ * otherwise.s element need not to have the closing tag, false
+ * otherwise. The HTML 4.0 definition specifies
+ * that some elements (like <code>&lt;hr&gt;</code>are
+ * not required to have the end tags.
+ */
+ public boolean omitEnd()
+ {
+ return oEnd;
+ }
+
+ /**
+ * True is this element need not to have the closing tag, false
+ * otherwise. The HTML 4.0 definition specifies
+ * that some elements (like <code>&lt;head&gt;</code> or
+ * <code>&lt;body&gt;</code>) are
+ * not required to have the start tags.
+ */
+ public boolean omitStart()
+ {
+ return oStart;
+ }
+
+ /**
+ * Returns the name of this element.
+ */
+ public String toString()
+ {
+ return name;
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/parser/Entity.java b/libjava/classpath/javax/swing/text/html/parser/Entity.java
new file mode 100644
index 00000000000..766984f9c79
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/Entity.java
@@ -0,0 +1,185 @@
+/* Entity.java -- Stores information, obtained by parsing SGML DTL
+ * &lt;!ENTITY % .. &gt; tag
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html.parser;
+
+import gnu.javax.swing.text.html.parser.support.gnuStringIntMapper;
+
+import java.io.Serializable;
+
+/**
+ * <p>Stores information, obtained by parsing SGML DTL
+ * &lt;!ENTITY % .. &gt; tag.</p>
+ * <p>
+ * The entity defines some kind of macro that can be used elsewhere in
+ * the document.
+ * When the macro is referred to by the name in the DTD, it is expanded into
+ * a string
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public final class Entity
+ implements DTDConstants, Serializable
+{
+ /**
+ * Package level mapper between type names and they string values.
+ */
+ final static gnuStringIntMapper mapper =
+ new gnuStringIntMapper()
+ {
+ protected void create()
+ {
+ add("ANY", DTDConstants.ANY);
+ add("CDATA", DTDConstants.CDATA);
+ add("PUBLIC", DTDConstants.PUBLIC);
+ add("SDATA", DTDConstants.SDATA);
+ add("PI", DTDConstants.PI);
+ add("STARTTAG", DTDConstants.STARTTAG);
+ add("ENDTAG", DTDConstants.ENDTAG);
+ add("MS", DTDConstants.MS);
+ add("MD", DTDConstants.MD);
+ add("SYSTEM", DTDConstants.SYSTEM);
+ }
+ };
+
+ /**
+ * The entity name.
+ */
+ public String name;
+
+ /**
+ * The entity data
+ */
+ public char[] data;
+
+ /**
+ * The entity type.
+ */
+ public int type;
+
+ /**
+ * String representation of the entity data.
+ */
+ private String sdata;
+
+ /**
+ * Create a new entity
+ * @param a_name the entity name
+ * @param a_type the entity type
+ * @param a_data the data replacing the entity reference
+ */
+ public Entity(String a_name, int a_type, char[] a_data)
+ {
+ name = a_name;
+ type = a_type;
+ data = a_data;
+ }
+
+ /**
+ * Converts a given string to the corresponding entity type.
+ * @return a value, defined in DTDConstants (one of
+ * PUBLIC, CDATA, SDATA, PI, STARTTAG, ENDTAG, MS, MD, SYSTEM)
+ * or CDATA if the parameter is not a valid entity type.
+ */
+ public static int name2type(String an_entity)
+ {
+ int r = mapper.get(an_entity);
+ return (r == 0) ? DTDConstants.CDATA : r;
+ }
+
+ /**
+ * Get the entity data.
+ */
+ public char[] getData()
+ {
+ return data;
+ }
+
+ /**
+ * Returns true for general entities. Each general entity can be
+ * referenced as <code>&entity-name;</code>. Such entities are
+ * defined by the SGML DTD tag
+ * <code>&lt;!ENTITY <i>name</i> "<i>value</i>"></code>. The general
+ * entities can be used anywhere in the document.
+ */
+ public boolean isGeneral()
+ {
+ return (type & DTDConstants.GENERAL) != 0;
+ }
+
+ /**
+ * Get the entity name.
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Returns true for parameter entities. Each parameter entity can be
+ * referenced as <code>&entity-name;</code>. Such entities are
+ * defined by the SGML DTD tag
+ * <code>&lt;!ENTITY % <i>name</i> "<i>value</i>"></code>. The parameter
+ * entities can be used only in SGML context.
+ */
+ public boolean isParameter()
+ {
+ return (type & DTDConstants.PARAMETER) != 0;
+ }
+
+ /**
+ * Returns a data as String
+ */
+ public String getString()
+ {
+ if (sdata == null)
+ sdata = new String(data);
+
+ return sdata;
+ }
+
+ /**
+ * Get the entity type.
+ * @return the value of the {@link #type}.
+ */
+ public int getType()
+ {
+ return type;
+ }
+
+}
diff --git a/libjava/classpath/javax/swing/text/html/parser/Parser.java b/libjava/classpath/javax/swing/text/html/parser/Parser.java
new file mode 100644
index 00000000000..5867107cd45
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/Parser.java
@@ -0,0 +1,436 @@
+/* Parser.java -- HTML parser
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html.parser;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import javax.swing.text.ChangedCharSetException;
+import javax.swing.text.SimpleAttributeSet;
+
+/*
+ * FOR DEVELOPERS: To avoid regression, please run the package test
+ * textsuite/javax.swing.text.html.parser/AllParserTests after your
+ * modifications.
+ */
+
+/**
+ * <p>A simple error-tolerant HTML parser that uses a DTD document
+ * to access data on the possible tokens, arguments and syntax.</p>
+ * <p> The parser reads an HTML content from a Reader and calls various
+ * notifying methods (which should be overridden in a subclass)
+ * when tags or data are encountered.</p>
+ * <p>Some HTML elements need no opening or closing tags. The
+ * task of this parser is to invoke the tag handling methods also when
+ * the tags are not explicitly specified and must be supposed using
+ * information, stored in the DTD.
+ * For example, parsing the document
+ * <p>&lt;table&gt;&lt;tr&gt;&lt;td&gt;a&lt;td&gt;b&lt;td&gt;c&lt;/tr&gt; <br>
+ * will invoke exactly the handling methods exactly in the same order
+ * (and with the same parameters) as if parsing the document: <br>
+ * <em>&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;table&gt;&lt;
+ * tbody&gt;</em>&lt;tr&gt;&lt;td&gt;a<em>&lt;/td&gt;</em>&lt;td&gt;b<em>
+ * &lt;/td&gt;</em>&lt;td&gt;c<em>&lt;/td&gt;&lt;/tr&gt;</em>&lt;
+ * <em>/tbody&gt;&lt;/table&gt;&lt;/body&gt;&lt;/html&gt;</em></p>
+ * (supposed tags are given in italics). The parser also supports
+ * obsolete elements of HTML syntax.<p>
+ * </p>
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public class Parser
+ implements DTDConstants
+{
+ /**
+ * The document template description that will be used to parse the documents.
+ */
+ protected DTD dtd;
+
+ /**
+ * The value of this field determines whether or not the Parser will be
+ * strict in enforcing SGML compatibility. The default value is false,
+ * stating that the parser should do everything to parse and get at least
+ * some information even from the incorrectly written HTML input.
+ */
+ protected boolean strict;
+
+ /**
+ * The package level reference to the working HTML parser in this
+ * implementation.
+ */
+ final gnu.javax.swing.text.html.parser.support.Parser gnu;
+
+ /**
+ * Creates a new parser that uses the given DTD to access data on the
+ * possible tokens, arguments and syntax. There is no single - step way
+ * 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() }.
+ * @param a_dtd A DTD to use.
+ */
+ public Parser(DTD a_dtd)
+ {
+ dtd = a_dtd;
+
+ final Parser j = this;
+
+ gnu =
+ new gnu.javax.swing.text.html.parser.support.Parser(dtd)
+ {
+ protected final void handleComment(char[] comment)
+ {
+ j.handleComment(comment);
+ }
+
+ protected final void handleEOFInComment()
+ {
+ j.handleEOFInComment();
+ }
+
+ protected final void handleEmptyTag(TagElement tag)
+ throws javax.swing.text.ChangedCharSetException
+ {
+ j.handleEmptyTag(tag);
+ }
+
+ protected final void handleStartTag(TagElement tag)
+ {
+ j.handleStartTag(tag);
+ }
+
+ protected final void handleEndTag(TagElement tag)
+ {
+ j.handleEndTag(tag);
+ }
+
+ protected final void handleError(int line, String message)
+ {
+ j.handleError(line, message);
+ }
+
+ protected final void handleText(char[] text)
+ {
+ j.handleText(text);
+ }
+
+ protected final void handleTitle(char[] title)
+ {
+ j.handleTitle(title);
+ }
+
+ protected final void markFirstTime(Element element)
+ {
+ j.markFirstTime(element);
+ }
+
+ protected final void startTag(TagElement tag)
+ throws ChangedCharSetException
+ {
+ j.startTag(tag);
+ }
+
+ protected final void endTag(boolean omitted)
+ {
+ j.endTag(omitted);
+ }
+
+ protected TagElement makeTag(Element element)
+ {
+ return j.makeTag(element);
+ }
+
+ protected TagElement makeTag(Element element, boolean isSupposed)
+ {
+ return j.makeTag(element, isSupposed);
+ }
+ };
+ }
+
+ /**
+ * Parse the HTML text, calling various methods in response to the
+ * occurence of the corresponding HTML constructions.
+ * @param reader The reader to read the source HTML from.
+ * @throws IOException If the reader throws one.
+ */
+ public synchronized void parse(Reader reader)
+ throws IOException
+ {
+ gnu.parse(reader);
+ }
+
+ /**
+ * Parses DTD markup declaration. Currently returns without action.
+ * @return null.
+ * @throws java.io.IOException
+ */
+ public String parseDTDMarkup()
+ throws IOException
+ {
+ return gnu.parseDTDMarkup();
+ }
+
+ /**
+ * Parse DTD document declarations. Currently only parses the document
+ * type declaration markup.
+ * @param strBuff
+ * @return true if this is a valid DTD markup declaration.
+ * @throws IOException
+ */
+ protected boolean parseMarkupDeclarations(StringBuffer strBuff)
+ throws IOException
+ {
+ return gnu.parseMarkupDeclarations(strBuff);
+ }
+
+ /**
+ * Get the attributes of the current tag.
+ * @return The attribute set, representing the attributes of the current tag.
+ */
+ protected SimpleAttributeSet getAttributes()
+ {
+ return gnu.getAttributes();
+ }
+
+ /**
+ * Get the number of the document line being parsed.
+ * @return The current line.
+ */
+ protected int getCurrentLine()
+ {
+ return gnu.hTag.where.beginLine;
+ }
+
+ /**
+ * Get the current position in the document being parsed.
+ * @return The current position.
+ */
+ protected int getCurrentPos()
+ {
+ return gnu.hTag.where.startPosition;
+ }
+
+ /**
+ * The method is called when the HTML end (closing) tag is found or if
+ * the parser concludes that the one should be present in the
+ * current position. The method is called immediatly
+ * before calling the handleEndTag().
+ * @param omitted True if the tag is no actually present in the document,
+ * but is supposed by the parser (like &lt;/html&gt; at the end of the
+ * document).
+ */
+ protected void endTag(boolean omitted)
+ {
+ }
+
+ /**
+ * Invokes the error handler. The default method in this implementation
+ * finally delegates the call to handleError, also providing the number of the
+ * current line.
+ */
+ protected void error(String msg)
+ {
+ gnu.error(msg);
+ }
+
+ /**
+ * Invokes the error handler. The default method in this implementation
+ * finally delegates the call to error (msg+": '"+invalid+"'").
+ */
+ protected void error(String msg, String invalid)
+ {
+ gnu.error(msg, invalid);
+ }
+
+ /**
+ * Invokes the error handler. The default method in this implementation
+ * finally delegates the call to error (parm1+" "+ parm2+" "+ parm3).
+ */
+ protected void error(String parm1, String parm2, String parm3)
+ {
+ gnu.error(parm1, parm2, parm3);
+ }
+
+ /**
+ * Invokes the error handler. The default method in this implementation
+ * finally delegates the call to error
+ * (parm1+" "+ parm2+" "+ parm3+" "+ parm4).
+ */
+ protected void error(String parm1, String parm2, String parm3, String parm4)
+ {
+ gnu.error(parm1, parm2, parm3, parm4);
+ }
+
+ /**
+ * In this implementation, this is never called and returns without action.
+ */
+ protected void flushAttributes()
+ {
+ gnu.flushAttributes();
+ }
+
+ /**
+ * Handle HTML comment. The default method returns without action.
+ * @param comment The comment being handled
+ */
+ protected void handleComment(char[] comment)
+ {
+ }
+
+ /**
+ * This is additionally called in when the HTML content terminates
+ * without closing the HTML comment. This can only happen if the
+ * HTML document contains errors (for example, the closing --;gt is
+ * missing. The default method calls the error handler.
+ */
+ protected void handleEOFInComment()
+ {
+ gnu.error("Unclosed comment");
+ }
+
+ /**
+ * 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.
+ * @throws javax.swing.text.ChangedCharSetException
+ */
+ protected void handleEmptyTag(TagElement tag)
+ throws ChangedCharSetException
+ {
+ }
+
+ /**
+ * 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
+ */
+ protected void handleEndTag(TagElement tag)
+ {
+ }
+
+ /* Handle error that has occured in the given line. */
+ protected void handleError(int line, String message)
+ {
+ }
+
+ /**
+ * 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
+ */
+ protected void handleStartTag(TagElement tag)
+ {
+ }
+
+ /**
+ * Handle the text section.
+ * <p> For non-preformatted section, the parser replaces
+ * \t, \r and \n by spaces and then multiple spaces
+ * by a single space. Additionaly, all whitespace around
+ * tags is discarded.
+ * </p>
+ * <p> For pre-formatted text (inside TEXAREA and PRE), the parser preserves
+ * all tabs and spaces, but removes <b>one</b> bounding \r, \n or \r\n,
+ * if it is present. Additionally, it replaces each occurence of \r or \r\n
+ * by a single \n.</p>
+ *
+ * @param text A section text.
+ */
+ protected void handleText(char[] text)
+ {
+ }
+
+ /**
+ * Handle HTML &lt;title&gt; tag. This method is invoked when
+ * both title starting and closing tags are already behind.
+ * The passed argument contains the concatenation of all
+ * title text sections.
+ * @param The title text.
+ */
+ protected void handleTitle(char[] title)
+ {
+ }
+
+ /**
+ * Constructs the tag from the given element. In this implementation,
+ * this is defined, but never called.
+ * @param element the base element of the tag.
+ * @return the tag
+ */
+ protected TagElement makeTag(Element element)
+ {
+ return makeTag(element, false);
+ }
+
+ /**
+ * Constructs the tag from the given element.
+ * @param 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.
+ * @return the tag
+ */
+ protected TagElement makeTag(Element element, boolean isSupposed)
+ {
+ return new TagElement(element, isSupposed);
+ }
+
+ /**
+ * This is called when the tag, representing the given element,
+ * occurs first time in the document.
+ * @param element
+ */
+ protected void markFirstTime(Element element)
+ {
+ }
+
+ /**
+ * 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. The method is called immediately before
+ * calling the handleStartTag.
+ * @param 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
new file mode 100644
index 00000000000..4b54e8a486c
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java
@@ -0,0 +1,210 @@
+/* ParserDelegator.java -- Delegator for ParserDocument.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.text.html.parser;
+
+import gnu.javax.swing.text.html.parser.HTML_401F;
+import gnu.javax.swing.text.html.parser.htmlAttributeSet;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Serializable;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.html.HTMLEditorKit.ParserCallback;
+
+/**
+ * This class instantiates and starts the working instance of
+ * html parser, being responsible for providing the default DTD.
+ *
+ * TODO Later this class must be derived from the totally abstract class
+ * HTMLEditorKit.Parser. HTMLEditorKit that does not yet exist.
+ *
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
+ */
+public class ParserDelegator
+ extends javax.swing.text.html.HTMLEditorKit.Parser
+ implements Serializable
+{
+ private class gnuParser
+ extends gnu.javax.swing.text.html.parser.support.Parser
+ {
+ private static final long serialVersionUID = 1;
+
+ private gnuParser(DTD d)
+ {
+ super(d);
+ }
+
+ protected final void handleComment(char[] comment)
+ {
+ callBack.handleComment(comment, hTag.where.startPosition);
+ }
+
+ protected final void handleEmptyTag(TagElement tag)
+ throws javax.swing.text.ChangedCharSetException
+ {
+ callBack.handleSimpleTag(tag.getHTMLTag(), getAttributes(),
+ hTag.where.startPosition
+ );
+ }
+
+ protected final void handleEndTag(TagElement tag)
+ {
+ callBack.handleEndTag(tag.getHTMLTag(), hTag.where.startPosition);
+ }
+
+ protected final void handleError(int line, String message)
+ {
+ callBack.handleError(message, hTag.where.startPosition);
+ }
+
+ protected final void handleStartTag(TagElement tag)
+ {
+ htmlAttributeSet attributes = gnu.getAttributes();
+
+ if (tag.fictional())
+ attributes.addAttribute(ParserCallback.IMPLIED, Boolean.TRUE);
+
+ callBack.handleStartTag(tag.getHTMLTag(), attributes,
+ hTag.where.startPosition
+ );
+ }
+
+ protected final void handleText(char[] text)
+ {
+ callBack.handleText(text, hTag.where.startPosition);
+ }
+
+ DTD getDTD()
+ {
+ // Accessing the inherited gnu.javax.swing.text.html.parser.support.Parser
+ // field. super. is a workaround, required to support JDK1.3's javac.
+ return super.dtd;
+ }
+ }
+
+ /**
+ * Use serialVersionUID for interoperability.
+ */
+ private static final long serialVersionUID = -1276686502624777206L;
+
+ private static DTD dtd = HTML_401F.getInstance();
+
+ /**
+ * The callback.
+ * This is package-private to avoid an accessor method.
+ */
+ HTMLEditorKit.ParserCallback callBack;
+
+ /**
+ * The reference to the working class of HTML parser that is
+ * actually used to parse the document.
+ * This is package-private to avoid an accessor method.
+ */
+ gnuParser gnu;
+
+ /**
+ * 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
+ * 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,
+ boolean ignoreCharSet
+ )
+ throws IOException
+ {
+ callBack = a_callback;
+
+ if (gnu == null || !dtd.equals(gnu.getDTD()))
+ {
+ gnu = new gnuParser(dtd);
+ }
+
+ gnu.parse(reader);
+
+ callBack.handleEndOfLineString(gnu.getEndOfLineSequence());
+ try
+ {
+ callBack.flush();
+ }
+ catch (BadLocationException ex)
+ {
+ // Convert this into the supported type of exception.
+ throw new IOException(ex.getMessage());
+ }
+ }
+
+ /**
+ * Calling this method instructs that, if not specified directly,
+ * the documents will be parsed using the default
+ * DTD of the implementation.
+ */
+ protected static void setDefaultDTD()
+ {
+ dtd = HTML_401F.getInstance();
+ }
+
+ /**
+ * Registers the user - written DTD under the given name, also
+ * making it default for the subsequent parsings. This has effect on
+ * 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 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
+ * value without consideration. This implementation returns the DTD
+ * that was previously set as the default DTD, or the implementations
+ * default DTD if none was set.
+ */
+ protected static DTD createDTD(DTD a_dtd, String name)
+ {
+ DTD.putDTDHash(name, a_dtd);
+
+ DTD dtd_prev = dtd;
+ dtd = a_dtd;
+ return dtd_prev;
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/parser/TagElement.java b/libjava/classpath/javax/swing/text/html/parser/TagElement.java
new file mode 100644
index 00000000000..4558b15eb0a
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/TagElement.java
@@ -0,0 +1,142 @@
+/* TagElement.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html.parser;
+
+import javax.swing.text.html.HTML;
+
+/**
+ * The SGML element, defining a single html tag.
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public class TagElement
+{
+ /**
+ * The Element the tag was constructed from.
+ */
+ private final Element element;
+
+ /**
+ * The coresponding HTML tag, assigned once in constructor.
+ */
+ private final HTML.Tag tag;
+
+ /**
+ * The 'fictional' flag.
+ */
+ private final boolean fictional;
+
+ /**
+ * Creates the html tag element from the defintion, stored in the
+ * given element. Sets the flag 'fictional' to false.
+ * @param an_element
+ */
+ public TagElement(Element an_element)
+ {
+ this(an_element, false);
+ }
+
+ /**
+ * Creates the html tag element from the defintion, stored in the
+ * given element, setting the flag 'fictional' to the given value.
+ */
+ public TagElement(Element an_element, boolean is_fictional)
+ {
+ element = an_element;
+ fictional = is_fictional;
+
+ HTML.Tag t = HTML.getTag(element.getName());
+
+ if (t != null)
+ tag = t;
+ else
+ tag = new HTML.UnknownTag(element.getName());
+ }
+
+ /**
+ * Get the element from that the tag was constructed.
+ */
+ public Element getElement()
+ {
+ return element;
+ }
+
+ /**
+ * Get the corresponding HTML tag. This is either one of the
+ * pre-defined HTML tags or the instance of the UnknownTag with the
+ * element name.
+ */
+ public HTML.Tag getHTMLTag()
+ {
+ return tag;
+ }
+
+ /**
+ * Calls isPreformatted() for the corresponding html tag and returns
+ * the obtained value.
+ */
+ public boolean isPreformatted()
+ {
+ return tag.isPreformatted();
+ }
+
+ /**
+ * Calls breaksFlow() for the corresponding html tag and returns
+ * the obtained value.
+ */
+ public boolean breaksFlow()
+ {
+ return tag.breaksFlow();
+ }
+
+ /**
+ * Get the value of the flag 'fictional'.
+ */
+ public boolean fictional()
+ {
+ return fictional;
+ }
+
+ /**
+ * Returns string representation of this object.
+ */
+ public String toString()
+ {
+ return getElement() + (fictional ? "?" : "");
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/parser/package.html b/libjava/classpath/javax/swing/text/html/parser/package.html
new file mode 100644
index 00000000000..5d5157fb2ed
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/html/parser/package.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.swing.text.html package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - javax.swing.text.html.parser</title></head>
+
+<body>
+<p> Provides the DTD driven for web browsers,
+ web robots, web page content analysers, web editors and
+ other applications applications working with Hypertext
+ Markup Language (HTML).
+</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/javax/swing/text/package.html b/libjava/classpath/javax/swing/text/package.html
new file mode 100644
index 00000000000..50043b6c4e8
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.swing.text package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - javax.swing.text</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/javax/swing/text/rtf/ControlWordToken.java b/libjava/classpath/javax/swing/text/rtf/ControlWordToken.java
new file mode 100644
index 00000000000..7008f0fd4a9
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/rtf/ControlWordToken.java
@@ -0,0 +1,86 @@
+/* ControlWordToken.java --
+ Copyright (C) 2005 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.rtf;
+
+/**
+ * A special {@link Token} that represents a control word in RTF like
+ * '\deff0' where 'deff' is the name of the control word and '0' is an
+ * optional parameter.
+ *
+ * @author Roman Kennke (roman@ontographics.com)
+ */
+class ControlWordToken extends Token
+{
+
+ /**
+ * The name of the control word.
+ */
+ public String name;
+
+ /**
+ * The optional parameter of the control word. Absence of a parameter is
+ * expressed through Integer.MIN_VALUE.
+ */
+ public int param;
+
+ /**
+ * Constructs a new ControlWordToken with the specified name and without
+ * a parameter.
+ *
+ * @param name the name of the control word
+ */
+ public ControlWordToken(String name)
+ {
+ this(name, Integer.MIN_VALUE);
+ }
+
+
+ /**
+ * Constructs a new ControlWordToken with the specified name and parameter.
+ *
+ * @param name the name of the control word
+ */
+ public ControlWordToken(String name, int param)
+ {
+ super(Token.CONTROL_WORD);
+ this.name = name;
+ this.param = param;
+ }
+
+}
diff --git a/libjava/classpath/javax/swing/text/rtf/RTFEditorKit.java b/libjava/classpath/javax/swing/text/rtf/RTFEditorKit.java
new file mode 100644
index 00000000000..b2ebe3dd18c
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/rtf/RTFEditorKit.java
@@ -0,0 +1,114 @@
+/* RTFEditorKit.java --
+ Copyright (C) 2005 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.rtf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.StyledEditorKit;
+
+/**
+ * Provides support for RTF data for use in
+ * {@link javax.swing.JEditorPane}s.
+ *
+ * @author Roman Kennke (roman@ontographics.com)
+ */
+public class RTFEditorKit
+ extends StyledEditorKit
+{
+
+ /**
+ * Constructs a new RTFEditorKit.
+ */
+ public RTFEditorKit()
+ {
+ super();
+ }
+
+ /**
+ * Returns the MIME content type. In the case of RTFEditorKit this is
+ * &apos;text/rtf&apos;
+ *
+ * @return the MIME content type for RTFEditorKit
+ */
+ public String getContentType()
+ {
+ return "text/rtf";
+ }
+
+ /**
+ * Reads RTF data from <code>stream</code> into <code>doc</code> at the
+ * specified position <code>pos</code>.
+ *
+ * @param stream the {@link InputStream} from where we read RTF data
+ * @param doc the {@link Document} into which we read the RTF data
+ * @param pos the position where to start
+ *
+ * @throws IOException if an IO error occurs
+ * @throws BadLocationException if the position is not valid
+ */
+ public void read(InputStream stream, Document doc, int pos)
+ throws IOException, BadLocationException
+ {
+ RTFParser parser = new RTFParser(stream, doc, pos);
+ parser.parse();
+ }
+
+
+ /**
+ * Reads RTF data from <code>reader</code> into <code>doc</code> at the
+ * specified position <code>pos</code>.
+ *
+ * @param reader the {@link Reader} from where we read RTF data
+ * @param doc the {@link Document} into which we read the RTF data
+ * @param pos the position where to start
+ *
+ * @throws IOException if an IO error occurs
+ * @throws BadLocationException if the position is not valid
+ */
+ public void read(Reader reader, Document doc, int pos)
+ throws IOException, BadLocationException
+ {
+ RTFParser parser = new RTFParser(reader, doc, pos);
+ parser.parse();
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/rtf/RTFParseException.java b/libjava/classpath/javax/swing/text/rtf/RTFParseException.java
new file mode 100644
index 00000000000..2a9c64f05b8
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/rtf/RTFParseException.java
@@ -0,0 +1,65 @@
+/* RTFParseException.java --
+ Copyright (C) 2005 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.rtf;
+
+/**
+ * Indicates a parsing error during RTF processing.
+ *
+ * @author Roman Kennke (roman@ontographics.com)
+ */
+class RTFParseException
+ extends RuntimeException
+{
+ /**
+ * Constructs a new RTFParseException without message.
+ */
+ public RTFParseException()
+ {
+ super();
+ }
+
+ /**
+ * Constructs a new RTFParseException with the specified message.
+ */
+ public RTFParseException(String message)
+ {
+ super(message);
+ }
+
+}
diff --git a/libjava/classpath/javax/swing/text/rtf/RTFParser.java b/libjava/classpath/javax/swing/text/rtf/RTFParser.java
new file mode 100644
index 00000000000..4f0f967c117
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/rtf/RTFParser.java
@@ -0,0 +1,195 @@
+/* RTFParser.java --
+ Copyright (C) 2005 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.rtf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+
+/**
+ * Parses an RTF file into a {@link Document}. The parser utilizes
+ * {@link RTFScanner}.
+ *
+ * @author Roman Kennke (roman@ontographics.com)
+ */
+class RTFParser
+{
+
+ /**
+ * Our scanner.
+ */
+ private RTFScanner scanner;
+
+ /**
+ * The document into which we parse.
+ */
+ private Document doc;
+
+ /**
+ * The current position.
+ */
+ private int pos;
+
+ /**
+ * Constructs a new RTFParser for the specified document and position,
+ * without initializing the scanner. This is only used internally.
+ *
+ * @param doc the {@link Document} into which we should parse
+ * @param pos the position to start
+ */
+ private RTFParser(Document doc, int pos)
+ {
+ this.doc = doc;
+ this.pos = pos;
+ }
+
+ /**
+ * Constructs a new RTFParser for the specified <code>stream</code>.
+ *
+ * @param stream the stream from which we parse
+ * @param doc the {@link Document} into which we should parse
+ * @param pos the position to start
+ */
+ public RTFParser(InputStream stream, Document doc, int pos)
+ {
+ this(doc, pos);
+ scanner = new RTFScanner(stream);
+ }
+
+ /**
+ * Constructs a new RTFParser for the specified <code>reader</code>.
+ *
+ * @param reader the reader from which we parse
+ * @param doc the {@link Document} into which we should parse
+ * @param pos the position to start
+ */
+ public RTFParser(Reader reader, Document doc, int pos)
+ {
+ this(doc, pos);
+ scanner = new RTFScanner(reader);
+ }
+
+ /**
+ * Returns the {@link Document} in which we parsed the RTF data.
+ *
+ * @return the {@link Document} in which we parsed the RTF data
+ */
+ public Document getDocument()
+ {
+ return doc;
+ }
+
+ /**
+ * Starts the parsing process.
+ */
+ public void parse()
+ throws IOException, BadLocationException
+ {
+ parseFile();
+ }
+
+ /**
+ * The parse rules for &lt;file&gt;.
+ */
+ private void parseFile()
+ throws IOException, BadLocationException
+ {
+ Token t1 = scanner.readToken();
+ if (t1.type != Token.LCURLY)
+ throw new RTFParseException("expected left curly braces");
+
+ parseHeader();
+ parseDocument();
+
+ Token t2 = scanner.readToken();
+ if (t2.type != Token.RCURLY)
+ throw new RTFParseException("expected right curly braces");
+
+ }
+
+ /**
+ * The parse rules for &lt;header&gt;.
+ *
+ * TODO: implement this properly
+ */
+ private void parseHeader()
+ //throws IOException, BadLocationException
+ {
+ // TODO add parse rules here
+ }
+
+
+ /**
+ * The parse rules for &lt;document&gt;.
+ *
+ * TODO: implement this properly
+ */
+ private void parseDocument()
+ throws IOException, BadLocationException
+ {
+ // !!! TODO !!!
+ // This simply emits every TEXT Token as text to the document
+ // which is plain stupid
+
+ boolean eof = false;
+
+ do {
+ Token token = scanner.readToken();
+ switch (token.type)
+ {
+ case Token.TEXT:
+ TextToken textToken = (TextToken) token;
+ doc.insertString(pos, textToken.text, null);
+ pos += textToken.text.length();
+ break;
+ case Token.EOF:
+ eof = true;
+ break;
+ default:
+ // FIXME
+ break;
+ }
+ } while (!eof);
+
+ }
+
+}
diff --git a/libjava/classpath/javax/swing/text/rtf/RTFScanner.java b/libjava/classpath/javax/swing/text/rtf/RTFScanner.java
new file mode 100644
index 00000000000..3cdd6e8e0b9
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/rtf/RTFScanner.java
@@ -0,0 +1,268 @@
+/* RTFScanner.java --
+ Copyright (C) 2005 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.rtf;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+/**
+ * Provides a scanner that scans an {@link InputStream} for tokens of the
+ * RTF syntax.
+ *
+ * This scanner is based upon the RTF specification 1.6
+ * available at:
+ *
+ * <a
+ * href="http://msdn.microsoft.com/library/en-us/dnrtfspec/html/rtfspec.asp">
+ * RTF specification at MSDN</a>
+ *
+ * @author Roman Kennke (roman@ontographics.com)
+ */
+class RTFScanner
+{
+
+ /**
+ * The reader from which we read the RTF data.
+ */
+ private Reader in;
+
+ /**
+ * This is used to constuct strings from the read in chars.
+ */
+ private StringBuffer buffer;
+
+ /**
+ * Constructs a new RTFScanner without initializing the {@link Reader}.
+ */
+ private RTFScanner()
+ {
+ buffer = new StringBuffer();
+ }
+
+ /**
+ * Constructs a new RTFScanner for the given {@link InputStream}.
+ * The stream is wrapped into an {@link InputStreamReader} and if it's
+ * not yet buffered then the Reader is wrapped in a {@link BufferedReader}
+ *
+ * @param stream the {@link InputStream} to read RTF data from
+ */
+ public RTFScanner(InputStream stream)
+ {
+ this();
+ InputStreamReader reader = new InputStreamReader(stream);
+ in = new BufferedReader(reader);
+ }
+
+ /**
+ * Constructs a new RTFScanner for the given {@link Reader}.
+ *
+ * If the reader is not an instance of {@link BufferedReader} then it
+ * is wrapped into a BufferedReader.
+ *
+ * @param reader the {@link BufferedReader} to read RTF data from
+ */
+ public RTFScanner(Reader reader)
+ {
+ this();
+ if (reader instanceof BufferedReader)
+ {
+ in = reader;
+ }
+ else
+ {
+ in = new BufferedReader(reader);
+ }
+ }
+
+ /**
+ * Reads in the next {@link Token} from the stream.
+ *
+ * @return the read {@link Token}
+ *
+ * @throws IOException if the underlying stream has problems
+ */
+ public Token readToken()
+ throws IOException
+ {
+ Token token = null;
+
+ int c = in.read();
+ switch(c)
+ {
+ case -1:
+ token = new Token(Token.EOF);
+ break;
+
+ case '{':
+ token = new Token(Token.LCURLY);
+ break;
+
+ case '}':
+ token = new Token(Token.RCURLY);
+ break;
+
+ case '\\':
+ buffer.delete(0, buffer.length());
+ buffer.append((char) c);
+ token = readControlWord();
+ break;
+
+ default:
+ buffer.delete(0, buffer.length());
+ buffer.append((char) c);
+ token = readText();
+ break;
+ }
+
+ return token;
+ }
+
+ /**
+ * Reads in a control word and optional parameter.
+ *
+ * @return the read in control word as {@link ControlWordToken}
+ *
+ * @throws IOException if the underlying stream has problems
+ */
+ private Token readControlWord()
+ throws IOException
+ {
+ // this flag indicates if we are still reading the name or are already
+ // in the parameter
+ boolean readingName = true;
+ String name = null;
+ String param = null;
+
+ while (true)
+ {
+ in.mark(1);
+ int c = in.read();
+
+ // check for 'a'..'z'
+ if (readingName && (c >= 'a') && (c <= 'z'))
+ {
+ buffer.append((char) c);
+ }
+ else if ((c >= '0') && (c <= '9'))
+ {
+ // if the last char was in the name, then finish reading the name
+ if (readingName)
+ {
+ name = buffer.toString();
+ buffer.delete(0, buffer.length());
+ readingName = false;
+ }
+ buffer.append((char) c);
+ }
+ else
+ {
+ // if we were in the name, then finish this
+ if (readingName)
+ {
+ name = buffer.toString();
+ }
+ // otherwise finish the parameter
+ else
+ {
+ param = buffer.toString();
+ }
+
+ // clear up
+ buffer.delete(0, buffer.length());
+ // reset input buffer to last char
+ in.reset();
+ // break while loop
+ break;
+ }
+ }
+
+ ControlWordToken token = null;
+
+ if (param == null)
+ token = new ControlWordToken(name);
+ else
+ token =new ControlWordToken(name, Integer.parseInt(param));
+
+ return token;
+
+ }
+
+ /**
+ * Reads in a block of text.
+ *
+ * @return the token for the text
+ */
+ private Token readText()
+ throws IOException
+ {
+
+ boolean readingText = true;
+ while (readingText)
+ {
+ in.mark(1);
+ int c = in.read();
+ switch(c)
+ {
+ case '\\':
+ case '{':
+ case '}':
+ case -1:
+ readingText = false;
+ in.reset();
+ break;
+
+ default:
+ buffer.append((char) c);
+ break;
+ }
+
+ }
+
+ String text = buffer.toString();
+ Token token = new TextToken(text);
+
+ buffer.delete(0, buffer.length());
+
+ return token;
+
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/rtf/TextToken.java b/libjava/classpath/javax/swing/text/rtf/TextToken.java
new file mode 100644
index 00000000000..2d6d527d132
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/rtf/TextToken.java
@@ -0,0 +1,65 @@
+/* TextToken.java --
+ Copyright (C) 2005 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.rtf;
+
+/**
+ * A special {@link Token} that represents a piece of text in RTF.
+ *
+ * @author Roman Kennke (roman@ontographics.com)
+ */
+class TextToken extends Token
+{
+
+ /**
+ * The text.
+ */
+ public String text;
+
+ /**
+ * Constructs a new TextToken with the specified textual data.
+ *
+ * @param text the text for this token
+ */
+ public TextToken(String text)
+ {
+ super(Token.TEXT);
+ this.text = text;
+ }
+
+}
diff --git a/libjava/classpath/javax/swing/text/rtf/Token.java b/libjava/classpath/javax/swing/text/rtf/Token.java
new file mode 100644
index 00000000000..7d5adaaf0bb
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/rtf/Token.java
@@ -0,0 +1,91 @@
+/* Token.java --
+ Copyright (C) 2005 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.rtf;
+
+/**
+ * Represents a simple token that the RTFScanner can read. A simple
+ * only has a type (like LCURLY or RCURLY). More complex tokens may
+ * attach data to the token.
+ *
+ * @author Roman Kennke (roman@ontographics.com)
+ */
+class Token
+{
+
+ /**
+ * This special type inidicates the end of the input stream.
+ */
+ public static final int EOF = -1;
+
+ /**
+ * A left curly brace '{'.
+ */
+ public static final int LCURLY = 1;
+
+ /**
+ * A right curly brace '}'.
+ */
+ public static final int RCURLY = 2;
+
+ /**
+ * A control word like '\rtf1'. Tokens with this type are represented
+ * through the subclass {@link ControlWordToken}.
+ */
+ public static final int CONTROL_WORD = 3;
+
+ /**
+ * A token that contains text. This is represented through the subclass
+ * {@link TextToken}.
+ */
+ public static final int TEXT = 4;
+
+
+ /** The token type. */
+ public int type;
+
+ /**
+ * Constructs a new Token with the specified type.
+ *
+ * @param type the Token type
+ */
+ public Token(int type)
+ {
+ this.type = type;
+ }
+}
OpenPOWER on IntegriCloud