带有来自 jar 文件的内联图像的 JEditorPane

JEditorPane with inline image from jar file

我有一个 JEditorPane,它显示 HTML 带有图像的内容。 我找到了这篇文章:JEditorPane with inline image。 在本文中提到使用协议处理程序“资源:” class 路径资源。

当我 运行 来自 Eclipse 的应用程序时,我尝试了这个并让它工作。 但是当我 运行 使用生成的 JAR 文件时,我无法从 JAR 文件中读取图像。

这是我的连接版本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;
        }
    }
}

当我从 Eclipse 中 运行 时,resourcePath 看起来像 file:/path/to/my/project/bin/path/to/image.png。从这里我必须删除 file: 并且图像将被显示。

当我 运行 使用 JAR 文件时,resourcePath 看起来像 jar:file:/path/to/the/jarfile.jar!/path/to/image.png。我不知道我必须如何操纵路径以便 Files.readAllBytes 可以读取它。我尝试了以下方法:

有趣的是,当我用 resourceURL 创建一个 ImageIcon 时,图像被加载(getIconWidth()getIconHeight() return 正确的值) .

编辑:

HTML 来源中的标签看起来像 <img src="resource:/path/to/image.png">

编辑:

Andrew Thompson 的回答让我想到了使用 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;
    }
}

这在 Eclipse 中再次正常工作,但我得到了 JAR 文件 java.lang.IllegalArgumentException: URI is not hierarchical。可能是因为 URL 以 jar:file:.

开头

终于搞定了。

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();
    }
}

感谢 Andrew Thompson 提出使用流的想法。