JEditorPane with inline image

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(...).

Leave a Comment