What I’m trying to achieve
I’m trying to implement a component that auto-scrolls contents which are streamed to nested JPanel
s. The auto-scrolling should keep the scrollbar at the bottom and allow a user to move the scrollbar freely even when contents are being updated. Once the scroll bar is moved, I’d like for the panel to stay at the current view, even though the contents are continuously being updated. If the user scrolls all the way back to the bottom, the component should then scroll as new content is being added to the underlying contents
Issue
Currently my approach consists of setting the viewport of a JBScrollPane
to my collection of JPanel
s. For each JPanel
component, I’m nesting a JEditorPane
component, whose text is updated when streaming content. However, anytime streaming content is updating the JEditorPane
text, the scroll bar jumps to where the text has been updated. Effectively, this prevents the user from scrolling when contents are being streamed.
What I’ve tried
I set the updatePolicy
on all JEditorPane
s to be DefaultCaret.NEVER_UPDATE
.
val caret = msg.caret as DefaultCaret
caret.updatePolicy = DefaultCaret.NEVER_UPDATE
With this, the scroll pane no longer moves by itself. So I can scroll and view all contents while they are being updated. However, now I need to implement the scrolling by myself. To try and do that, when contents are updated, I’m checking the scroll position of the vertical scroll bar to see if it should be updated. This kind of works, where the scroll bar will automatically scroll while it’s at the bottom. But there’s some odd cases where it will jump to the top of the panel, when it should stay at the bottom
val scrollBar = mainContent.verticalScrollBar
val currentScrollPosition = scrollBar.value
val maxScrollPosition = scrollBar.maximum - scrollBar.visibleAmount
val shouldUpdateViewPort = currentScrollPosition >= maxScrollPosition
if (shouldUpdateViewPort) {
mainContent.viewport.viewPosition =
Point(
mainContentSize.width,
scrollBar.maximum,
)
}
Question
Is there a better option to implement auto-scrolling for scroll panes? I’ve been unable to find a cleaner alternative