JEditorPaneのスクロールに連動してJTreeのノードを選択する
Total: 2066
, Today: 2
, Yesterday: 2
Posted by aterai at
Last-modified:
概要
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を有効に戻す }); }