JEditorPane со встроенным изображением из файла jar

У меня есть JEditorPane, который показывает содержимое HTML с изображениями. Я нашел эту статью: JEditorPane со встроенным изображением. В этой статье упоминается использование ресурса обработчика протокола: для ресурсов пути к классу.

Я попробовал это и заработал, когда запускаю приложение из Eclipse. Но когда я запускаю его со сгенерированным файлом JAR, я не могу прочитать изображение из файла JAR.

Это моя версия класса соединения:

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 мог его прочитать. Я пробовал следующее:

  • без манипуляций
  • удалено jar:
  • удалено jar:file:
  • преобразовал resourceURL в URI и использовал его с Paths.get. Это привело к ошибке java.nio.file.FileSystemNotFoundException.

Интересно то, что когда я создаю ImageIcon с resourceURL, изображение загружается (getIconWidth() и getIconHeight() возвращают правильные значения).

Изменить:

Тег в исходном коде HTML выглядит как <img src="resource:/path/to/image.png">.

Изменить:

Ответ Эндрю Томпсона натолкнул меня на мысль использовать 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:.


person Joe    schedule 29.01.2021    source источник


Ответы (1)


У меня наконец заработало.

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

Спасибо Эндрю Томпсону за идею работы с потоками.

person Joe    schedule 30.01.2021