From thangalin at gmail.com Tue Jun 16 15:20:48 2020 From: thangalin at gmail.com (Thangalin) Date: Tue, 16 Jun 2020 08:20:48 -0700 Subject: Synchronize Editor scrollbar with WebView scrollbar Message-ID: 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 mEditorScrollPane = new VirtualizedScrollPane<>( mEditor ); private final WebView mWebView = new WebView(); private final String mHtml = "%CONTENT%"; 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 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!