2

I have a parent scrollpane which contains a webview as one of its children. When I scroll over the webview by having the mouse pointer on the webview area, it continues scrolling as expected till the end of the webview. However, is there a way where I can make the parent scrollpane scroll down, once the end of the child-webview is reached, while still the mouse pointer is on the webview-area ?

Sample Structure :

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.web.*?>

<ScrollPane prefHeight="455.0" prefWidth="602.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="wes.we.fx.view.ui.express.reports.generic.Demo">
   <content>
      <AnchorPane prefHeight="400.0" prefWidth="600.0">
         <children>
            <VBox layoutX="26.0">
               <children>
                  <WebView prefHeight="316.0" prefWidth="530.0" />
               </children>
            </VBox>
         </children>
      </AnchorPane>
   </content>
</ScrollPane>
vi90
  • 73
  • 8
  • 1
    [mcve] please .. – kleopatra Sep 02 '20 at 13:57
  • 1
    please read the referenced help page and act accordingly (you don't really expect us to write the boilerplate around the fxml, do you :) .. and keep it simple, not more ui elements as absolutely necessary to demonstrate what you are after (and doesn't work as you expect it) – kleopatra Sep 02 '20 at 14:01
  • Thanks for trying to guide me. But sorry, this is the basic structure that I am using. From the parent to the child. I do not know how to further simplify it for explaining better. The webview loads a long content and the user just scrolls over the webview not knowing there is more content below the webview. I saw some examples from javascript using the css, and was thinking it must be similar in this situation. – vi90 Sep 02 '20 at 14:29
  • 1
    okay, and now write the boilerplate app/controller and explain what you tried so far (most probably I'm not able to help, not knowing enough about webView - but others most certainly can :) – kleopatra Sep 02 '20 at 14:38

1 Answers1

0

Explanation of my solution: When using a WebView you can inject javascript which is what I used to pull values of the page to figure out when I was at the bottom. I am no JavaScript wiz so Im am not sure if there is a better solution here(I could not find one). I used the formula of screenTopPosition + screenTotalHeight to get the screenBottomPosition and compared that to the totalPageHeight if they are equal then you are at the bottom of the page this all worked as expected. This is where I feel it gets "Hacky" I couldn't figure out how to get the focus of the scrollbar from the scrollPane when at the bottom of the page. So my only other idea was to increment the scrollPane Vvalue by a fixed value when you were at the bottom of the webpage. The problem is the value you choose to increment it by may be different than the actual scrolling value incrementing I chose .1 once the Vvalue hits 1 it is at the bottom of the scrollPane

This is not exactly how I wanted to solve this problem hopefully someone can recommend a better solution that feels less "Hacky" and I would be glad to edit my answer if provided with guidance on how to figure out what the default incrementing is for the Vvalue

public class Main extends Application {

    @Override
    public void start(Stage stage) {
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setPrefSize(602, 455);

        AnchorPane anchorPane = new AnchorPane();
        anchorPane.setPrefSize(600, 400);
        scrollPane.setContent(anchorPane);

        VBox vBox = new VBox();
        vBox.setPrefWidth(530);
        vBox.setLayoutX(26);
        anchorPane.getChildren().add(vBox);

        WebView webView = new WebView();
        webView.setPrefSize(530,316);
        webView.getEngine().load("http://www.google.com");
        webView.setOnScroll(event -> {
            Integer screenTopPosition = (Integer) (webView.getEngine().executeScript("document.body.scrollTop"));
            Integer screenTotalHeight = (Integer) webView.getEngine().executeScript("document.body.clientHeight");
            Integer screenBottomPosition = screenTopPosition + screenTotalHeight;

            Integer totalPageHeight = (Integer) webView.getEngine().executeScript("document.body.scrollHeight");

            if(screenBottomPosition.equals(totalPageHeight)){
                System.out.println("Bottom of Page Reached");
                scrollPane.setVvalue(scrollPane.getVvalue()+.1);
            }
        });
        vBox.getChildren().add(webView);

        Label label = new Label("Content\nContent");
        label.setFont(new Font(100));
        vBox.getChildren().add(label);

        stage.setScene(new Scene(scrollPane));
        stage.show();
    }
}
Matt
  • 3,052
  • 1
  • 17
  • 30