Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebView not reloading page with identical URL

JavaFX shows some odd behaviour when loading a page that has an identical url to a page that has been loaded before. The code below demonstrates this issue:

After class initalization a page is loaded, then a highlight is applied to an arbitrary html element using a custom style class. This highlight is rendered correctly.

Finally, through user input event, the WebView is told to load a new page (with the same URI). Instead of showing the page as-is, the highlight is shown as well.

WebView webView = new WebView();
static String URI = "http://www.example.com";

public void loadPage() {
    // Step 1: load page
    webView.getEngine().load(URI);

    // Step 2: Change style attribute in page
    (Element) element = xpath.evaluate("//div[@id='mydiv']", webView.getEngine().getDocument(), XPathConstants.NODE);
    element.setAttribute("class", "mystyle");
}

handle() {
    // Step 3: load page again
    webView.getEngine().load(URI);
}

I have experimented with forcing the page to reload with WebView.getEngine().reload(), disabling cache, waiting for workers to complete, etc.

The only option I currently see is to create a new instance of the WebView, but as this is pretty CPU heavy, I prefer to reuse the object rather than creating it new every time I want to revert to the original page.

like image 968
Stern Avatar asked Nov 01 '22 16:11

Stern


1 Answers

Here is a SSCCE that demonstrates the reloading of the HTML content. It is bit different from your approach but the story is the same, though didn't try loading an external URL like yours. You are right about caching of webEngine since the webEngine.reload() does not load the original content.

public class WebViewReload extends Application {

    private String content = "<html>"
            + "    <head>"
            + "         <style type=\"text/css\">"
            + "            .mystyle {"
            + "                padding: 20px;"
            + "                background-color: red;"
            + "                font-size: 30px;"
            + "            }"
            + "        </style>"
            + "    </head>"
            + "    <body>"
            + "        <div id=\"mydiv\">initial content</div>"
            + "    </body>"
            + "</html>";

    @Override
    public void start(final Stage stage) throws Exception {
        final WebView webView = new WebView();
        webView.getEngine().loadContent(content);
        // It is same as loading an external html source, like this
        // webView.getEngine().load(getClass().getResource("my.html").toExternalForm());

        Button btn1 = new Button("Apply style");
        btn1.setPrefWidth(200);
        btn1.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                Element element = webView.getEngine().getDocument().getElementById("mydiv");
                element.setAttribute("class", "mystyle");
                element.setTextContent("new content");
            }
        });

        Button btn2 = new Button("Reload content");
        btn2.setPrefWidth(200);
        btn2.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                webView.getEngine().loadContent(content);
                // following does not reload at all
                // webView.getEngine().reload();
            }
        });

        VBox vbox = new VBox(10);
        vbox.setPadding(new Insets(20));
        vbox.setStyle("-fx-background-color: gray");
        vbox.getChildren().addAll(webView, btn1, btn2);

        Scene scene = new Scene(vbox);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
like image 115
Uluk Biy Avatar answered Nov 08 '22 04:11

Uluk Biy