Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript in JavaFX WebView

I am new to Java and JavaFX and I am just wondering if the webview of JavaFX can run javascript in itself apart from the communcation it has with the java code. 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. I know that I can capture this alert event with my java code by

webEngine.setOnAlert

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

The reason that I am asking this simple question is because I am using a webview with a textarea where I want to enable spell checking. I have a javascript spell checker that works perfectly in normal browsers where I get the red underline when I type something wrong, but I want to get it to work in the JavaFX webview also.

I am thankful for any help I can get!

like image 299
Jason Blade Avatar asked Sep 15 '13 20:09

Jason Blade


People also ask

How do I execute JavaScript in a JavaFX WebView?

Execute JavaScript From Java It is possible to execute JavaScript embedded in the HTML page displayed inside a JavaFX WebView from Java. You execute JavaScript in a WebView from Java via the WebEngine executeScript () method. Here is a simple example of executing JavaScript embedded in a WebView from Java code:

How to display JavaScript and CSS code inside a JavaFX application?

It is capable of showing CSS, HTML, and JAVASCRIPT code on the webView, inside the JavaFX application. To use this we need to import the library from the JavaFX while programming.

How to implement browser tabs in JavaFX?

In your JavaFX application, you can implement browser tabs by using the TabPane class and create a new WebView object when a user adds a new tab. To further enhance this application, you can apply effects, transformations and animated transitions, and even add more WebView instances.

How to invoke JavaScript from JavaFX?

Now you know how to invoke JavaScript from JavaFX. In this chapter, you can explore the opposite functionality — calling from web content to JavaFX. The general concept is to create an interface object in the JavaFX application and make it known to JavaScript by calling the JSObject.setMember () method.


1 Answers

WebView JavaScript Callback Handler Example

Here is some sample code for displaying a JavaFX dialog based on a JavaScript trigger command. The sample code is for a JavaScript confirm handler, but code for an alert handler would function similarly.

In the sample screenshot, the yellow bar on the left will display a JavaFX label based on the result of a confirmation dialog triggered by a JavaScript function invoked from the WebView which covers the rest of the screen.

The confirmation dialog is rendered in JavaFX over the top of the WebView, preventing interaction with the WebView while the dialog is displayed. The styling of the confirmation dialog, is just a sample, it might be styled any way you wish using css, and the layout may be changed in code as well (or you could define dialog layout in FXML markup instead if you preferred).

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

Possible answer to your question

Your question isn't exactly clear to me, but I think if you popup a ControlsFX dialog box, you will achieve what you want. You could use either a standard Dialog (which functions like Internet Explorer's JavaScript alert dialog) or a light-weight dialog (which functions like Firefox's JavaScript alert dialog) - see the ControlsFX features page for more information.

ControlsFX is Java 8 based, but for JavaFX 2.2, there are numerous topics on StackOverflow regarding showing dialogs in JavaFX, (for example: How to create and show common dialog (Error, Warning, Confirmation) in JavaFX 2.0?). The sample code above is an example of dialog usage in JavaFX 2.2

Comments on additional points raised in your question

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

Yes WebView can process 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.

Yes, if you have set up an alert handler for your WebView so that it functions like a "normal browser", popping up a dialog on receiving a JavaScript alert command. Note that "normal browsers" do not modify the web page document object model based on a JavaScript alert function, instead they popup a native dialog - the dialog is not really part of the web page.

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

"Normal" browsers handle alerts differently depending on their UI model. For example in Firefox the alert dialog will appear in the current browser tab window, and in Internet Explorer the alert dialog will appear above the Internet Explorer window. The JavaFX alert handler is flexible enough that you can handle the alert pretty much however you want.

like image 69
jewelsea Avatar answered Oct 07 '22 00:10

jewelsea