8

我是 Java 和 JavaFX 的新手,我只是想知道 JavaFX 的 webview 是否可以运行 JavaScript,除了它与 java 代码的通信。例如,当窗口加载时,我是否可以在 webview 中运行 javascript alert 语句,并像在普通浏览器中一样在 webview 中实际获得警报。我知道我可以通过我的 java 代码捕获这个警报事件

webEngine.setOnAlert

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

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

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

4

1 回答 1

13

WebView JavaScript 回调处理程序示例

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

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

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

webview确认

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 警报处理程序足够灵活,您可以随心所欲地处理警报。

于 2013-09-16T06:21:13.553 回答