Code
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);
}
}
});
// ...
tree.addTreeSelectionListener(e -> {
if (!tree.isEnabled()) { // Ignore node selection from JEditorPane side
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); // Disable TreeSelectionListener in JTree
TreePath path = new TreePath(node.getPath());
tree.setSelectionPath(path);
tree.scrollPathToVisible(path);
tree.setEnabled(true); // Restores TreeSelectionListener in JTree
});
}
References