Well, I have an html file with a tag that points to an image inside the folder /img/. Through a JavaFX window application (not in the same path of the html file) I load the html file but the image does not load. Here's how I load the html file:
@FXML
WebView webView; // I get the webView through @FXML annotation
...
webView.getEngine().loadContent("path/to/file.html");
HTML file structure:
path/to/file.html
path/to/img/image.png
Here's HTML content:
<h1 style="color:red; font-style: italic">
This is opencraft's presentation :)
</h1>
<img src="img/image.png">
<p>
This is a simple description of how the game works, lol.
</p>
THE IMAGE GET LOADED IF I LOAD IT WITH THE BROWSER
Anyone could help me?
Basically, the issue is that you need a complete URL, including the scheme etc, for relative links within the html to work. A URL that is relative to the current class or the working directory will not work.
Assuming the html file and the associated image are bundled with the application (i.e. when you build a jar file for the application, the html file and image will be part of the jar file), then you can retrieve a URL for the html file with
getClass().getClassLoader().getResource("path/to/file.html");
where the path is relative to the classpath. You can then use toExternalForm()
to convert to a String
in the appropriate format. This is appropriate for html help pages, etc.
Here is an example:
HTMLTest.java:
package htmltest;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class HTMLTest extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
WebView webView = new WebView();
webView.getEngine().load(getClass().getClassLoader().getResource("htmltest/html/test.html").toExternalForm());
Scene scene = new Scene(webView, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
test.html:
<html>
<head><title>Test</title></head>
<body>
<h1>Test page</h1>
<img src="img/testImage.png"/>
</body>
</html>
testImage.png:
Project layout:
htmltest
- HTMLTest.class
- html
- test.html
- img
- testImage.png
Screenshot:
On the other hand, if you are genuinely loading the HTML file from the filesystem, you can create a File
object for the HTML file, and then convert that to a URI. This would be appropriate, for example, if you were writing an HTML editor in which the user edited the HTML file and saved it to the file system, and you wanted to display the result in a web view; or alternatively if you prompted the user to load an HTML file with a FileChooser
.
The code for this would look like:
File htmlFile = new File(...); // or get from filechooser...
webEngine.load(htmlFile.toURI().toString());
I ran into the same problem and solved it by modifying the src reference in the image at runtime. This code will work when run inside of your IDE and when the application is run in a JAR file. Tested using 1.8.0_121 on Ubuntu and Windows 10.
Platform.runLater( () -> {
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
if (newState == Worker.State.SUCCEEDED) {
NodeList nodeList = doc.getElementsByTagName("img");
for (int i = 0; i < nodeList.getLength(); i++) {
HTMLImageElement n = (HTMLImageElement)nodeList.item(i);
String path = n.getSrc();
if( path.startsWith("file://")) {
path = path.substring(7,path.length());
} else if( path.startsWith("jar:")) {
path = path.substring(4,path.length());
}
URL m = YOURCLASS.class.getResource(path);
if( m != null ) {
n.setSrc(m.toExternalForm());
}
}
}
}
});
webEngine.load( url );
}
Inside your HTML you should specify the image using the full resource path. You can use a relative path if you're careful with the selection of YOURCLASS.
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