【问题标题】:Make WebView ignore scene CSS in JavaFX使 WebView 在 JavaFX 中忽略场景 CSS
【发布时间】:2017-06-06 11:43:05
【问题描述】:

当我使用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;
}

这导致

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

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

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

【问题讨论】:

    标签: java javafx javafx-8


    【解决方案1】:

    您可以使用某种 hack,例如 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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      您还可以在 CSS 中使用样式类来管理将样式应用到哪些元素。在您的 CSS 中定义一个“myapplication”类,并将该类添加到您的根节点。

      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);
      ...
      

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

      虽然没有真正的方法来防止 style 值 被继承,但 style 类 不会添加到子级中。

      【讨论】:

        猜你喜欢
        • 2015-10-06
        • 2020-07-25
        • 2014-04-05
        • 1970-01-01
        • 2020-03-23
        • 1970-01-01
        • 1970-01-01
        • 2016-04-13
        • 1970-01-01
        相关资源
        最近更新 更多