7

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?

4
  • I don't think the problem is in the html file but anyway, I updated it. Commented Dec 30, 2016 at 17:35
  • No, but it gives me something to test with. Commented Dec 30, 2016 at 17:46
  • Where is the html content going to be located? Are you really loading from the file system, or is the HTML file and the associated resources (image, etc) going to be bundled as part of the application? For example, when you package your application as a jar file, are the html and image going to be in the jar file? Or are you dynamically loading them from somewhere external to the application? Commented Dec 30, 2016 at 17:48
  • Sorry if I didn't answered you, firstly I was trying to load it from an external jar then I though that was not possible and I extracted the html from the jar and loaded it thorugh file system. But know thanks to your answer I decided to load it directly from the jar. Commented Dec 30, 2016 at 20:36

4 Answers 4

2

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:

enter image description here

Project layout:

htmltest
  - HTMLTest.class
  - html
    - test.html
    - img
      - testImage.png

Screenshot:

enter image description here

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());
Sign up to request clarification or add additional context in comments.

2 Comments

It wasn't exactly my problem since I had to load a file from an external folder but thank you so much, I didn't know that was possible load an image inside a jar without unzipping it. I'll change some code ;)
In that case use the code at the end of the answer, which will load the image from the folder you specify in the argument to the File constructor.
1

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.

Comments

0

First, you have to get local path of an image as string

String path = System.getProperty("user.dir");

Then you have to replace "\" marks with "/" in local path

path = path.replace("\\", "/");

Then you can print path using system.out.print(path) and it will get your local directry path of your JavaFx project like D:/Projects/Java_Fx/My_Project
If your imege file in a folder like "img" use path += "/img/";
Then your image local path will D:/Projects/Java_Fx/My_Project/img/

Then load html file like this

webView.getEngine().loadContent("<!doctype html>  \n" +
                                "<html>          \n" +
                                "<head>     \n" +
                                "<meta charset='utf-8'>   \n" +
                                "<title>Your html</title>    \n" +
                                "</head>             \n" +

                                "<body>          \n" +
                                    "<h1 style='color:red; font-style: italic'>      \n" +
                                    "This is opencraft's presentation :)             \n" +
                                    "</h1>           \n" +
                                    "<img src='file:/"+path+"image.png'>         \n" +
                                    "<p>                 \n" +
                                    "   This is a simple description of how the game works.      \n" +
                                    "</p>        \n" +
                                "</body>             \n" +
                                "</html>"

I've directly loaded html to engine with passing "path" before image.png and used single quote everywhere inside html code and double quote to string concatenation
<img src='file:/"+path+"image.png'>
If you want to insert image as backgroud image you can use
style='background-image: url(file:/"+path+"image.png);'

Comments

-1

Try using a hard link to the location of the html file in your webView.getEngine().loadContent("path/to/file.html");

Something like this

String htmlFile = "file:///c:/full/path/to/file.html";
webView.getEngine().loadContent(htmlFile);

Although this might give you some more issues when you want to package your app (if the html files and resources are going to be packaged with the app), there are also workarounds with that too. So, its safer that your html files and resources are not packaged with the app. I'll try to update this post to reflect that too.

3 Comments

@loryruta The problem is it will stop working when you deploy your application.
No it isn't since I know where's the html file is stored for any computer since I unzipped it from the jar at a specified location. But anyway, your method of solving this problem @James_D was better, thank you :)
@loryruta OK, fair enough. But I also strongly recommend not creating a file:: URL by hand like this: presumably for example to create the "specified location" you are looking up the user's home directory and concatenating it into the file path (or something similar). If that directory contains characters that are illegal in a URL (such as whitespace) you will need to replace them. The File.toURI() method will take care of all that for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.