Как обрабатывать форму HTML в приложении JavaFX

Может кто-нибудь помочь, как я могу захватить событие onclick кнопки HTML внутри JavaFX? При нажатии этой кнопки должно отображаться предупреждение javascript, я могу отображать HTML-страницу в окне апплета, но событие onclick не работает

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>

Ниже приведен мой код JavaFX:

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

person Community    schedule 01.07.2015    source источник


Ответы (1)


Причина, по которой вы ничего не видите, заключается в том, что вы не определили обработчик onAlert для webEngine. Попробуйте самое простое:

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

Это будет печатать предупреждение в стандартном выводе. Это также означает, что событие действительно зафиксировано.

Если вы хотите вызвать код Java из этого события, вам придется прочитать это < strong>(EDIT 2017/08/06: ссылка больше не работает; это самое близкое, что я смог найти). Короче говоря:

  1. Создайте объект, содержащий код, который вы хотите вызвать, например:

    public class Bridge {
        public void doSomething() {
            ...
        }
    }
    
  2. Поместите его в контекст страницы:

    JSObject jsobj = (JSObject) webEngine.executeScript("window");
    jsobj.setMember("bridge", new Bridge());
    
  3. Вызовите его из обработчика событий JS:

    function buttonClick() {
        bridge.doSomething();
    }
    
  4. Используйте JSObject.removeMember(), когда вам больше не нужен мост, чтобы удалить его.

  5. Обратите внимание на безопасность!

person Nikos Paraskevopoulos    schedule 01.07.2015
comment
Привет, Никос, у меня есть еще одно сомнение: если у меня есть 2 кнопки с двумя разными функциями JavaScript, как я могу их отличить? ‹button onclick=buttonClick1()›Click‹/кнопка› ‹button onclick=buttonClick2()›Click‹/button› ‹script› function buttonClick1() { alert(первая кнопка нажата); //bridge.doSomething(); } function buttonClick2() { оповещение (нажата вторая кнопка); //bridge.doSomething(); } ‹/скрипт› - person ; 03.07.2015
comment
Тот же принцип; например создать другой объект, Bridge2, -ИЛИ- создать новый метод doSomethingElse() в Bridge и т.д... - person Nikos Paraskevopoulos; 03.07.2015
comment
Спасибо, Никос. 1. Не могли бы вы рассказать мне, как получить поля формы, если у меня есть текстовое поле типа ‹input type=text id=text-box› - person ; 03.07.2015
comment
2. Как перейти с одной страницы на другую с содержанием, пожалуйста? это может решить все мои сомнения. - person ; 03.07.2015
comment
Для (1) вам нужны стандартные манипуляции с Javascript - если вы не уверены, лучше задать другой вопрос. (2) - это еще один вопрос, вы должны предоставить более подробную информацию о том, что именно вы хотите. Стандартные HTML-ссылки работают во многих случаях... - person Nikos Paraskevopoulos; 03.07.2015
comment
Спасибо, Никос. Конечно задам еще вопрос - person ; 06.07.2015
comment
Отличный ответ, но ссылка this выше не работает - у вас есть обновленная ссылка? - person DrAl; 06.08.2017
comment
@DrAl Ach, веб-контент приходит и уходит ... и я не смог найти ту же запись в блоге Oracle. Это самое близкое, что я смог найти. (По крайней мере, я последовал мудрому совету Stackoverflow включить связанный контент в ответ :)) Также обновление выше; - person Nikos Paraskevopoulos; 06.08.2017