Search code examples
javafx-8javafx-webenginejavafx-9

JavaFX WebView usage, transparent background, jdk8 vs jdk9


I have some code snipped out of a much bigger app, which renders some white text on a black background in a JavaFX WebView. The background colour of the page is set to transparent, using some code from Transparent background in the WebView in JavaFX

import java.lang.reflect.Field;
import org.w3c.dom.Document;
import com.sun.webkit.WebPage;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class TestWebView extends Application {

  public void start(Stage stage) throws Exception {
    StackPane stackpane = new StackPane();
    Scene scene = new Scene(stackpane, stage.getWidth(), stage.getHeight(), Color.BLACK);
    stage.setScene(scene);
    scene.setFill(Color.BLACK);
    stackpane.setStyle("-fx-background-color: BLACK");
    WebView webview = new WebView();
    stackpane.getChildren().add(webview);
    WebEngine webengine = webview.getEngine();
    webengine.documentProperty().addListener(new WebDocumentListener(webengine));
    webengine.loadContent("<p style='color:white'>Hello World</p>");
    stage.show();
  }

  public static void main(String[] args) {
    launch(args);
  }

  protected class WebDocumentListener implements ChangeListener<Document> {
    private final WebEngine wdl_webEngine;

    public WebDocumentListener(WebEngine webEngine) {
      wdl_webEngine = webEngine;
    }

    @Override
    public void changed(ObservableValue<? extends Document> arg0, Document arg1, Document arg2) {
      try {
        Field f = wdl_webEngine.getClass().getDeclaredField("page");
        f.setAccessible(true);
        com.sun.webkit.WebPage page = (WebPage) f.get(wdl_webEngine);
        page.setBackgroundColor((new java.awt.Color(0, 0, 0, 0)).getRGB());
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
}

Testing on MacOS 10.11.6, with Oracle's JDK:

With JDK 1.8.0_152, this code works nicely - I get white text on black. (And the transparency works too when I layer things underneath it in the stackpane)

With JDK 9 (9+181), com.sun.webkit.WebPage is no longer accessible, so I have to compile and run it with --add-exports javafx.web/com.sun.webkit=ALL-UNNAMED - but having done that, I get black text on a black screen. I can tell the text is there by selecting the text and dragging it, which makes the text appear white while being dragged.

Ideally, I'd like to keep a single codebase that works for both JDK 8 and 9. (Java's usually been good to me with backward compatibility). Or as a second best, how do I get the white text I'm expecting in JDK 9?

Can anyone point me in the right direction? Many thanks in advance.


Solution

  • I had the same issue, I solved it by going further in the reflective process :

    Field f = webEngine.getClass().getDeclaredField("page");
    f.setAccessible(true);
    Object page = f.get(webEngine);
    Method m = page.getClass().getMethod("setBackgroundColor", int.class);
    m.setAccessible(true);
    m.invoke(page, (new java.awt.Color(0, 0, 0, 0)).getRGB());