Is it possible to wrap a whole Stylesheet in a string and apply it to a certain node?
Usage case would be to add specific (non changeble) behavior for PseudoClass.
I know I can use pane.getStylesheets().add(getClass().getResource("mycss.css").toExternalForm());
, but I would like to know if there's some way to embrd it direcly in source; something along the lines:
pane.getStylesheets().add(
".button:ok { -fx-background-color: green; }\n"+
".button:ko { -fx-background-color: red; }");
I found a way of doing this by defining a new URL connection:
private String css;
public void initialize() {
...
// to be done only once.
URL.setURLStreamHandlerFactory(new StringURLStreamHandlerFactory());
...
}
private void updateCss(Node node) {
// can be done multiple times.
css = createCSS();
node.getStylesheets().setAll("internal:"+System.nanoTime()+"stylesheet.css");
}
private class StringURLConnection extends URLConnection {
public StringURLConnection(URL url){
super(url);
}
@Override public void connect() throws IOException {}
@Override public InputStream getInputStream() throws IOException {
return new StringBufferInputStream(css);
}
}
private class StringURLStreamHandlerFactory implements URLStreamHandlerFactory {
URLStreamHandler streamHandler = new URLStreamHandler(){
@Override protected URLConnection openConnection(URL url) throws IOException {
if (url.toString().toLowerCase().endsWith(".css")) {
return new StringURLConnection(url);
}
throw new FileNotFoundException();
}
};
@Override public URLStreamHandler createURLStreamHandler(String protocol) {
if ("internal".equals(protocol)) {
return streamHandler;
}
return null;
}
}
Obviously protocol "internal" can be any (non clashing) well-formed string and (in this simple example) filepath is compeltely ignored.
I use this to set the global .css, so I do not need to remember multiple strings. It seems the Stream is opened just once, but I do not know if this holds true in all cases.
Feel free to complicate the code as needed ;)
Credit for this method goes to Jasper Potts (see this example)