HTMLDocumentpublic class HTMLDocument extends DefaultStyledDocument A document that models HTML. The purpose of this model
is to support both browsing and editing. As a result,
the structure described by an HTML document is not
exactly replicated by default. The element structure that
is modeled by default, is built by the class
HTMLDocument.HTMLReader , which implements
the HTMLEditorKit.ParserCallback protocol
that the parser expects. To change the structure one
can subclass HTMLReader , and reimplement the method
{@link #getReader(int)} to return the new reader
implementation. The documentation for HTMLReader
should be consulted for the details of
the default structure created. The intent is that
the document be non-lossy (although reproducing the
HTML format may result in a different format).
The document models only HTML, and makes no attempt to
store view attributes in it. The elements are identified
by the StyleContext.NameAttribute attribute,
which should always have a value of type HTML.Tag
that identifies the kind of element. Some of the elements
(such as comments) are synthesized. The HTMLFactory
uses this attribute to determine what kind of view to build.
This document supports incremental loading. The
TokenThreshold property controls how
much of the parse is buffered before trying to update
the element structure of the document. This property
is set by the EditorKit so that subclasses can disable
it.
The Base property determines the URL
against which relative URLs are resolved.
By default, this will be the
Document.StreamDescriptionProperty if
the value of the property is a URL. If a <BASE>
tag is encountered, the base will become the URL specified
by that tag. Because the base URL is a property, it
can of course be set directly.
The default content storage mechanism for this document
is a gap buffer (GapContent ).
Alternatives can be supplied by using the constructor
that takes a Content implementation. |
Fields Summary |
---|
private boolean | frameDocument | private boolean | preservesUnknownTags | private HashMap | radioButtonGroupsMap | static final String | TokenThresholdDocument property for the number of tokens to buffer
before building an element subtree to represent them. | private static final int | MaxThreshold | private static final int | StepThreshold | public static final String | AdditionalCommentsDocument property key value. The value for the key will be a Vector
of Strings that are comments not found in the body. | static final String | StyleTypeDocument property key value. The value for the key will be a
String indicating the default type of stylesheet links. | URL | baseThe location to resolve relative URLs against. By
default this will be the document's URL if the document
was loaded from a URL. If a base tag is found and
can be parsed, it will be used as the base location. | boolean | hasBaseTagdoes the document have base tag | private String | baseTargetBASE tag's TARGET attribute value | private HTMLEditorKit$Parser | parserThe parser that is used when inserting html into the existing
document. | private static AttributeSet | contentAttributeSetUsed for inserts when a null AttributeSet is supplied. | static String | MAP_PROPERTYProperty Maps are registered under, will be a Hashtable. | private static char[] | NEWLINE | private static final String | IMPLIED_CR | private static final String | I18NPropertyI18N property key. |
Constructors Summary |
---|
public HTMLDocument()Constructs an HTML document using the default buffer size
and a default StyleSheet . This is a convenience
method for the constructor
HTMLDocument(Content, StyleSheet) .
this(new GapContent(BUFFER_SIZE_DEFAULT), new StyleSheet());
| public HTMLDocument(StyleSheet styles)Constructs an HTML document with the default content
storage implementation and the specified style/attribute
storage mechanism. This is a convenience method for the
constructor
HTMLDocument(Content, StyleSheet) .
this(new GapContent(BUFFER_SIZE_DEFAULT), styles);
| public HTMLDocument(Content c, StyleSheet styles)Constructs an HTML document with the given content
storage implementation and the given style/attribute
storage mechanism.
super(c, styles);
|
Methods Summary |
---|
void | addMap(javax.swing.text.html.Map map)Adds the specified map, this will remove a Map that has been
previously registered with the same name.
String name = map.getName();
if (name != null) {
Object maps = getProperty(MAP_PROPERTY);
if (maps == null) {
maps = new Hashtable(11);
putProperty(MAP_PROPERTY, maps);
}
if (maps instanceof Hashtable) {
((Hashtable)maps).put("#" + name, map);
}
}
| protected void | create(ElementSpec[] data)Replaces the contents of the document with the given
element specifications. This is called before insert if
the loading is done in bursts. This is the only method called
if loading the document entirely in one burst.
super.create(data);
| protected javax.swing.text.Element | createBranchElement(javax.swing.text.Element parent, javax.swing.text.AttributeSet a)Creates a document branch element, that can contain other elements.
This is implemented to return an element of type
HTMLDocument.BlockElement .
return new BlockElement(parent, a);
| protected AbstractElement | createDefaultRoot()Creates the root element to be used to represent the
default document structure.
// grabs a write-lock for this initialization and
// abandon it during initialization so in normal
// operation we can detect an illegitimate attempt
// to mutate attributes.
writeLock();
MutableAttributeSet a = new SimpleAttributeSet();
a.addAttribute(StyleConstants.NameAttribute, HTML.Tag.HTML);
BlockElement html = new BlockElement(null, a.copyAttributes());
a.removeAttributes(a);
a.addAttribute(StyleConstants.NameAttribute, HTML.Tag.BODY);
BlockElement body = new BlockElement(html, a.copyAttributes());
a.removeAttributes(a);
a.addAttribute(StyleConstants.NameAttribute, HTML.Tag.P);
getStyleSheet().addCSSAttributeFromHTML(a, CSS.Attribute.MARGIN_TOP, "0");
BlockElement paragraph = new BlockElement(body, a.copyAttributes());
a.removeAttributes(a);
a.addAttribute(StyleConstants.NameAttribute, HTML.Tag.CONTENT);
RunElement brk = new RunElement(paragraph, a, 0, 1);
Element[] buff = new Element[1];
buff[0] = brk;
paragraph.replace(0, 0, buff);
buff[0] = paragraph;
body.replace(0, 0, buff);
buff[0] = body;
html.replace(0, 0, buff);
writeUnlock();
return html;
| protected javax.swing.text.Element | createLeafElement(javax.swing.text.Element parent, javax.swing.text.AttributeSet a, int p0, int p1)Creates a document leaf element that directly represents
text (doesn't have any children). This is implemented
to return an element of type
HTMLDocument.RunElement .
return new RunElement(parent, a, p0, p1);
| private javax.swing.text.Element | findFrame(java.lang.String frameName)Searches the element hierarchy for an FRAME element
that has its name attribute equal to the frameName .
ElementIterator it = new ElementIterator(this);
Element next = null;
while ((next = it.next()) != null) {
AttributeSet attr = next.getAttributes();
if (matchNameAttribute(attr, HTML.Tag.FRAME)) {
String frameTarget = (String)attr.getAttribute(HTML.Attribute.NAME);
if (frameTarget != null && frameTarget.equals(frameName)) {
break;
}
}
}
return next;
| protected void | fireChangedUpdate(javax.swing.event.DocumentEvent e)Notifies all listeners that have registered interest for
notification on this event type. The event instance
is lazily created using the parameters passed into
the fire method.
super.fireChangedUpdate(e);
| protected void | fireUndoableEditUpdate(javax.swing.event.UndoableEditEvent e)Notifies all listeners that have registered interest for
notification on this event type. The event instance
is lazily created using the parameters passed into
the fire method.
super.fireUndoableEditUpdate(e);
| public java.net.URL | getBase()Returns the location to resolve relative URLs against. By
default this will be the document's URL if the document
was loaded from a URL. If a base tag is found and
can be parsed, it will be used as the base location.
return base;
| java.lang.String | getBaseTarget()
return baseTarget;
| java.lang.String | getDefaultStyleSheetType()Returns the content type language used for style sheets. The default
is text/css.
String retValue = (String)getProperty(StyleType);
if (retValue == null) {
return "text/css";
}
return retValue;
| public javax.swing.text.Element | getElement(java.lang.String id)Returns the element that has the given id Attribute .
If the element can't be found, null is returned.
Note that this method works on an Attribute ,
not a character tag. In the following HTML snippet:
<a id="HelloThere"> the attribute is
'id' and the character tag is 'a'.
This is a convenience method for
getElement(RootElement, HTML.Attribute.id, id) .
This is not thread-safe.
if (id == null) {
return null;
}
return getElement(getDefaultRootElement(), HTML.Attribute.ID, id,
true);
| public javax.swing.text.Element | getElement(javax.swing.text.Element e, java.lang.Object attribute, java.lang.Object value)Returns the child element of e that contains the
attribute, attribute with value value , or
null if one isn't found. This is not thread-safe.
return getElement(e, attribute, value, true);
| private javax.swing.text.Element | getElement(javax.swing.text.Element e, java.lang.Object attribute, java.lang.Object value, boolean searchLeafAttributes)Returns the child element of e that contains the
attribute, attribute with value value , or
null if one isn't found. This is not thread-safe.
If searchLeafAttributes is true, and e is
a leaf, any attributes that are instances of HTML.Tag
with a value that is an AttributeSet will also be checked.
AttributeSet attr = e.getAttributes();
if (attr != null && attr.isDefined(attribute)) {
if (value.equals(attr.getAttribute(attribute))) {
return e;
}
}
if (!e.isLeaf()) {
for (int counter = 0, maxCounter = e.getElementCount();
counter < maxCounter; counter++) {
Element retValue = getElement(e.getElement(counter), attribute,
value, searchLeafAttributes);
if (retValue != null) {
return retValue;
}
}
}
else if (searchLeafAttributes && attr != null) {
// For some leaf elements we store the actual attributes inside
// the AttributeSet of the Element (such as anchors).
Enumeration names = attr.getAttributeNames();
if (names != null) {
while (names.hasMoreElements()) {
Object name = names.nextElement();
if ((name instanceof HTML.Tag) &&
(attr.getAttribute(name) instanceof AttributeSet)) {
AttributeSet check = (AttributeSet)attr.
getAttribute(name);
if (check.isDefined(attribute) &&
value.equals(check.getAttribute(attribute))) {
return e;
}
}
}
}
}
return null;
| public javax.swing.text.html.HTMLDocument$Iterator | getIterator(javax.swing.text.html.HTML$Tag t)Fetches an iterator for the specified HTML tag.
This can be used for things like iterating over the
set of anchors contained, or iterating over the input
elements.
if (t.isBlock()) {
// TBD
return null;
}
return new LeafIterator(t, this);
| javax.swing.text.html.Map | getMap(java.lang.String name)Returns the Map associated with the given name.
if (name != null) {
Object maps = getProperty(MAP_PROPERTY);
if (maps != null && (maps instanceof Hashtable)) {
return (Map)((Hashtable)maps).get(name);
}
}
return null;
| java.util.Enumeration | getMaps()Returns an Enumeration of the possible Maps.
Object maps = getProperty(MAP_PROPERTY);
if (maps instanceof Hashtable) {
return ((Hashtable)maps).elements();
}
return null;
| public javax.swing.text.html.HTMLEditorKit$Parser | getParser()Returns the parser that is used when inserting HTML into the existing
document.
Object p = getProperty("__PARSER__");
if (p instanceof HTMLEditorKit.Parser) {
return (HTMLEditorKit.Parser)p;
}
return parser;
| public boolean | getPreservesUnknownTags()Returns the behavior the parser observes when encountering
unknown tags.
return preservesUnknownTags;
| public javax.swing.text.html.HTMLEditorKit$ParserCallback | getReader(int pos)Fetches the reader for the parser to use when loading the document
with HTML. This is implemented to return an instance of
HTMLDocument.HTMLReader .
Subclasses can reimplement this
method to change how the document gets structured if desired.
(For example, to handle custom tags, or structurally represent character
style elements.)
Object desc = getProperty(Document.StreamDescriptionProperty);
if (desc instanceof URL) {
setBase((URL)desc);
}
HTMLReader reader = new HTMLReader(pos);
return reader;
| public javax.swing.text.html.HTMLEditorKit$ParserCallback | getReader(int pos, int popDepth, int pushDepth, javax.swing.text.html.HTML$Tag insertTag)Returns the reader for the parser to use to load the document
with HTML. This is implemented to return an instance of
HTMLDocument.HTMLReader .
Subclasses can reimplement this
method to change how the document gets structured if desired.
(For example, to handle custom tags, or structurally represent character
style elements.)
This is a convenience method for
getReader(int, int, int, HTML.Tag, TRUE) .
return getReader(pos, popDepth, pushDepth, insertTag, true);
| javax.swing.text.html.HTMLEditorKit$ParserCallback | getReader(int pos, int popDepth, int pushDepth, javax.swing.text.html.HTML$Tag insertTag, boolean insertInsertTag)Fetches the reader for the parser to use to load the document
with HTML. This is implemented to return an instance of
HTMLDocument.HTMLReader. Subclasses can reimplement this
method to change how the document get structured if desired
(e.g. to handle custom tags, structurally represent character
style elements, etc.).
Object desc = getProperty(Document.StreamDescriptionProperty);
if (desc instanceof URL) {
setBase((URL)desc);
}
HTMLReader reader = new HTMLReader(pos, popDepth, pushDepth,
insertTag, insertInsertTag, false,
true);
return reader;
| public javax.swing.text.html.StyleSheet | getStyleSheet()Fetches the StyleSheet with the document-specific display
rules (CSS) that were specified in the HTML document itself.
return (StyleSheet) getAttributeContext();
| public int | getTokenThreshold()Gets the number of tokens to buffer before trying to update
the documents element structure. The default value is
Integer.MAX_VALUE .
Integer i = (Integer) getProperty(TokenThreshold);
if (i != null) {
return i.intValue();
}
return Integer.MAX_VALUE;
| boolean | hasBaseTag()
return hasBaseTag;
| protected void | insert(int offset, ElementSpec[] data)Inserts new elements in bulk. This is how elements get created
in the document. The parsing determines what structure is needed
and creates the specification as a set of tokens that describe the
edit while leaving the document free of a write-lock. This method
can then be called in bursts by the reader to acquire a write-lock
for a shorter duration (i.e. while the document is actually being
altered).
super.insert(offset, data);
| public void | insertAfterEnd(javax.swing.text.Element elem, java.lang.String htmlText)Inserts the HTML specified as a string after the
the end of the given element.
For this to work correcty, the document must have an
HTMLEditorKit.Parser set. This will be the case
if the document was created from an HTMLEditorKit via the
createDefaultDocument method.
verifyParser();
if (elem != null) {
Element parent = elem.getParentElement();
if (parent != null) {
int offset = elem.getEndOffset();
if (offset > getLength()) {
offset--;
}
else if (elem.isLeaf() && getText(offset - 1, 1).
charAt(0) == NEWLINE[0]) {
offset--;
}
insertHTML(parent, offset, htmlText, false);
}
}
| public void | insertAfterStart(javax.swing.text.Element elem, java.lang.String htmlText)Inserts the HTML specified as a string at the start
of the element.
For this to work correcty, the document must have an
HTMLEditorKit.Parser set. This will be the case
if the document was created from an HTMLEditorKit via the
createDefaultDocument method.
verifyParser();
if (elem != null && elem.isLeaf()) {
throw new IllegalArgumentException
("Can not insert HTML after start of a leaf");
}
insertHTML(elem, elem.getStartOffset(), htmlText, false);
| public void | insertBeforeEnd(javax.swing.text.Element elem, java.lang.String htmlText)Inserts the HTML specified as a string at the end of
the element.
If elem 's children are leaves, and the
character at a elem.getEndOffset() - 1 is a newline,
this will insert before the newline so that there isn't text after
the newline.
For this to work correcty, the document must have an
HTMLEditorKit.Parser set. This will be the case
if the document was created from an HTMLEditorKit via the
createDefaultDocument method.
verifyParser();
if (elem != null && elem.isLeaf()) {
throw new IllegalArgumentException
("Can not set inner HTML before end of leaf");
}
int offset = elem.getEndOffset();
if (elem.getElement(elem.getElementIndex(offset - 1)).isLeaf() &&
getText(offset - 1, 1).charAt(0) == NEWLINE[0]) {
offset--;
}
insertHTML(elem, offset, htmlText, false);
| public void | insertBeforeStart(javax.swing.text.Element elem, java.lang.String htmlText)Inserts the HTML specified as a string before the start of
the given element.
For this to work correcty, the document must have an
HTMLEditorKit.Parser set. This will be the case
if the document was created from an HTMLEditorKit via the
createDefaultDocument method.
verifyParser();
if (elem != null) {
Element parent = elem.getParentElement();
if (parent != null) {
insertHTML(parent, elem.getStartOffset(), htmlText, false);
}
}
| private void | insertHTML(javax.swing.text.Element parent, int offset, java.lang.String html, boolean wantsTrailingNewline)Inserts a string of HTML into the document at the given position.
parent is used to identify the location to insert the
html . If parent is a leaf this can have
unexpected results.
if (parent != null && html != null) {
HTMLEditorKit.Parser parser = getParser();
if (parser != null) {
int lastOffset = Math.max(0, offset - 1);
Element charElement = getCharacterElement(lastOffset);
Element commonParent = parent;
int pop = 0;
int push = 0;
if (parent.getStartOffset() > lastOffset) {
while (commonParent != null &&
commonParent.getStartOffset() > lastOffset) {
commonParent = commonParent.getParentElement();
push++;
}
if (commonParent == null) {
throw new BadLocationException("No common parent",
offset);
}
}
while (charElement != null && charElement != commonParent) {
pop++;
charElement = charElement.getParentElement();
}
if (charElement != null) {
// Found it, do the insert.
HTMLReader reader = new HTMLReader(offset, pop - 1, push,
null, false, true,
wantsTrailingNewline);
parser.parse(new StringReader(html), reader, true);
reader.flush();
}
}
}
| protected void | insertUpdate(DefaultDocumentEvent chng, javax.swing.text.AttributeSet attr)Updates document structure as a result of text insertion. This
will happen within a write lock. This implementation simply
parses the inserted content for line breaks and builds up a set
of instructions for the element buffer.
if(attr == null) {
attr = contentAttributeSet;
}
// If this is the composed text element, merge the content attribute to it
else if (attr.isDefined(StyleConstants.ComposedTextAttribute)) {
((MutableAttributeSet)attr).addAttributes(contentAttributeSet);
}
if (attr.isDefined(IMPLIED_CR)) {
((MutableAttributeSet)attr).removeAttribute(IMPLIED_CR);
}
super.insertUpdate(chng, attr);
| private void | installParserIfNecessary()Installs a default Parser if one has not been installed yet.
if (getParser() == null) {
setParser(new HTMLEditorKit().getParser());
}
| private static final boolean | isComplex(char ch)
return (ch >= '\u0900" && ch <= '\u0D7F") || // Indic
(ch >= '\u0E00" && ch <= '\u0E7F"); // Thai
| private static final boolean | isComplex(char[] text, int start, int limit)
for (int i = start; i < limit; ++i) {
if (isComplex(text[i])) {
return true;
}
}
return false;
| boolean | isFrameDocument()Returns true if the document will be viewed in a frame.
return frameDocument;
| static boolean | matchNameAttribute(javax.swing.text.AttributeSet attr, javax.swing.text.html.HTML$Tag tag)Returns true if StyleConstants.NameAttribute is
equal to the tag that is passed in as a parameter.
Object o = attr.getAttribute(StyleConstants.NameAttribute);
if (o instanceof HTML.Tag) {
HTML.Tag name = (HTML.Tag) o;
if (name == tag) {
return true;
}
}
return false;
| void | obtainLock()
writeLock();
| public void | processHTMLFrameHyperlinkEvent(javax.swing.text.html.HTMLFrameHyperlinkEvent e)Processes HyperlinkEvents that
are generated by documents in an HTML frame.
The HyperlinkEvent type, as the parameter suggests,
is HTMLFrameHyperlinkEvent .
In addition to the typical information contained in a
HyperlinkEvent ,
this event contains the element that corresponds to the frame in
which the click happened (the source element) and the
target name. The target name has 4 possible values:
- _self
- _parent
- _top
- a named frame
If target is _self, the action is to change the value of the
HTML.Attribute.SRC attribute and fires a
ChangedUpdate event.
If the target is _parent, then it deletes the parent element,
which is a <FRAMESET> element, and inserts a new <FRAME>
element, and sets its HTML.Attribute.SRC attribute
to have a value equal to the destination URL and fire a
RemovedUpdate and InsertUpdate .
If the target is _top, this method does nothing. In the implementation
of the view for a frame, namely the FrameView ,
the processing of _top is handled. Given that _top implies
replacing the entire document, it made sense to handle this outside
of the document that it will replace.
If the target is a named frame, then the element hierarchy is searched
for an element with a name equal to the target, its
HTML.Attribute.SRC attribute is updated and a
ChangedUpdate event is fired.
String frameName = e.getTarget();
Element element = e.getSourceElement();
String urlStr = e.getURL().toString();
if (frameName.equals("_self")) {
/*
The source and destination elements
are the same.
*/
updateFrame(element, urlStr);
} else if (frameName.equals("_parent")) {
/*
The destination is the parent of the frame.
*/
updateFrameSet(element.getParentElement(), urlStr);
} else {
/*
locate a named frame
*/
Element targetElement = findFrame(frameName);
if (targetElement != null) {
updateFrame(targetElement, urlStr);
}
}
| void | releaseLock()
writeUnlock();
| private void | removeElements(javax.swing.text.Element e, int index, int count)Removes child Elements of the passed in Element e . This
will do the necessary cleanup to ensure the element representing the
end character is correctly created.
This is not a general purpose method, it assumes that e
will still have at least one child after the remove, and it assumes
the character at e.getStartOffset() - 1 is a newline and
is of length 1.
writeLock();
try {
int start = e.getElement(index).getStartOffset();
int end = e.getElement(index + count - 1).getEndOffset();
if (end > getLength()) {
removeElementsAtEnd(e, index, count, start, end);
}
else {
removeElements(e, index, count, start, end);
}
} finally {
writeUnlock();
}
| private void | removeElements(javax.swing.text.Element e, int index, int count, int start, int end)Called to remove child Elements when the end is not touched.
Element[] removed = new Element[count];
Element[] added = new Element[0];
for (int counter = 0; counter < count; counter++) {
removed[counter] = e.getElement(counter + index);
}
DefaultDocumentEvent dde = new DefaultDocumentEvent
(start, end - start, DocumentEvent.EventType.REMOVE);
((AbstractDocument.BranchElement)e).replace(index, removed.length,
added);
dde.addEdit(new ElementEdit(e, index, removed, added));
UndoableEdit u = getContent().remove(start, end - start);
if (u != null) {
dde.addEdit(u);
}
postRemoveUpdate(dde);
dde.end();
fireRemoveUpdate(dde);
if (u != null) {
fireUndoableEditUpdate(new UndoableEditEvent(this, dde));
}
| private void | removeElementsAtEnd(javax.swing.text.Element e, int index, int count, int start, int end)Called to remove child elements of e when one of the
elements to remove is representing the end character.
Since the Content will not allow a removal to the end character
this will do a remove from start - 1 to end .
The end Element(s) will be removed, and the element representing
start - 1 to start will be recreated. This
Element has to be recreated as after the content removal its offsets
become start - 1 to start - 1 .
// index must be > 0 otherwise no insert would have happened.
boolean isLeaf = (e.getElement(index - 1).isLeaf());
DefaultDocumentEvent dde = new DefaultDocumentEvent(
start - 1, end - start + 1, DocumentEvent.
EventType.REMOVE);
if (isLeaf) {
Element endE = getCharacterElement(getLength());
// e.getElement(index - 1) should represent the newline.
index--;
if (endE.getParentElement() != e) {
// The hiearchies don't match, we'll have to manually
// recreate the leaf at e.getElement(index - 1)
replace(dde, e, index, ++count, start, end, true, true);
}
else {
// The hierarchies for the end Element and
// e.getElement(index - 1), match, we can safely remove
// the Elements and the end content will be aligned
// appropriately.
replace(dde, e, index, count, start, end, true, false);
}
}
else {
// Not a leaf, descend until we find the leaf representing
// start - 1 and remove it.
Element newLineE = e.getElement(index - 1);
while (!newLineE.isLeaf()) {
newLineE = newLineE.getElement(newLineE.getElementCount() - 1);
}
newLineE = newLineE.getParentElement();
replace(dde, e, index, count, start, end, false, false);
replace(dde, newLineE, newLineE.getElementCount() - 1, 1, start,
end, true, true);
}
postRemoveUpdate(dde);
dde.end();
fireRemoveUpdate(dde);
fireUndoableEditUpdate(new UndoableEditEvent(this, dde));
| void | removeMap(javax.swing.text.html.Map map)Removes a previously registered map.
String name = map.getName();
if (name != null) {
Object maps = getProperty(MAP_PROPERTY);
if (maps instanceof Hashtable) {
((Hashtable)maps).remove("#" + name);
}
}
| private void | replace(DefaultDocumentEvent dde, javax.swing.text.Element e, int index, int count, int start, int end, boolean remove, boolean create)This is used by removeElementsAtEnd , it removes
count elements starting at start from
e . If remove is true text of length
start - 1 to end - 1 is removed. If
create is true a new leaf is created of length 1.
Element[] added;
AttributeSet attrs = e.getElement(index).getAttributes();
Element[] removed = new Element[count];
for (int counter = 0; counter < count; counter++) {
removed[counter] = e.getElement(counter + index);
}
if (remove) {
UndoableEdit u = getContent().remove(start - 1, end - start);
if (u != null) {
dde.addEdit(u);
}
}
if (create) {
added = new Element[1];
added[0] = createLeafElement(e, attrs, start - 1, start);
}
else {
added = new Element[0];
}
dde.addEdit(new ElementEdit(e, index, removed, added));
((AbstractDocument.BranchElement)e).replace(
index, removed.length, added);
| public void | setBase(java.net.URL u)Sets the location to resolve relative URLs against. By
default this will be the document's URL if the document
was loaded from a URL. If a base tag is found and
can be parsed, it will be used as the base location.
This also sets the base of the StyleSheet
to be u as well as the base of the document.
base = u;
getStyleSheet().setBase(u);
| void | setDefaultStyleSheetType(java.lang.String contentType)Sets the content type language used for style sheets that do not
explicitly specify the type. The default is text/css.
putProperty(StyleType, contentType);
| void | setFrameDocumentState(boolean frameDoc)Sets a boolean state about whether the document will be
viewed in a frame.
this.frameDocument = frameDoc;
| public void | setInnerHTML(javax.swing.text.Element elem, java.lang.String htmlText)Replaces the children of the given element with the contents
specified as an HTML string.
This will be seen as at least two events, n inserts followed by
a remove.
For this to work correcty, the document must have an
HTMLEditorKit.Parser set. This will be the case
if the document was created from an HTMLEditorKit via the
createDefaultDocument method.
verifyParser();
if (elem != null && elem.isLeaf()) {
throw new IllegalArgumentException
("Can not set inner HTML of a leaf");
}
if (elem != null && htmlText != null) {
int oldCount = elem.getElementCount();
int insertPosition = elem.getStartOffset();
insertHTML(elem, elem.getStartOffset(), htmlText, true);
if (elem.getElementCount() > oldCount) {
// Elements were inserted, do the cleanup.
removeElements(elem, elem.getElementCount() - oldCount,
oldCount);
}
}
| public void | setOuterHTML(javax.swing.text.Element elem, java.lang.String htmlText)Replaces the given element in the parent with the contents
specified as an HTML string.
This will be seen as at least two events, n inserts followed by
a remove.
When replacing a leaf this will attempt to make sure there is
a newline present if one is needed. This may result in an additional
element being inserted. Consider, if you were to replace a character
element that contained a newline with <img> this would create
two elements, one for the image, ane one for the newline.
If you try to replace the element at length you will most likely
end up with two elements, eg setOuterHTML(getCharacterElement
(getLength()), "blah") will result in two leaf elements at the end,
one representing 'blah', and the other representing the end element.
For this to work correcty, the document must have an
HTMLEditorKit.Parser set. This will be the case if the document
was created from an HTMLEditorKit via the
createDefaultDocument method.
verifyParser();
if (elem != null && elem.getParentElement() != null &&
htmlText != null) {
int start = elem.getStartOffset();
int end = elem.getEndOffset();
int startLength = getLength();
// We don't want a newline if elem is a leaf, and doesn't contain
// a newline.
boolean wantsNewline = !elem.isLeaf();
if (!wantsNewline && (end > startLength ||
getText(end - 1, 1).charAt(0) == NEWLINE[0])){
wantsNewline = true;
}
Element parent = elem.getParentElement();
int oldCount = parent.getElementCount();
insertHTML(parent, start, htmlText, wantsNewline);
// Remove old.
int newLength = getLength();
if (oldCount != parent.getElementCount()) {
int removeIndex = parent.getElementIndex(start + newLength -
startLength);
removeElements(parent, removeIndex, 1);
}
}
| public void | setParagraphAttributes(int offset, int length, javax.swing.text.AttributeSet s, boolean replace)Sets attributes for a paragraph.
This method is thread safe, although most Swing methods
are not. Please see
Threads
and Swing for more information.
try {
writeLock();
// Make sure we send out a change for the length of the paragraph.
int end = Math.min(offset + length, getLength());
Element e = getParagraphElement(offset);
offset = e.getStartOffset();
e = getParagraphElement(end);
length = Math.max(0, e.getEndOffset() - offset);
DefaultDocumentEvent changes =
new DefaultDocumentEvent(offset, length,
DocumentEvent.EventType.CHANGE);
AttributeSet sCopy = s.copyAttributes();
int lastEnd = Integer.MAX_VALUE;
for (int pos = offset; pos <= end; pos = lastEnd) {
Element paragraph = getParagraphElement(pos);
if (lastEnd == paragraph.getEndOffset()) {
lastEnd++;
}
else {
lastEnd = paragraph.getEndOffset();
}
MutableAttributeSet attr =
(MutableAttributeSet) paragraph.getAttributes();
changes.addEdit(new AttributeUndoableEdit(paragraph, sCopy, replace));
if (replace) {
attr.removeAttributes(attr);
}
attr.addAttributes(s);
}
changes.end();
fireChangedUpdate(changes);
fireUndoableEditUpdate(new UndoableEditEvent(this, changes));
} finally {
writeUnlock();
}
| public void | setParser(javax.swing.text.html.HTMLEditorKit$Parser parser)Sets the parser that is used by the methods that insert html
into the existing document, such as setInnerHTML ,
and setOuterHTML .
HTMLEditorKit.createDefaultDocument will set the parser
for you. If you create an HTMLDocument by hand,
be sure and set the parser accordingly.
this.parser = parser;
putProperty("__PARSER__", null);
| public void | setPreservesUnknownTags(boolean preservesTags)Determines how unknown tags are handled by the parser.
If set to true, unknown
tags are put in the model, otherwise they are dropped.
preservesUnknownTags = preservesTags;
| public void | setTokenThreshold(int n)Sets the number of tokens to buffer before trying to update
the documents element structure.
putProperty(TokenThreshold, new Integer(n));
| private void | updateFrame(javax.swing.text.Element element, java.lang.String url)Updates the Frame elements HTML.Attribute.SRC attribute
and fires a ChangedUpdate event.
try {
writeLock();
DefaultDocumentEvent changes = new DefaultDocumentEvent(element.getStartOffset(),
1,
DocumentEvent.EventType.CHANGE);
AttributeSet sCopy = element.getAttributes().copyAttributes();
MutableAttributeSet attr = (MutableAttributeSet) element.getAttributes();
changes.addEdit(new AttributeUndoableEdit(element, sCopy, false));
attr.removeAttribute(HTML.Attribute.SRC);
attr.addAttribute(HTML.Attribute.SRC, url);
changes.end();
fireChangedUpdate(changes);
fireUndoableEditUpdate(new UndoableEditEvent(this, changes));
} finally {
writeUnlock();
}
| private void | updateFrameSet(javax.swing.text.Element element, java.lang.String url)Replaces a frameset branch Element with a frame leaf element.
try {
int startOffset = element.getStartOffset();
int endOffset = Math.min(getLength(), element.getEndOffset());
String html = "<frame";
if (url != null) {
html += " src=\"" + url + "\"";
}
html += ">";
installParserIfNecessary();
setOuterHTML(element, html);
} catch (BadLocationException e1) {
// Should handle this better
} catch (IOException ioe) {
// Should handle this better
}
| private void | verifyParser()Verifies the document has an HTMLEditorKit.Parser set.
If getParser returns null , this will throw an
IllegalStateException.
if (getParser() == null) {
throw new IllegalStateException("No HTMLEditorKit.Parser");
}
|
|