JEditorPaneのHTMLDocumentからIDでElementを取得する
Total: 5786, Today: 2, Yesterday: 0
Posted by aterai at
Last-modified:
Summary
JEditorPaneに設定したHTMLDocumentを検索してid属性を持つElementを取得します。
Screenshot

Advertisement
Source Code Examples
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, KotlinDescription
Element#getElement(id)- HTMLDocument#getElement(String)メソッドを使用して指定した
idを持つElementを取得 - これらの
Element(HTMLDocument.BlockElementなど)はorg.w3c.dom.Elementではなくjavax.swing.text.Elementインタフェースを実装しているので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)の場合、改行を含むハイライトや選択状態の描画がおかしくなる?
ParserDelegatorParserDelegatorを使って文字列をパースし、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(); }
Reference
HTMLDocument (Java Platform SE 8)