user4156687
user4156687

Reputation:

How to handle HTML form in JavaFX application

Can some one please help to how can I capture onclick event of HTML button inside JavaFX? onClick of that button javascript alert should display, I can display HTML page on applet window but onclick event is not working

HTML:

<html lang="en">
<head>
    <title>WebView</title>
    <link rel="stylesheet" type="text/css" href="help.css">
    <script>
        function buttonClick() {
            alert("Button Clicked");
        }
    </script>
</head>
<body>

<button onclick="buttonClick()">Submit</button>

</body>
</html>

Bellow is my JavaFX code:

public class WebViewSample extends Application {

    private Scene scene;

    @Override
    public void start(Stage stage) {
        // create scene
        stage.setTitle("WebView");
        scene = new Scene(new Browser(), 750, 500, Color.web("#666970"));
        stage.setScene(scene);
        // apply CSS style
        //scene.getStylesheets().add("webviewsample/BrowserToolbar.css");        
        // show stage
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
class Browser extends Region {

    private HBox toolBar;
    private static String[] imageFiles = new String[]{
        "help.png"
    };
    private static String[] captions = new String[]{
        "Help"
    };
    private static String[] urls = new String[]{
        WebViewSample.class.getResource("help.html").toExternalForm()
    };    

    final Hyperlink[] hpls = new Hyperlink[captions.length];
    final Image[] images = new Image[imageFiles.length];
    final WebView browser = new WebView();
    final WebEngine webEngine = browser.getEngine();        
    final ComboBox comboBox = new ComboBox();   

    public Browser() {
        //apply the styles
        getStyleClass().add("browser");

        for (int i = 0; i < captions.length; i++) {
            // create hyperlinks
            Hyperlink hpl = hpls[i] = new Hyperlink(captions[i]);
            Image image = images[i] =
                    new Image(getClass().getResourceAsStream(imageFiles[i]));
            hpl.setGraphic(new ImageView(image));
            final String url = urls[i];

            hpl.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent e) {                  
                    webEngine.executeScript("url");
                }
            });


        }

        comboBox.setPrefWidth(60);

        // create the toolbar
        toolBar = new HBox();
        toolBar.setAlignment(Pos.CENTER);
        toolBar.getStyleClass().add("browser-toolbar");
        toolBar.getChildren().add(comboBox);
        toolBar.getChildren().addAll(hpls);
        toolBar.getChildren().add(createSpacer());

        //add components
        getChildren().add(toolBar);
        getChildren().add(browser);
    }    

    private Node createSpacer() {
        Region spacer = new Region();
        HBox.setHgrow(spacer, Priority.ALWAYS);
        return spacer;
    }

    @Override
    protected void layoutChildren() {
        double w = getWidth();
        double h = getHeight();
        double tbHeight = toolBar.prefHeight(w);
        layoutInArea(browser,0,0,w,h-tbHeight,0,HPos.CENTER,VPos.CENTER);
        layoutInArea(toolBar,0,h-tbHeight,w,tbHeight,0,HPos.CENTER,VPos.CENTER);
    }

    @Override
    protected double computePrefWidth(double height) {
        return 750;
    }

    @Override
    protected double computePrefHeight(double width) {
        return 600;
    }
}

Upvotes: 0

Views: 2410

Answers (1)

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40298

The reason why you are not seeing anything is that you have not defined an onAlert handler for the webEngine. Try the simplest thing:

    // in the constructor of `Browser`
    webEngine.setOnAlert((WebEvent<String> event) -> {
        System.out.println("ALERT!!!! " + event.getData());
    });

This will be printing the alert in the std out. This also means that the event is actually captured.

If you want to call Java code from this event, you will have to read this (EDIT 2017/08/06: the link is gone now; this is the closest I could find). In short:

  1. Make an object containing the code you want to call, e.g.:

    public class Bridge {
        public void doSomething() {
            ...
        }
    }
    
  2. Place it in the page context:

    JSObject jsobj = (JSObject) webEngine.executeScript("window");
    jsobj.setMember("bridge", new Bridge());
    
  3. Call it from the JS event handler:

    function buttonClick() {
        bridge.doSomething();
    }
    
  4. Use JSObject.removeMember() once you no longer need the bridge to remove it

  5. Pay attention to security!

Upvotes: 3

Related Questions