I have a JEditorPane which shows HTML content with images. I found this article: JEditorPane with inline image. In this article is mentioned to use a protocol handler "resource:" for class path resources.
I tried this and got it working, when I run the application from Eclipse. But when I run it with a generated JAR file I'm not able to read the image out of the JAR file.
This is my version of the connection class:
public class ResourceConnection extends URLConnection {
protected ResourceConnection(URL url) {
super(url);
}
@Override
public void connect() throws IOException {
connected = true;
}
@Override
public InputStream getInputStream() throws IOException {
String filename = url.getFile();
URL resourceURL = ResourceConnection.class.getResource(filename);
String resourcePath = resourceURL.toString();
Path path = null;
if (resourcePath.startsWith("file:")) {
resourcePath = resourcePath.substring(5);
path = Paths.get(resourcePath);
} else if (resourcePath.startsWith("jar:")) {
// TODO path to image in jar file
}
if (path != null) {
byte[] bytes = Files.readAllBytes(path);
return new ByteArrayInputStream(bytes);
} else {
return null;
}
}
}
When I run it from Eclipse, the resourcePath
looks like file:/path/to/my/project/bin/path/to/image.png
. From this I have to remove the file:
and the image will be shown.
When I run it with a JAR file, the resourcePath
looks like jar:file:/path/to/the/jarfile.jar!/path/to/image.png
. I don't how I have to manipulate the path so that Files.readAllBytes
can read it. I tried the following:
jar:
jar:file:
resourceURL
to an URI
and used that with Paths.get
. This resulted with an java.nio.file.FileSystemNotFoundException
.The interessting thing is, when I create an ImageIcon
with resourceURL
the image is loaded (getIconWidth()
and getIconHeight()
return the correct values).
Edit:
The tag in the HTML source looks like <img src="resource:/path/to/image.png">
.
Edit:
The answer of Andrew Thompson gave me the idea to use a FileInputStream
.
public InputStream getInputStream() throws IOException {
try {
String filename = url.getFile();
URL resourceURL = ResourceConnection.class.getResource(filename);
return new FileInputStream(new File(resourceURL.toURI()));
} catch (FileNotFoundException | URISyntaxException e) {
e.printStackTrace();
return null;
}
}
This again works fine from Eclipse but with the JAR file I get java.lang.IllegalArgumentException: URI is not hierarchical
. Probably because the URL begins with jar:file:
.
I got it finally working.
public class ResourceConnection extends URLConnection {
protected ResourceConnection(URL url) {
super(url);
}
@Override
public void connect() throws IOException {
connected = true;
}
@Override
public InputStream getInputStream() throws IOException {
return ResourceConnection.class.getResource(url.getFile()).openConnection().getInputStream();
}
}
Thanks to Andrew Thompson for the idea to work with streams.