How to make an overlay on top of JavaFX 2 webview?

后端 未结 2 448
广开言路
广开言路 2020-12-09 22:27

Is it possible to to overlay any JavaFx2 widgets or canvas on top of a JavaFX 2 webview?

I want to generate a transparent heatmap by means of JavaFX 2 on top of a w

相关标签:
2条回答
  • 2020-12-09 23:15

    Do you mean something like this:

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.Pane;
    import javafx.scene.layout.StackPane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Rectangle;
    import javafx.scene.shape.RectangleBuilder;
    import javafx.scene.text.Font;
    import javafx.scene.text.FontWeight;
    import javafx.scene.text.Text;
    import javafx.scene.text.TextBuilder;
    import javafx.scene.web.WebView;
    import javafx.stage.Stage;
    
    public class Demo extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            WebView webView = new WebView();
            webView.getEngine().load("http://www.google.com");
            StackPane root = new StackPane();
            root.getChildren().addAll(webView, getOverlay());
            primaryStage.setScene(new Scene(root, 300, 250));
            primaryStage.show();
        }
    
         private Pane getOverlay() {
            StackPane p = new StackPane();
            Rectangle r = RectangleBuilder.create()
                    .height(100).width(100)
                    .arcHeight(40).arcWidth(40)
                    .stroke(Color.RED)
                    .fill(Color.web("red", 0.1))
                    .build();
    
            Text txt=TextBuilder.create().text("Overlay")
                    .font(Font.font("Arial", FontWeight.BOLD, 18))
                    .fill(Color.BLUE)
                    .build();
             p.getChildren().addAll(r, txt);
             return p;
        }
    
         public static void main(String[] args) {
            launch(args);
        }
    }
    
    0 讨论(0)
  • 2020-12-09 23:18

    Adding overlay is very easy: just put webview and any pane to StackPane.

    Another story is to synchronize overlay and webview data. To achieve that you need to ask webview for object coordinates through javascript. Here is an example which finds stackoverflow question area and marks it on overlay:

    webView overlay

    public class WebOverlay extends Application {

        @Override
        public void start(Stage stage) {
            StackPane root = new StackPane();
            WebView webView = new WebView();
    
            final WebEngine webEngine = webView.getEngine();
            Canvas overlay = new Canvas(600,600);
            overlay.setOpacity(0.5);
            final GraphicsContext gc = overlay.getGraphicsContext2D();
            gc.setFill(Color.RED);
    
            root.getChildren().addAll(webView, overlay);
            stage.setScene(new Scene(root, 600, 600));
    
            webEngine.getLoadWorker().workDoneProperty().addListener((observable, oldValue, newValue) -> {
                if (newValue.intValue() == 100) {
                    // find coordinates by javascript call
                    JSObject bounds = (JSObject)webEngine.executeScript("document.getElementsByClassName('question-hyperlink')[0].getBoundingClientRect()");
    
                    Number right = (Number)bounds.getMember("right");
                    Number top = (Number)bounds.getMember("top");
                    Number bottom = (Number)bounds.getMember("bottom");
                    Number left = (Number)bounds.getMember("left");
    
                    // paint on overlaing canvas
                    gc.rect(left.doubleValue(), top.doubleValue(), right.doubleValue(), bottom.doubleValue());
                    gc.fill();
                }
            });
            webEngine.load("http://stackoverflow.com/questions/10894903/how-to-make-an-overlay-on-top-of-javafx-2-webview");
    
            stage.show();
        }
    
        public static void main(String[] args) { launch(); }
    }
    
    0 讨论(0)
提交回复
热议问题