使WebView忽略JavaFX中的场景CSS

时间:2017-06-06 11:43:06

标签: java javafx javafx-8

当我使用javafx.scene.web.WebView加载网站/ html时,该网站似乎受到我的场景自定义样式的影响。一个证明问题的最小例子。

Main.java

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        VBox root = new VBox();

        primaryStage.setScene(new Scene(root, 900, 900));

        String css = Main.class.getResource("/test.css").toExternalForm();
        primaryStage.getScene().getStylesheets().add(css);

        WebView webView = new WebView();

        root.getChildren().add(webView);

        webView.getEngine().load("http://google.pl");

        primaryStage.show();
    }


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

test.css

.text-area,
.text-field {
  -fx-background-color: red;
}

这导致Image representing the result of above's code

最终我希望像webview.getEngine().dontInheritStyles()这样的方法当然没有,我找不到任何方法。试过:

webView.getStylesheets().clear();
webView.setStyle(null);
webView.getStyleClass().clear();

他们都没有奏效。我认为可以使这项工作的一种方式(尚未尝试过)将在不使用相同场景的子窗口中打开webview,但我希望将webview嵌入到我现有的应用程序视图中所以这个选项将是我最后的选择,我宁愿避免它。

2 个答案:

答案 0 :(得分:2)

您可以使用某种黑客攻击,例如JavaFX和Swing的组合。

你有两个班级:

  • JFXPanel - 允许您将JavaFX控件嵌入Swing
  • SwingNode - 允许您将Swing控件嵌入JavaFX

您可以在包装类中结合使用JFXPanel和SwingNode类:

public class Styleless<T extends Parent> extends StackPane {
    private T root;

    public Styleless(T root) {
        this.root = root;

        JFXPanel jfxPanel = new JFXPanel();
        jfxPanel.setScene(new Scene(root));

        SwingNode swingNode = new SwingNode();
        swingNode.setContent(jfxPanel);

        getChildren().add(swingNode);
    }

    public T getRoot() {
        return root;
    }
}

你可以像这样使用它:

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        VBox root = new VBox();
        primaryStage.setScene(new Scene(root, 900, 900));

        String css = Main.class.getResource("/test.css").toExternalForm();
        primaryStage.getScene().getStylesheets().add(css);

        WebView webView = new WebView();
        webView.getEngine().load("http://google.pl");

        Styleless<WebView> webViewStyleless = new Styleless<>(webView);

        root.getChildren().add(webViewStyleless);
        VBox.setVgrow(webViewStyleless, Priority.ALWAYS);

        primaryStage.show();
    }

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

答案 1 :(得分:0)

您还可以在CSS中使用样式类来管理哪些元素应用了样式。定义一个&#39; myapplication&#39;你的css中的class,并将该类添加到你的根节点。

test.css

/* any text fields inside a container with the myapplication style class */
.myapplication > .text-field{
    -fx-background-color: red;
}

/* any text areas inside a container with the myapplication style class */
.myapplication > .text-area{
    -fx-background-color: red;
}

Main.java

...
root.getStyleClass().add("myapplication");
TextField txtField = new TextField("Application text field");
root.getChildren().addAll(webView, txtField);
...

使用&#39;&gt;&#39; css选择器(https://www.w3schools.com/cssref/css_selectors.asp)这种方式将样式应用于其父级具有样式类&#39; myapplication&#39;的文本字段。创建WebView时,它具有样式类&#39; web-view&#39; (https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html#webview

虽然没有真正的方法来阻止继承样式值,但样式类不会添加到子项中。