WebView JavaScript 回调处理程序示例
下面是一些基于 JavaScript 触发器命令显示 JavaFX 对话框的示例代码。示例代码适用于 JavaScript 确认处理程序,但警报处理程序的代码功能类似。
在示例屏幕截图中,左侧的黄色栏将显示一个 JavaFX 标签,该标签基于由覆盖屏幕其余部分的 WebView 调用的 JavaScript 函数触发的确认对话框的结果。
确认对话框在 JavaFX 中呈现在 WebView 的顶部,防止在显示对话框时与 WebView 交互。确认对话框的样式只是一个示例,它可以使用 css 以任何您希望的方式设置样式,并且布局也可以在代码中更改(或者如果您愿意,也可以在 FXML 标记中定义对话框布局)。
![webview确认](https://i.stack.imgur.com/BGoau.png)
WebViewConfirm.java
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.*;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.effect.BoxBlur;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;
import javafx.stage.*;
import javafx.util.Callback;
/**
* Demonstrates a modal WebView confirm box in JavaFX.
* Dialog is rendered upon a blurred background.
* Dialog is translucent.
* Requires JavaFX 2.2
* To test, run the program, then click the "Try it" button in the Result textarea.
*/
public class WebViewConfirm extends Application {
public static void main(String[] args) { launch(args); }
@Override public void start(final Stage primaryStage) {
// initialize the stage
primaryStage.setTitle("Modal Confirm Example");
final WebView webView = new WebView();
webView.getEngine().load("http://www.w3schools.com/js/tryit.asp?filename=tryjs_confirm");
// layout the stage - a vbox to show confirmation results and a webview to generate confirmations.
final VBox confirmationResults = new VBox();
confirmationResults.getStyleClass().add("confirmation-results");
confirmationResults.setMinWidth(150);
HBox layout = new HBox();
layout.getChildren().addAll(confirmationResults, webView);
primaryStage.setScene(new Scene(layout));
primaryStage.show();
primaryStage.getScene().getStylesheets().add(getClass().getResource("modal-dialog.css").toExternalForm());
// show the confirmation dialog each time a new page is loaded and
// record the confirmation result.
webView.getEngine().setConfirmHandler(new Callback<String, Boolean>() {
@Override public Boolean call(String msg) {
Boolean confirmed = confirm(primaryStage, msg);
confirmationResults.getChildren().add(new Label("Confirmed? " + confirmed));
return confirmed;
}
});
}
private Boolean confirm(final Stage parent, String msg) {
final BooleanProperty confirmationResult = new SimpleBooleanProperty();
// initialize the confirmation dialog
final Stage dialog = new Stage(StageStyle.TRANSPARENT);
dialog.initOwner(parent);
dialog.initModality(Modality.WINDOW_MODAL);
dialog.setScene(
new Scene(
HBoxBuilder.create().styleClass("modal-dialog").children(
LabelBuilder.create().text(msg).build(),
ButtonBuilder.create().text("OK").defaultButton(true).onAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent actionEvent) {
// take action and close the dialog.
confirmationResult.set(true);
parent.getScene().getRoot().setEffect(null);
dialog.close();
}
}).build(),
ButtonBuilder.create().text("Cancel").cancelButton(true).onAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent actionEvent) {
// abort action and close the dialog.
confirmationResult.set(false);
parent.getScene().getRoot().setEffect(null);
dialog.close();
}
}).build()
).build()
, Color.TRANSPARENT
)
);
// allow the dialog to be dragged around.
final Node root = dialog.getScene().getRoot();
final Delta dragDelta = new Delta();
root.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
dragDelta.x = dialog.getX() - mouseEvent.getScreenX();
dragDelta.y = dialog.getY() - mouseEvent.getScreenY();
}
});
root.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
dialog.setX(mouseEvent.getScreenX() + dragDelta.x);
dialog.setY(mouseEvent.getScreenY() + dragDelta.y);
}
});
// style and show the dialog.
dialog.getScene().getStylesheets().add(getClass().getResource("modal-dialog.css").toExternalForm());
parent.getScene().getRoot().setEffect(new BoxBlur());
dialog.showAndWait();
return confirmationResult.get();
}
// records relative x and y co-ordinates.
class Delta { double x, y; }
}
模态对话框.css
/**
* modal-dialog.css
* place in same directory as WebViewConfirm.java
* ensure your build system copies the file to your build output directory
*/
.root {
-fx-glass-color: rgba(95, 158, 160, 0.9);
}
.modal-dialog {
-fx-padding: 20;
-fx-spacing: 10;
-fx-alignment: center;
-fx-font-size: 20;
-fx-background-color: linear-gradient(to bottom, derive(-fx-glass-color, 20%), -fx-glass-color);
-fx-border-color: derive(-fx-glass-color, -20%);
-fx-border-width: 5;
-fx-background-insets: 12;
-fx-border-insets: 10;
-fx-border-radius: 6;
-fx-background-radius: 6;
}
.modal-dialog:pressed {
-fx-cursor: move;
}
.modal-dialog .button:pressed {
-fx-cursor: default;
}
.confirmation-results {
-fx-background-color: cornsilk;
-fx-padding: 5;
}
您的问题的可能答案
你的问题对我来说不是很清楚,但我认为如果你弹出一个ControlsFX对话框,你会实现你想要的。您可以使用标准对话框(其功能类似于 Internet Explorer 的 JavaScript 警报对话框)或轻量级对话框(其功能类似于 Firefox 的 JavaScript 警报对话框) - 请参阅ControlsFX 功能页面以获取更多信息。
ControlsFX 是基于 Java 8 的,但对于 JavaFX 2.2,StackOverflow 上有许多关于在 JavaFX 中显示对话框的主题(例如:How to create and show common dialog (Error, Warning, Confirmation) in JavaFX 2.0?)。上面的示例代码是 JavaFX 2.2 中对话框使用的示例
对您问题中提出的其他观点的评论
如果 JavaFX 的 webview 本身可以运行 javascript,除了它与 java 代码的通信
是的,WebView 可以处理 JavaScript。
例如,当窗口加载时,我是否可以在 webview 中运行 javascript alert 语句,并像在普通浏览器中一样在 webview 中实际获得警报。
是的,如果您为 WebView 设置了警报处理程序,使其像“普通浏览器”一样运行,则会在接收 JavaScript 警报命令时弹出一个对话框。请注意,“普通浏览器”不会基于 JavaScript 警报功能修改网页文档对象模型,而是弹出一个原生对话框 - 该对话框实际上并不是网页的一部分。
我实际上希望 javascript 事件像在普通浏览器中一样发生在 webview 窗口本身中。
“普通”浏览器根据其 UI 模型以不同方式处理警报。例如,在 Firefox 中,警报对话框将出现在当前浏览器选项卡窗口中,而在 Internet Explorer 中,警报对话框将出现在 Internet Explorer 窗口上方。JavaFX 警报处理程序足够灵活,您可以随心所欲地处理警报。