Swing/Scrollspy のバックアップ(No.1)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/Scrollspy へ行く。
- 1 (2020-01-13 (月) 03:48:10)
- 2 (2020-01-30 (木) 19:26:47)
- 3 (2021-07-24 (土) 23:44:59)
- category: swing folder: Scrollspy title: JEditorPaneのスクロールに連動してJTreeのノードを選択する tags: [JEditorPane, JTree, JScrollPane, HTMLDocument, Html] author: aterai pubdate: 2020-01-13T03:43:21+09:00 description: JEditorPaneのスクロールに連動して表示状態になったリンクと同名のJTreeノードを検索・選択します。 image: https://drive.google.com/uc?id=1WPiIXVEn_n8seXVfgwCByMIWUPocOwmF
概要
JEditorPaneのスクロールに連動して表示状態になったリンクと同名のJTreeノードを検索・選択します。
Screenshot
Advertisement
サンプルコード
JScrollPane scroll = new JScrollPane(editor);
scroll.getVerticalScrollBar().getModel().addChangeListener(e -> {
HTMLDocument.Iterator itr = doc.getIterator(HTML.Tag.A);
for (; itr.isValid(); itr.next()) {
try {
Rectangle r = editor.modelToView(itr.getStartOffset());
if (r != null && editor.getVisibleRect().contains(r.getLocation())) {
searchTreeNode(tree, itr.getAttributes().getAttribute(HTML.Attribute.NAME));
break;
}
} catch (BadLocationException ex) {
UIManager.getLookAndFeel().provideErrorFeedback(editor);
}
}
});
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JEditorPane
を配置したJScrollPane
の縦ScrollBar
にChangeListener
を設定し、表示状態になったリンクと同名のJTree
ノードを検索して選択します。
- リンクが表示されているかは
HTMLDocument#getIterator(HTML.Tag.A)
で取得した<a>
タグの先頭位置がJEditorPane#getVisibleRect()
で取得した表示範囲に含まれるかで判断 JTree
側にはノードをマウスクリックなどで選択したらJEditorPane#scrollToReference(ref)
でそのリンクまでスクロールするTreeSelectionListener
を追加しているので、JEditorPane
側からのノード選択を実行する場合はそのTreeSelectionListener
が反応しないよう設定する必要があるtree.addTreeSelectionListener(e -> { if (!tree.isEnabled()) { // JEditorPane側からのノード選択は無視する return; } Object o = e.getNewLeadSelectionPath().getLastPathComponent(); if (o instanceof DefaultMutableTreeNode) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) o; String ref = Objects.toString(node.getUserObject()); editor.scrollToReference(ref); } }); // ... private static void searchTreeNode(JTree tree, Object name) { TreeModel model = tree.getModel(); DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); Collections.list((Enumeration<?>) root.preorderEnumeration()).stream() .filter(DefaultMutableTreeNode.class::isInstance) .map(DefaultMutableTreeNode.class::cast) .filter(node -> Objects.equals(name, Objects.toString(node.getUserObject()))) .findFirst() .ifPresent(node -> { tree.setEnabled(false); // JTreeに設定したTreeSelectionListenerを無効にする TreePath path = new TreePath(node.getPath()); tree.setSelectionPath(path); tree.scrollPathToVisible(path); tree.setEnabled(true); // JTreeに設定したTreeSelectionListenerを有効に戻す }); }