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.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With