Synchronize Editor scrollbar with WebView scrollbar
Thangalin
thangalin at gmail.com
Tue Jun 16 15:20:48 UTC 2020
Aloha List!
How would you synchronize the scrollbars for a StyleClassedTextArea
with a WebView instance, without using JavaScript?
Here's a code snippet that shows the overall objective:
public class ScrollSync extends Application {
private final StyleClassedTextArea mEditor =
new StyleClassedTextArea( false );
private final VirtualizedScrollPane<StyleClassedTextArea> mEditorScrollPane =
new VirtualizedScrollPane<>( mEditor );
private final WebView mWebView = new WebView();
private final String mHtml =
"<!DOCTYPE html><html><body>%CONTENT%</body></html>";
public static void main( final String[] args ) {
launch( args );
}
@Override
public void start( final Stage stage ) {
mEditorScrollPane.setVbarPolicy( ScrollPane.ScrollBarPolicy.ALWAYS );
mEditor.textProperty().addListener(
( observable, oldValue, newValue ) -> {
mWebView.getEngine().loadContent(
mHtml.replace( "%CONTENT%", newValue )
);
}
);
final SplitPane splitPane = new SplitPane(
mEditorScrollPane,
mWebView
);
stage.setScene( new Scene( splitPane, 800, 400 ) );
stage.show();
}
}
Using FlyingSaucer, JScrollPane, and a SwingNode:
private final Consumer<Double> mScrollEventObserver = o -> {
final var eScrollPane = getActiveEditor().getScrollPane();
final int eScrollY = eScrollPane
.estimatedScrollYProperty().getValue().intValue();
final int eHeight = (int) (eScrollPane
.totalHeightEstimateProperty().getValue().intValue()
- eScrollPane.getHeight());
final double eRatio = eHeight > 0
? Math.min( Math.max( eScrollY / (float) eHeight, 0 ), 1 ) : 0;
final var pPreviewPane = getPreviewPane();
final var pScrollBar = pPreviewPane.getVerticalScrollBar();
final var pHeight = pScrollBar.getMaximum() - pScrollBar.getHeight();
final var pScrollY = (int) (pHeight * eRatio);
final var pScrollPane = pPreviewPane.getScrollPane();
final int oldScrollY = mScrollRatio.getAndSet( pScrollY );
final int delta = Math.abs( oldScrollY - pScrollY );
if( delta > 33 ) {
// Prevent concurrent modification exceptions when attempting to
// set the vertical scroll bar position.
synchronized( mMutex ) {
Platform.runLater( () -> {
pScrollBar.setValue( pScrollY );
pScrollPane.repaint();
} );
}
}
};
The "delta > 33" is required because it appears the values for
estimatedScrollYProperty() and totalHeightEstimateProperty() are
unstable. (That is, they fluctuate when typing along the same row
within the text area.)
How would you get a reference to the WebView's vertical scroll bar?
I've tried using lookup( ".scroll-bar:vertical" ), but the object
wasn't responsive to changing the scroll bar position.
Thank you!
More information about the openjfx-discuss
mailing list