是否可以/如何在JAR中嵌入和访问HTML文件?

时间:2013-08-26 11:44:18

标签: java html swing jar jeditorpane

我现在有点受阻:我写了一个非常复杂的Java桌面应用程序(没有Applet / Web App!),它有自己的“用户手册”。本手册包含一些HTML和JPG文件。本手册使用JEditorPane显示在我的应用程序的“帮助菜单”中。

到目前为止一切顺利。只要我使用Eclipse启动Programm,这种方法就可以正常工作。只要我将部署版本创建为可运行的jar(使用launch4j将其包装到.exe中),HTML“Viewer”就无法显示用户手册(图像丢失)。

我明白为什么会这样,但我不知道如何解决/规避这个问题。

我的应用程序通过getClass()。getResource()加载其资源(属性文件,图标等)。例子:

this.setIconImage(new ImageIcon(getClass().getResource("/images/dialog-question.png")).getImage());

stream = new BufferedInputStream(MABIUpdater.class.getResourceAsStream("/settings.properties"));

就像我之前说的那样,这确实很有效(从Eclipse中启动应用程序或作为包装的可执行文件或runnable-jar启动。

所以我试图像这样访问我的HTML“手册”:

File manual = new File(getClass().getResource("/manual/help.html").toURI());

jEditorPane.setPage(manual.toURI().toURL());

这不起作用。通过Eclipse启动程序我看到手册但缺少图像。通过jar / exe启动它我得到一个空框架。

那么如何实现这一目标还有什么“诀窍”呢? 我猜一个问题是HTML页面本身,因为它无法访问该jar中的链接图像。 这是一个非常小的HTML文件示例,它不起作用(缺少图像):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html lang="de">
    <head>
        <title>Manual</title>
    </head>
    <body>
        <h1>Example: </h1>
        <p>fubar</p>
        <img style="display: block; text-align: center;" src="../manual/img/Shot01.png" width="666" height="644" border="0" alt="Bildtext">
        <p><a href=\"http://www.google.com/\">blablubb</a></p>
    </body>
</html>

我希望我的问题很明确,有人有想法;)。

编辑: 所有必需的HTML文件和图像都在JAR文件/类路径中。 (只是为了让这个更清楚)

2 个答案:

答案 0 :(得分:7)

File manual = new File(getClass().getResource("/manual/help.html").toURI());

这就是出错的地方。 Java无法从

创建File对象

将其保留为URL并将其用于setPage(..)


关于更普遍的问题。

通过相对引用链接资源(例如CSS或图像)的Jar文件中的HTML将正常工作。

E.G。

此示例从Jar中加载HTML(具有对图像的相对引用)。

import javax.swing.*;
import java.net.URL;

class ShowHtml {

    public static void main(String[] args) {
        final String address =
            "jar:http://pscode.org/jh/hs/object.jar!/popup_contents.html";
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    URL url = new URL(address);
                    JEditorPane jep = new JEditorPane(url);
                    JFrame f = new JFrame("Show HTML in Jar");
                    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    f.add(new JScrollPane(jep));
                    f.pack();
                    f.setSize(400,300);
                    f.setLocationByPlatform(true);
                    f.setVisible(true);
                } catch(Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

截图

JEditorPane displaying Jar'd HTML

HTML

正在加载的HTML。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!--       
 *        Copyright (C) 1997  Sun Microsystems, Inc
 *                    All rights reserved.
 *          Notice of copyright on this source code 
 *          product does not indicate publication. 
 * 
 * RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by 
 * the U.S. Government is subject to restrictions as set forth 
 * in subparagraph (c)(1)(ii) of the Rights in Technical Data
 * and Computer Software Clause at DFARS 252.227-7013 (Oct. 1988) 
 * and FAR 52.227-19 (c) (June 1987).
 *
 *    Sun Microsystems, Inc., 2550 Garcia Avenue,
 *    Mountain View, California 94043.
 *
-->
<HTML>
<HEAD>
<TITLE>
Editing Project Attributes
</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffff">
<IMG SRC="images/popup_icon.gif" width="24" height="24"> <b>Popup Window</b>
<p>
Popup windows appear near the location from which they are
activated.  They are not contained in frames and thus
cannot be resized or moved by the user.  Popups are
dismissed by clicking anywhere in the help viewer.
<p>
Popup windows can be activated by clicking on a text object, 
graphic object, or JComponent button.  All three examples are
included in this demo.
<p>
<A HREF="popup_contents2.html">More...</A>
</body>
</html>

E.G。 2

对于动态创建的HTML,JRE将可能使用类文件的位置作为HTML的假定位置。但是为了消除所有疑问,我们可以在base中指定head元素。

import javax.swing.*;

class HtmlUsingBase {

    public static void main(String[] args) {
        final String htmlContent =
            "<html>" +
            "<head>" +
            "<base href='http://www.gravatar.com/'>" +
            "</head>" +
            "<body>" +
            "<h1>Image path from BASE</h1>" +
            "<img src='avatar/a1ab0af4997654345d7a9" +
            "49877f8037e?s=128&d=identicon&r=PG'" +
            " width='128' height='128'>" +
            "</body>" +
            "</html>";
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JLabel label = new JLabel(htmlContent);
                JOptionPane.showMessageDialog(null, label);
            }
        });
    }
}

截图

enter image description here

答案 1 :(得分:2)

获得URI后,您将其转换为文件,然后返回URI,然后转换为URL。只需将URI转换为URL

,您就可以获得更好的成功