JEditorPane with inline image

前端 未结 1 664
醉梦人生
醉梦人生 2020-11-30 11:40

I\'m attempting to display an inline image in a Java JEditorPane. The code below uses HTML content that properly displays the image in Firefox, but not in the JEditorPane.

相关标签:
1条回答
  • 2020-11-30 12:07

    You need to add a protocol handler for "data:" so an URL/URLConnection can be opened for it. Alternatively you could create some protocol handler "resource:" for class path resources.

    You need a package data with a class Handler (fixed name convention!). This will be the factory class for "data:" return an URLConnection. We will create DataConnection for that.

    Installing a protocol handler can be done via System.setProperty. Here I provided Handler.install(); to do that in a generic way.

    package test1.data;
    
    import java.io.IOException;
    import java.net.URL;
    import java.net.URLConnection;
    import java.net.URLStreamHandler;
    
    public class Handler extends URLStreamHandler {
    
        @Override
        protected URLConnection openConnection(URL u) throws IOException {
            return new DataConnection(u);
        }
    
        public static void install() {
            String pkgName = Handler.class.getPackage().getName();
            String pkg = pkgName.substring(0, pkgName.lastIndexOf('.'));
    
            String protocolHandlers = System.getProperty("java.protocol.handler.pkgs", "");
            if (!protocolHandlers.contains(pkg)) {
                if (!protocolHandlers.isEmpty()) {
                    protocolHandlers += "|";
                }
                protocolHandlers += pkg;
                System.setProperty("java.protocol.handler.pkgs", protocolHandlers);
            }
        }
    }
    

    The URLConnection gives an InputStream to the bytes:

    package test1.data;
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URL;
    import java.net.URLConnection;
    import javax.xml.bind.DatatypeConverter;
    
    public class DataConnection extends URLConnection {
    
        public DataConnection(URL u) {
            super(u);
        }
    
        @Override
        public void connect() throws IOException {
            connected = true;
        }
    
        @Override
        public InputStream getInputStream() throws IOException {
            String data = url.toString();
            data = data.replaceFirst("^.*;base64,", "");
            System.out.println("Data: " + data);
            byte[] bytes = DatatypeConverter.parseBase64Binary(data);
            return new ByteArrayInputStream(bytes);
        }
    
    }
    

    The clever thing here is to use Base64 decoding of DatatypeConverter in standard Java SE.


    P.S.

    Nowadays one would use Base64.getEncoder().encode(...).

    0 讨论(0)
提交回复
热议问题