Java Swing 组件如何显示嵌套了svg的html?

我用的是JavaSwing的JEditorPane组件,但是它只能显示html文件,如果嵌套了svg文件,那么svg文件那块就会显示问号,不能显示出来。
如果是显示纯svg文件的话我也有办法,现在的问题就是如何在swing组件中显示嵌套了svg文件的html文件。
能有什么办法解决这个问题吗? 谢谢!

家里网络访问不了sourceforge的网站……。不然很想尝试在swing中嵌入浏览器哪个djproject,看看是否支持svg。
我用JEditorPane时,使用底层的一些api,可以访问内嵌svg的html文件了。
思想如下:
使用HttpConnection访问url(JEditorPane底层也是这样访问url的)获取响应内容,然后提取embed、object中包含svg文件的标签,做特殊处理,处理步骤如下:
1.先通过svg的地址获取的资源路径,然后使用batik处理svg,转换为jpg格式的图片
2.将该jpg图片保存到一台图片服务器中(tomcat也可),并返回jpg路径
3.将原html内容中的embed、object中包含svg文件的标签内容替换为img标签,并把jpg路径放到src属性上
4.把新的html响应内容使用JEditorPane底层的解析类处理

代码如下(写的比较粗糙,主要是使用HTMLDocument、Parser 、ParserCallback这几个底层的类):
[code="java"]
import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;

import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.text.html.HTMLEditorKit.Parser;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.html.HTMLDocument;

import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public class TestJEditorPane extends JFrame {

/**
 * 
 */
private static final long serialVersionUID = 7429079353774653739L;

/**
 * @param args
 */
public static void main(String[] args) throws Exception {
    testJEditorPane();
}

public static void testJEditorPane() throws Exception {
    JFrame frame = new JFrame();
    frame.setTitle("Test");

    URL url = new URL("http://localhost:8889/springwork/user/login.do");

    Reader HTMLReader = new InputStreamReader(url.openConnection()
            .getInputStream());
    BufferedReader br = new BufferedReader(HTMLReader);
    String line = "";
    String jpg = "";
    StringBuffer sb = new StringBuffer();
    while((line = br.readLine()) != null) {
        if(line.indexOf("embed") != -1) {
            String contextPath = url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + "/" + getAttribute(line, "src");
            System.out.println(contextPath);
            jpg = getImagePath(contextPath);
            line = "<img src=\"" + jpg + "\"/>";
        } 
        sb.append(line);
        sb.append("\n");
    }
    System.out.println(sb.toString());
    JEditorPane jp = new JEditorPane();
    try {
        jp.setSize(400, 300);
        jp.setPage(url);
    } catch (IOException e) {
        e.printStackTrace();
    }

    HTMLDocument hdoc = (HTMLDocument) jp.getDocument();
    Parser p = hdoc.getParser();

    ParserCallback receiver = hdoc.getReader(0);
    Boolean ignoreCharset = (Boolean)jp.getDocument().getProperty("IgnoreCharsetDirective");
    p.parse(new StringReader(sb.toString()), receiver, (ignoreCharset == null) ? false : ignoreCharset.booleanValue());
    receiver.flush();

    frame.getContentPane().add(jp, BorderLayout.CENTER);

    frame.setSize(400, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.pack();
    frame.repaint();
    frame.setVisible(true);
}

public static String getImagePath(String svgUrl) {
    try {
        JPEGTranscoder t = new JPEGTranscoder();
        t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(.8));
        //String svgURI = new File("C:/Users/Administrator/Desktop/svg/asf-logo.svg").toURL().toString();
        String svgURI = "http://localhost:8889//springwork/styles/svgs/a_1.svg";
        TranscoderInput input = new TranscoderInput(svgURI);

        String outPath = "D:/work/eclipse/eclipse4.2/code/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/springwork/styles/svgs/a_1.jpg";
        FileOutputStream ostream = new FileOutputStream(outPath);
        TranscoderOutput output = new TranscoderOutput(ostream);
        t.transcode(input, output);
        ostream.flush();
        ostream.close();

        outPath = "http://localhost:8888/springwork/styles/svgs/a_1.jpg";//相对路径,依据具体的图片服务器地址
        return outPath;
    } catch (Exception e) {
        e.printStackTrace();
        return "";
    }
}

public static Document parseText(String str) throws Exception
{
    Document document = null;
    try
    {
        document = DocumentHelper.parseText(str);
    }
    catch(DocumentException de)
    {
        throw de;
    }
    catch(Exception e)
    {
        throw e;
    }
    return document;
}

public static String getAttribute(String str, String name) {
    try {
        Document doc = parseText(str);
        Element ele = doc.getRootElement();
        return ele.attributeValue("src");
    } catch(Exception e) {
        return "";
    }
}

}
[/code]

不清楚iframe 里面可以用不、你测试下。
< src ="rect.svg" width ="300" height ="100" >
</ iframe >

本身swing整合html就不稳定(比如说里面各种复杂的标签等等)
再加上个svg,表示压力很大。

如果真要做,我觉得可以重新实现JEditorPane里面的若干方法。JEditorPane肯定也是解析html来显示的,那么你把这部分代码加上svg解析功能,再在pane上描绘出来,应该就能实现了

stackoverflow 有几篇 不知道你看过了吗

[url]http://stackoverflow.com/questions/9353744/jeditorpane-external-resources-arent-resolved[/url]
[url]http://stackoverflow.com/questions/9361779/jeditorpane-html-layout-broken[/url]
[url]http://stackoverflow.com/questions/16073740/cant-show-html-svg[/url]

你应该在Swing中嵌浏览器而不是JEditorPane,一般浏览器都是对svg支持得比较好的。
Swing嵌浏览器你可以参考[url]http://djproject.sourceforge.net/ns/[/url]。

虽然已经几年了,但是我这里有更好的答案:
https://github.com/kirill-grouchnikov/radiance

这是大佬写的一个框架,其中有一个功能就是svg文件转java文件