How to render a internal image on a swing component using html?

后端 未结 4 1129
故里飘歌
故里飘歌 2021-01-19 13:05

I have the following code:

public static void main(String[] args) {
    JFrame frm = new JFrame();
    JEditorPane pane = new JEditorPane(\"text/html\", \"&l         


        
4条回答
  •  离开以前
    2021-01-19 13:28

    I had to rewrite one of the Java classes and extend another, but got the BASE64 image working under HTML on the JEditorPane. I'll post my solution in case someone needs it in the future...

    First, create a Special HTMLEditorKit that will use the rewritten ImageView class for the HTML.Tag.IMG

    class BASE64HTMLEditorKit extends HTMLEditorKit {
    
        private static HTMLFactory factory = null;
    
        @Override
        public ViewFactory getViewFactory() {
            if (factory == null) {
                factory = new HTMLFactory() {
    
                    @Override
                    public View create(Element elem) {
                        AttributeSet attrs = elem.getAttributes();
                        Object elementName = attrs.getAttribute(AbstractDocument.ElementNameAttribute);
                        Object o = (elementName != null) ? null : attrs.getAttribute(StyleConstants.NameAttribute);
                        if (o instanceof HTML.Tag) {
                            HTML.Tag kind = (HTML.Tag) o;
                            if (kind == HTML.Tag.IMG) {
                                // HERE is the call to the special class...
                                return new BASE64ImageView(elem);
                            }
                        }
                        return super.create(elem);
                    }
                };
            }
            return factory;
        }
    
    }
    

    With that done, implement the special class, based on the openjdk code. Download the source code here, and open the file openjdk/jdk/src/share/classes/javax/swing/text/html/ImageView.java. Because it have almost everything private, I found it easier to copy it entirely and then change the method needed to load BASE64 Images:

    private void loadImage() {
        String b64 = getBASE64Image();
        BufferedImage newImage = null;
        try (ByteArrayInputStream bais = new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(b64))) {
            newImage = ImageIO.read(bais);
        } catch (IOException ex) {
            ...
        }
        image = newImage;
    }
    
    private String getBASE64Image() {
        String src = (String) getElement().getAttributes().getAttribute(HTML.Attribute.SRC);
        if (src == null) {
            return null;
        }
        return src.replaceFirst("data:image/png;base64,", "");
    }
    

    The getBASE64Image method just cuts the non BASE64 part of the attribute. The loadImage method is the one that has to be changed, and if it where public, would have helped cut a lot of code from the solution...

    If someone has a better and preferably smaller (mine have 1000 lines of code), please share it...

提交回复
热议问题