Applying CSS file to JavaFX WebView

前端 未结 2 1588
南旧
南旧 2020-12-10 03:53

I am trying to apply a CSS file to a JavaFX WebView object. From what I\'ve read, this should do the trick, but evidently I\'m missing something because the WebView display

相关标签:
2条回答
  • 2020-12-10 04:11

    James_D already explained in his answer how to convert "JavaFx CSS" to "HTML CSS", but it may be more convenient to use WebEngine.setUserStylesheetLocation to set a stylesheet that contains the CSS:

    webEngine.setUserStyleSheetLocation(getClass().getResource("style.css").toString());
    

    style.css contains the css code:

    body {
        background-color: #00ff80; 
        font-family: Arial, Helvetica, sans-serif;
    }
    
    0 讨论(0)
  • 2020-12-10 04:11

    Your code applies CSS to the JavaFX WebView node; you are trying to apply CSS to the HTML document displayed inside the WebView. Since the web view has no JavaFX nodes with any text, -fx-font-family has no effect, and the background of the HTML page will obscure the background of the WebView, so -fx-background-color will not be visible.

    In order to do what you want, you need to manipulate the DOM of the loaded document and apply (standard, HTML-applicable) CSS to it. This would look something like:

    import javafx.application.Application;
    import javafx.concurrent.Worker.State;
    import javafx.scene.Scene;
    import javafx.scene.layout.VBox;
    import javafx.scene.web.WebEngine;
    import javafx.scene.web.WebView;
    import javafx.stage.Stage;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Text;
    
    
    public class WebViewCssPlay extends Application {
    
        private static final String CSS = 
                  "body {"
                + "    background-color: #00ff80; "
                + "    font-family: Arial, Helvetica, san-serif;"
                + "}";
    
        @Override
        public void start(Stage stage) {
            stage.setTitle("CSS Styling Test");
            stage.setWidth(300);
            stage.setHeight(200);
    
            WebView browser = new WebView();
            WebEngine webEngine = browser.getEngine();
    
            webEngine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
                if (newState == State.SUCCEEDED) {
                    Document doc = webEngine.getDocument() ;
                    Element styleNode = doc.createElement("style");
                    Text styleContent = doc.createTextNode(CSS);
                    styleNode.appendChild(styleContent);
                    doc.getDocumentElement().getElementsByTagName("head").item(0).appendChild(styleNode);
    
                    System.out.println(webEngine.executeScript("document.documentElement.innerHTML"));
                }
            });
            webEngine.loadContent("<html><body><h1>Hello!</h1>This is a <b>test</b></body></html>");
    
            VBox root = new VBox(); 
            root.getChildren().addAll(browser);
            root.getStyleClass().add("browser");
            Scene scene = new Scene(root);
            stage.setScene(scene);
    //        scene.getStylesheets().add("/net/snortum/play/web_view.css");
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    Edit: also see @fabian's answer, which is much cleaner and preferable in the vast majority of use cases.

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