From 1ea63ef8be1cc54dd0de9d82c684713a1dcf1e06 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 23 Sep 2005 21:31:04 +0000 Subject: Imported Classpath 0.18. * sources.am, Makefile.in: Updated. * Makefile.am (nat_source_files): Removed natProxy.cc. * java/lang/reflect/natProxy.cc: Removed. * gnu/classpath/jdwp/VMFrame.java, gnu/classpath/jdwp/VMIdManager.java, gnu/classpath/jdwp/VMVirtualMachine.java, java/lang/reflect/VMProxy.java: New files. 2005-09-23 Thomas Fitzsimmons * scripts/makemake.tcl (verbose): Add gnu/java/awt/peer/qt to BC list. 2005-09-23 Thomas Fitzsimmons * gnu/java/net/DefaultContentHandlerFactory.java (getContent): Remove ClasspathToolkit references. 2005-09-23 Thomas Fitzsimmons * gnu/awt/xlib/XCanvasPeer.java: Add new peer methods. * gnu/awt/xlib/XFramePeer.java: Likewise. * gnu/awt/xlib/XGraphicsConfiguration.java: Likewise. 2005-09-23 Thomas Fitzsimmons * Makefile.am (libgcjawt_la_SOURCES): Remove jawt.c. Add classpath/native/jawt/jawt.c. * Makefile.in: Regenerate. * jawt.c: Remove file. * include/Makefile.am (tool_include__HEADERS): Remove jawt.h and jawt_md.h. Add ../classpath/include/jawt.h and ../classpath/include/jawt_md.h. * include/Makefile.in: Regenerate. * include/jawt.h: Regenerate. * include/jawt_md.h: Regenerate. From-SVN: r104586 --- .../javax/swing/text/DefaultStyledDocument.java | 307 ++++++++++++++++++++- 1 file changed, 295 insertions(+), 12 deletions(-) (limited to 'libjava/classpath/javax/swing/text/DefaultStyledDocument.java') diff --git a/libjava/classpath/javax/swing/text/DefaultStyledDocument.java b/libjava/classpath/javax/swing/text/DefaultStyledDocument.java index 6fe206a8453..3545e52c453 100644 --- a/libjava/classpath/javax/swing/text/DefaultStyledDocument.java +++ b/libjava/classpath/javax/swing/text/DefaultStyledDocument.java @@ -42,42 +42,174 @@ import java.awt.Color; import java.awt.Font; import java.io.Serializable; +import javax.swing.event.DocumentEvent; + /** + * The default implementation of {@link StyledDocument}. + * + * The document is modeled as an {@link Element} tree, which has + * a {@link SectionElement} as single root, which has one or more + * {@link AbstractDocument.BranchElement}s as paragraph nodes + * and each paragraph node having one or more + * {@link AbstractDocument.LeafElement}s as content nodes. + * * @author Michael Koch (konqueror@gmx.de) + * @author Roman Kennke (roman@kennke.org) */ public class DefaultStyledDocument extends AbstractDocument implements StyledDocument { + /** + * Performs all structural changes to the Element + * hierarchy. + */ public class ElementBuffer implements Serializable { + /** The root element of the hierarchy. */ private Element root; - + + /** Holds the offset for structural changes. */ + private int offset; + + /** Holds the length of structural changes. */ + private int length; + + /** + * Creates a new ElementBuffer for the specified + * root element. + * + * @param root the root element for this ElementBuffer + */ public ElementBuffer(Element root) { this.root = root; } + /** + * Returns the root element of this ElementBuffer. + * + * @return the root element of this ElementBuffer + */ public Element getRootElement() { return root; } + + /** + * Modifies the element structure so that the specified interval starts + * and ends at an element boundary. Content and paragraph elements + * are split and created as necessary. + * + * This also updates the DefaultDocumentEvent to reflect the + * structural changes. + * + * The bulk work is delegated to {@link #changeUpdate()}. + * + * @param offset the start index of the interval to be changed + * @param length the length of the interval to be changed + * @param ev the DefaultDocumentEvent describing the change + */ + public void change(int offset, int length, DefaultDocumentEvent ev) + { + this.offset = offset; + this.length = length; + changeUpdate(); + } + + /** + * Performs the actual work for {@link #change}. + * The elements at the interval boundaries are split up (if necessary) + * so that the interval boundaries are located at element boundaries. + */ + protected void changeUpdate() + { + // Split up the element at the start offset if necessary. + Element el = getCharacterElement(offset); + split(el, offset); + + int endOffset = offset + length; + el = getCharacterElement(endOffset); + split(el, endOffset); + } + + /** + * Splits an element if offset is not alread at its boundary. + * + * @param el the Element to possibly split + * @param offset the offset at which to possibly split + */ + void split(Element el, int offset) + { + if (el instanceof AbstractElement) + { + AbstractElement ael = (AbstractElement) el; + int startOffset = ael.getStartOffset(); + int endOffset = ael.getEndOffset(); + int len = endOffset - startOffset; + if (startOffset != offset && endOffset != offset) + { + Element paragraph = ael.getParentElement(); + if (paragraph instanceof BranchElement) + { + BranchElement par = (BranchElement) paragraph; + Element child1 = createLeafElement(par, ael, startOffset, + offset); + Element child2 = createLeafElement(par, ael, offset, + endOffset); + int index = par.getElementIndex(startOffset); + par.replace(index, 1, new Element[]{ child1, child2 }); + } + else + throw new AssertionError("paragraph elements are expected to " + + "be instances of " + + "javax.swing.text.AbstractDocument.BranchElement"); + } + } + else + throw new AssertionError("content elements are expected to be " + + "instances of " + + "javax.swing.text.AbstractDocument.AbstractElement"); + } } - + + /** + * The default size to use for new content buffers. + */ public static final int BUFFER_SIZE_DEFAULT = 4096; + /** + * The EditorBuffer that is used to manage to + * Element hierarchy. + */ protected DefaultStyledDocument.ElementBuffer buffer; - + + /** + * Creates a new DefaultStyledDocument. + */ public DefaultStyledDocument() { this(new GapContent(BUFFER_SIZE_DEFAULT), new StyleContext()); } + /** + * Creates a new DefaultStyledDocument that uses the + * specified {@link StyleContext}. + * + * @param context the StyleContext to use + */ public DefaultStyledDocument(StyleContext context) { this(new GapContent(BUFFER_SIZE_DEFAULT), context); } + /** + * Creates a new DefaultStyledDocument that uses the + * specified {@link StyleContext} and {@link Content} buffer. + * + * @param content the Content buffer to use + * @param context the StyleContext to use + */ public DefaultStyledDocument(AbstractDocument.Content content, StyleContext context) { @@ -86,15 +218,38 @@ public class DefaultStyledDocument extends AbstractDocument setLogicalStyle(0, context.getStyle(StyleContext.DEFAULT_STYLE)); } + /** + * Adds a style into the style hierarchy. Unspecified style attributes + * can be resolved in the parent style, if one is specified. + * + * While it is legal to add nameless styles (nm == nullnull if the style should + * be unnamed + * @param parent the parent in which unspecified style attributes are + * resolved, or null if that is not necessary + * + * @return the newly created Style + */ public Style addStyle(String nm, Style parent) { StyleContext context = (StyleContext) getAttributeContext(); return context.addStyle(nm, parent); } - + + /** + * Create the default root element for this kind of Document. + * + * @return the default root element for this kind of Document + */ protected AbstractDocument.AbstractElement createDefaultRoot() { Element[] tmp; + // FIXME: Create a SecionElement here instead of a BranchElement. + // Use createBranchElement() and createLeafElement instead. BranchElement section = new BranchElement(null, null); BranchElement paragraph = new BranchElement(section, null); @@ -109,7 +264,17 @@ public class DefaultStyledDocument extends AbstractDocument return section; } - + + /** + * Returns the Element that corresponds to the character + * at the specified position. + * + * @param position the position of which we query the corresponding + * Element + * + * @return the Element that corresponds to the character + * at the specified position + */ public Element getCharacterElement(int position) { Element element = getDefaultRootElement(); @@ -122,63 +287,172 @@ public class DefaultStyledDocument extends AbstractDocument return element; } - + + /** + * Extracts a background color from a set of attributes. + * + * @param attributes the attributes from which to get a background color + * + * @return the background color that correspond to the attributes + */ public Color getBackground(AttributeSet attributes) { StyleContext context = (StyleContext) getAttributeContext(); return context.getBackground(attributes); } - + + /** + * Returns the default root element. + * + * @return the default root element + */ public Element getDefaultRootElement() { return buffer.getRootElement(); } - + + /** + * Extracts a font from a set of attributes. + * + * @param attributes the attributes from which to get a font + * + * @return the font that correspond to the attributes + */ public Font getFont(AttributeSet attributes) { StyleContext context = (StyleContext) getAttributeContext(); return context.getFont(attributes); } + /** + * Extracts a foreground color from a set of attributes. + * + * @param attributes the attributes from which to get a foreground color + * + * @return the foreground color that correspond to the attributes + */ public Color getForeground(AttributeSet attributes) { StyleContext context = (StyleContext) getAttributeContext(); return context.getForeground(attributes); } - + + /** + * Returns the logical Style for the specified position. + * + * @param position the position from which to query to logical style + * + * @return the logical Style for the specified position + */ public Style getLogicalStyle(int position) { Element paragraph = getParagraphElement(position); AttributeSet attributes = paragraph.getAttributes(); return (Style) attributes.getResolveParent(); } - + + /** + * Returns the paragraph element for the specified position. + * + * @param position the position for which to query the paragraph element + * + * @return the paragraph element for the specified position + */ public Element getParagraphElement(int position) { Element element = getCharacterElement(position); return element.getParentElement(); } + /** + * Looks up and returns a named Style. + * + * @param nm the name of the Style + * + * @return the found Style of null if no such + * Style exists + */ public Style getStyle(String nm) { StyleContext context = (StyleContext) getAttributeContext(); return context.getStyle(nm); } + /** + * Removes a named Style from the style hierarchy. + * + * @param nm the name of the Style to be removed + */ public void removeStyle(String nm) { StyleContext context = (StyleContext) getAttributeContext(); context.removeStyle(nm); } + /** + * Sets text attributes for the fragment specified by offset + * and length. + * + * @param offset the start offset of the fragment + * @param length the length of the fragment + * @param attributes the text attributes to set + * @param replace if true, the attributes of the current + * selection are overridden, otherwise they are merged + */ public void setCharacterAttributes(int offset, int length, AttributeSet attributes, boolean replace) { - // FIXME: Implement me. - throw new Error("not implemented"); + DefaultDocumentEvent ev = + new DefaultDocumentEvent(offset, length, + DocumentEvent.EventType.CHANGE); + + // Modify the element structure so that the interval begins at an element + // start and ends at an element end. + buffer.change(offset, length, ev); + + Element root = getDefaultRootElement(); + // Visit all paragraph elements within the specified interval + int paragraphCount = root.getElementCount(); + for (int pindex = 0; pindex < paragraphCount; pindex++) + { + Element paragraph = root.getElement(pindex); + // Skip paragraphs that lie outside the interval. + if ((paragraph.getStartOffset() > offset + length) + || (paragraph.getEndOffset() < offset)) + continue; + + // Visit content elements within this paragraph + int contentCount = paragraph.getElementCount(); + for (int cindex = 0; cindex < contentCount; cindex++) + { + Element content = paragraph.getElement(cindex); + // Skip content that lies outside the interval. + if ((content.getStartOffset() > offset + length) + || (content.getEndOffset() < offset)) + continue; + + if (content instanceof AbstractElement) + { + AbstractElement el = (AbstractElement) content; + if (replace) + el.removeAttributes(el); + el.addAttributes(attributes); + } + else + throw new AssertionError("content elements are expected to be" + + "instances of " + + "javax.swing.text.AbstractDocument.AbstractElement"); + } + } } + /** + * Sets the logical style for the paragraph at the specified position. + * + * @param position the position at which the logical style is added + * @param style the style to set for the current paragraph + */ public void setLogicalStyle(int position, Style style) { Element el = getParagraphElement(position); @@ -192,6 +466,15 @@ public class DefaultStyledDocument extends AbstractDocument + "instances of javax.swing.text.AbstractDocument.AbstractElement"); } + /** + * Sets text attributes for the paragraph at the specified fragment. + * + * @param offset the beginning of the fragment + * @param length the length of the fragment + * @param attributes the text attributes to set + * @param replace if true, the attributes of the current + * selection are overridden, otherwise they are merged + */ public void setParagraphAttributes(int offset, int length, AttributeSet attributes, boolean replace) -- cgit v1.2.1