Swing/HTMLAttributeID のバックアップ(No.6)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/HTMLAttributeID へ行く。
- 1 (2013-09-09 (月) 03:01:50)
- 2 (2013-09-09 (月) 04:06:08)
- 3 (2014-05-22 (木) 14:30:02)
- 4 (2014-08-27 (水) 21:11:19)
- 5 (2014-10-31 (金) 01:40:03)
- 6 (2015-02-27 (金) 12:02:13)
- 7 (2016-12-20 (火) 14:00:43)
- 8 (2017-08-23 (水) 18:41:49)
- 9 (2018-09-11 (火) 14:34:41)
- 10 (2020-09-03 (木) 09:44:21)
- 11 (2022-03-19 (土) 11:33:37)
- title: JEditorPaneのHTMLDocumentからIDでElementを取得する tags: [JEditorPane, HTMLDocument, Element, HTMLEditorKit, ParserDelegator, Highlighter] author: aterai pubdate: 2013-09-09T03:01:50+09:00 description: JEditorPaneに設定したHTMLDocumentを検索してid属性を持つElementを取得します。
概要
JEditorPane
に設定したHTMLDocument
を検索してid
属性を持つElement
を取得します。
Screenshot
Advertisement
サンプルコード
private void traverseElementById(Element element) {
if (element.isLeaf()) {
checkID(element);
} else {
for (int i = 0; i < element.getElementCount(); i++) {
Element child = element.getElement(i);
checkID(child);
if (!child.isLeaf()) {
traverseElementById(child);
}
}
}
}
private void checkID(Element element) {
AttributeSet attrs = element.getAttributes();
Object elementName = attrs.getAttribute(
AbstractDocument.ElementNameAttribute);
Object name = (elementName != null)
? null : attrs.getAttribute(StyleConstants.NameAttribute);
HTML.Tag tag;
if (name instanceof HTML.Tag) {
tag = (HTML.Tag)name;
} else {
return;
}
textArea.append(String.format("%s%n", tag));
if (tag.isBlock()) { //block
Object bid = attrs.getAttribute(HTML.Attribute.ID);
if (bid != null) {
textArea.append(String.format("block: id=%s%n", bid));
addHighlight(element, true);
}
} else { //inline
Enumeration e = attrs.getAttributeNames();
while (e.hasMoreElements()) {
Object obj = attrs.getAttribute(e.nextElement());
//System.out.println("AttributeNames: "+obj);
if (obj instanceof AttributeSet) {
AttributeSet a = (AttributeSet)obj;
Object iid = a.getAttribute(HTML.Attribute.ID);
if (iid != null) {
textArea.append(String.format("inline: id=%s%n", iid));
addHighlight(element, false);
}
}
}
}
}
View in GitHub: Java, Kotlin解説
Element#getElement(id)
- HTMLDocument#getElement(String)メソッドを使用して指定した
id
を持つElement
を取得 - これらの
Element
は、org.w3c.dom.Element
ではなく、javax.swing.text.Element
インタフェースを実装するHTMLDocument.BlockElement
などorg.w3c.dom.Document#getElementById(String)
などは使用できない
- 指定した
id
のElement
が存在した場合、editorPane.select(element.getStartOffset(), element.getEndOffset());
で選択element.getStartOffset()
などで取得されるオフセットは、JEditorPane
に表示されない要素や属性は含まれない
- HTMLDocument#getElement(String)メソッドを使用して指定した
Highlight Element[@id]
id
属性を持つElement
をハイライト表示HTMLDocument.BlockElement
などには、html
の要素や属性が後で復元するための備考としてAttributeSet
に保存されている- ブロック要素とインライン要素で属性の保存されている場所が異なる
DefaultHighlighter#setDrawsLayeredHighlights(false)
の場合、改行を含むハイライトや選択状態の描画がおかしくなる?
ParserDelegator
ParserDelegator
を使って文字列をパースし、HTMLEditorKit.ParserCallback#handleStartTag(...)
でタグの開始を見つけたら、MutableAttributeSet#getAttribute(HTML.Attribute.ID);
でそのタグのid
を取得javax.swing.text.Element
とは無関係に、JEditorPane#getText()
で取得した文字列をhtml
として解析しているHTMLEditorKit
が設定されたJEditorPane
からgetText()
で取得された文字列には、<body>
などのタグが自動的に補完されているので、元のhtml
テキストとは異なる点に注意
System.out.println("ParserDelegator");
final String id = field.getText().trim();
final String text = editorPane.getText();
ParserDelegator delegator = new ParserDelegator();
try {
delegator.parse(new StringReader(text), new HTMLEditorKit.ParserCallback() {
@Override public void handleStartTag(
HTML.Tag tag, MutableAttributeSet a, int pos) {
Object attrid = a.getAttribute(HTML.Attribute.ID);
textArea.append(String.format("%s@id=%s%n", tag, attrid));
if (id.equals(attrid)) {
textArea.append(String.format("found: pos=%d%n", pos));
int endoffs = text.indexOf('>', pos);
textArea.append(String.format("%s%n", text.substring(pos, endoffs + 1)));
}
}
}, Boolean.TRUE);
} catch (Exception ex) {
ex.printStackTrace();
}