• category: swing folder: ScrollToReference title: JEditorPane内のリンク参照位置までスクロールする tags: [JEditorPane, HTMLDocument, JScrollPane] author: aterai pubdate: 2019-10-28T02:33:24+09:00 description: JEditorPaneのHTMLDocument内に配置されたリンクのアンカータグが表示される位置までスクロールします。 image: https://drive.google.com/uc?id=1dnBj5zunBtGVHQ4iD2Kgwqe6IbWCjYSV

概要

JEditorPaneのHTMLDocument内に配置されたリンクのアンカータグが表示される位置までスクロールします。

サンプルコード

HTMLEditorKit htmlEditorKit = new HTMLEditorKit();
JEditorPane editor = new JEditorPane();
editor.setEditable(false);
editor.setEditorKit(htmlEditorKit);
HTMLDocument doc = (HTMLDocument) editor.getDocument();
String tag = "<a name='%s'>%s</a>";
doc.insertBeforeEnd(element, String.format(tag, ref, ref));

tree.addTreeSelectionListener(e -> {
  Object o = e.getNewLeadSelectionPath().getLastPathComponent();
  if (o instanceof DefaultMutableTreeNode) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) o;
    String ref = Objects.toString(node.getUserObject());
    editor.scrollToReference(ref);
  }
});
View in GitHub: Java, Kotlin

解説

  • JTreeのノードを選択すると、そのノードのUserObjectと一致する<a>アンカータグのname属性をもつリンクをまでJEditorPane#scrollToReference(ref)メソッドを使用してビューをスクロールする
    • id属性やhref属性などを指定してもJEditorPane#scrollToReference(ref)メソッドでは効果がない
  • bottomボタンをクリックすると、ドキュメントの末尾に記述した<p id='bottom'>タグが表示される位置までスクロール
    • JEditorPane#scrollToReference(ref)メソッドの実装を参考にして、HTMLElement#getElement(id)メソッドでidbottomElementを検索してその位置までJEditorPane#scrollRectToVisible(...)メソッドでスクールするメソッドを作成
private static void scrollToId(JEditorPane editor, String id) {
  Document d = editor.getDocument();
  if (d instanceof HTMLDocument) {
    HTMLDocument doc = (HTMLDocument) d;
    Element element = doc.getElement(id);
    try {
      int pos = element.getStartOffset();
      Rectangle r = editor.modelToView(pos);
      if (r != null) {
        Rectangle vis = editor.getVisibleRect();
        r.height = vis.height;
        editor.scrollRectToVisible(r);
        editor.setCaretPosition(pos);
      }
    } catch (BadLocationException ex) {
      UIManager.getLookAndFeel().provideErrorFeedback(editor);
    }
  }
}

参考リンク

コメント