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

2019-01-18 06:35发布

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 webview.

2条回答
淡お忘
2楼-- · 2019-01-18 06:51

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(); }
}
查看更多
走好不送
3楼-- · 2019-01-18 07:04

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);
    }
}
查看更多
登录 后发表回答