JavaFX Web View 中的 Javascript

标签 java javascript webview javafx

我是 Java 和 JavaFX 的新手,我只是想知道 JavaFX 的 webview 除了与 java 代码的通信之外是否可以本身运行 javascript。例如,我可以在加载窗口时在 webview 中运行 javascript 警报语句,并像在普通浏览器中那样在 webview 中实际获得警报吗?我知道我可以通过以下方式用我的 java 代码捕获此警报事件

webEngine.setOnAlert

但我实际上希望 javascript 事件像在普通浏览器中一样在 webview 窗口中发生。

我问这个简单问题的原因是因为我正在使用带有文本区域的 Web View ,我想在其中启用拼写检查。我有一个 javascript 拼写检查器,可以在普通浏览器中完美运行,当我输入错误时会出现红色下划线,但我也想让它在 JavaFX webview 中运行。

我很感谢能得到的任何帮助!

最佳答案

WebView JavaScript 回调处理程序示例

这是一些 sample code用于显示基于 JavaScript 触发器命令的 JavaFX 对话框。示例代码用于 JavaScript 确认处理程序,但警报处理程序的代码功能类似。

在示例屏幕截图中,左侧的黄色条将根据确认对话框的结果显示 JavaFX 标签,确认对话框由覆盖屏幕其余部分的 WebView 调用的 JavaScript 函数触发。

确认对话框在 JavaFX 中呈现在 WebView 的顶部,防止在显示对话框时与 WebView 交互。确认对话框的样式只是一个示例,您可以使用 css 以任何方式设置样式,并且布局也可以在代码中更改(或者如果您愿意,可以在 FXML 标记中定义对话框布局)。

webviewconfirm

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; }
}

modal-dialog.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 features page了解更多信息。

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 中对话框的使用示例

对您问题中提出的其他要点的评论

if the webview of JavaFX can run javascript in itself apart from the communcation it has with the java code

是的 WebView 可以处理 JavaScript。

Can I for example run a javascript alert statement in the webview when the window loads and actually get an alert in the webview as I would in a normal browser.

是的,如果您已经为您的 WebView 设置了一个警报处理程序,以便它像“普通浏览器”一样运行,在接收到 JavaScript 警报命令时弹出一个对话框。请注意,“普通浏览器”不会修改基于 JavaScript 警报功能的网页文档对象模型,而是会弹出一个 native 对话框 - 该对话框实际上并不是网页的一部分。

I actually want javascript events to happen in the webview window itself as they would in a normal browser.

“普通”浏览器根据其 UI 模型以不同方式处理警报。例如,在 Firefox 中,警告对话框将出现在当前浏览器选项卡窗口中,而在 Internet Explorer 中,警告对话框将出现在 Internet Explorer 窗口上方。 JavaFX 警报处理程序非常灵活,您几乎可以随心所欲地处理警报。

关于JavaFX Web View 中的 Javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18817269/

相关文章:

java - 在 Java 中从字符串中获取 Double

java - 关于 Java 文件加密性能的建议

java - java中如何加载字体?

ios - Xamarin Forms webview 根本无法在 IOS 上运行

ios - 如何使用 UiWebView 和 Objective-C 创建持久缓存?

java - Bson 过滤 MongoDB

javascript - Chrome 自动错放结束标签

php - SWFUpload 是否可以将多个文件上传到单个 php 脚本执行

javascript - 如何触发键盘输入事件以在文本区域的下一行添加缩进

android - 被阻止 :csp in Android webView