关于实际问题("Java FX Stylesheet via String"):新的JavaFX 17 CSS数据URL协议是正确的选择。
但是关于@Ajax关于通过Handler注册URL协议的建议,这里有一个完整的实际示例,展示了如何使用建议的方法注册多个协议。
这段代码是在最古老的JDK之一上编写和测试的:v1.2(1998)。因此,其中的一些部分比现代JDK更冗长,但它也已经在JDK 17和1.8(也称为"8")上进行了测试。
在这个示例中,通过一个实用类注册了两个URL协议。
所以,总共有3个包和5个类。
首先,是实用类(包括一个测试)...
package com.stackoverflow.handler.util;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class HandlerUtil {
private HandlerUtil() {}
public synchronized static String register(final Class clazz) {
final String className = clazz.getName();
final int dotLast = className.lastIndexOf('.');
final int dotLastButOne = className.lastIndexOf('.', dotLast - 1);
System.out.println("Class Name............................: " + className);
System.out.println("dotLast...............................: " + dotLast);
System.out.println("dotLastButOne.........................: " + dotLastButOne);
final String ourSuperPackage;
final String protocolName;
try {
ourSuperPackage = className.substring(0, dotLastButOne);
protocolName = className.substring( dotLastButOne + 1, dotLast);
}
catch (final StringIndexOutOfBoundsException e) {
throw new IllegalArgumentException("Full Classname must contain at least 2 dots. Class=" + className);
}
System.out.println("PROTOCOL_NAME.........................: " + protocolName);
final String handlerProperty = "java.protocol.handler.pkgs";
final char sepBar = '|';
final String handlerPackageList = System.getProperty(handlerProperty, "").trim();
final String sepListSep = sepBar + handlerPackageList + sepBar;
final String sepNewSep = sepBar + ourSuperPackage + sepBar;
if (sepListSep.indexOf(sepNewSep) < 0) {
final String updatedList;
if (handlerPackageList.length() == 0) {
updatedList = ourSuperPackage;
} else {
updatedList = handlerPackageList + sepBar + ourSuperPackage;
}
System.out.println("Updated handlerPackageList............: " + updatedList);
System.setProperty(handlerProperty, updatedList);
}
return protocolName;
}
public static void main(final String[] args) throws MalformedURLException, IOException {
testProtocol(com.stackoverflow.handler.reverse.Handler.PROTOCOL_NAME, "path/reverseme");
testProtocol(com.stackoverflow.handler.dubble .Handler.PROTOCOL_NAME, "path/doubleme");
testProtocol("unregisteredProtocol", "path/unregistered");
}
private static void testProtocol(final String protocol, final String path) throws MalformedURLException, IOException {
final URLConnection urlConnection = new URL(protocol + ':' + path).openConnection();
; urlConnection.connect();
System.out.println("[main] urlConnection..................: " + urlConnection.getClass());
System.out.println("[main] urlInputStream.................: " + new String(readBytes(urlConnection)));
}
private static byte[] readBytes(final URLConnection urlConnection) throws IOException {
final byte[] bytes = new byte[8192];
final int byteCount = urlConnection.getInputStream().read(bytes);
final byte[] bytesCopy = new byte[byteCount];
System.arraycopy(bytes, 0, bytesCopy, 0, byteCount);
return bytesCopy;
}
}
现在,为第一个协议(URLConnection和Handler)创建两个类。
package com.stackoverflow.handler.dubble;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public final class DoubleURLConnection extends URLConnection {
protected DoubleURLConnection(final URL url) {
super(url);
System.out.println("DublURLConnection.new.................: " + url);
}
public void connect() throws IOException {
System.out.println("DublURLConnection.connect.............:");
}
public InputStream getInputStream() throws IOException {
System.out.println("DublURLConnection.getInputStream......:");
final String urlString = this.getURL().toString();
return new ByteArrayInputStream(("DUBL_" + urlString + '_' + urlString + "_DUBL").getBytes());
}
}
处理程序...
package com.stackoverflow.handler.dubble;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import com.stackoverflow.handler.util.HandlerUtil;
public final class Handler extends URLStreamHandler {
public static void register() {
}
public static final String PROTOCOL_NAME = HandlerUtil.register(DoubleURLConnection.class);
protected URLConnection openConnection(final URL url) throws IOException {
System.out.println("DUBL Handler.openConnection.(URL).....: " + url);
System.out.println("DUBL Handler.openConnection.(Protocol): " + url.getProtocol());
return new DoubleURLConnection(url);
}
}
最后,为第二个协议(URLConnection和Handler)创建了两个类。
package com.stackoverflow.handler.reverse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public final class ReverseURLConnection extends URLConnection {
protected ReverseURLConnection(final URL url) {
super(url);
System.out.println("RvrsURLConnection.new.................: " + url);
}
public void connect() throws IOException {
System.out.println("RvrsURLConnection.connect.............:");
}
public InputStream getInputStream() throws IOException {
System.out.println("RvrsURLConnection.getInputStream......:");
final StringBuffer sbd = new StringBuffer();
final char[] urlChars = this.getURL().toString().toCharArray();
for (int i=0; i < urlChars.length ; i++) {
sbd.insert(0, urlChars[i]);
}
return new ByteArrayInputStream(sbd.toString().getBytes());
}
}
处理程序...
package com.stackoverflow.handler.reverse;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import com.stackoverflow.handler.util.HandlerUtil;
public final class Handler extends URLStreamHandler {
public static void register() {
}
public static final String PROTOCOL_NAME = HandlerUtil.register(ReverseURLConnection.class);
protected URLConnection openConnection(final URL url) throws IOException {
System.out.println("Handler.openConnection.(URL)..........: " + url);
System.out.println("Handler.openConnection.(Protocol).....: " + url.getProtocol());
return new ReverseURLConnection(url);
}
}