Java Swing webEngine.executeScript не запускается в веб-просмотре Javafx HTML - PullRequest
0 голосов
/ 05 апреля 2019

Привет всем, что я был в этом некоторое время. Я не могу понять это правильно из всех примеров, которые я видел до сих пор. Кажется, это будет легко, но я в растерянности.

Мой HTML:

WebView webView = new WebView();

webView.getEngine().setJavaScriptEnabled(true);
webView.setContextMenuEnabled(false);
webView.getEngine().loadContent(""+
"<!DOCTYPE html>\r\n" + 
    "<html>\r\n" + 
        "<head>\r\n" + 
        "</head>\r\n" +
        "<body>" +
                    "<div class=\"chatbox\" style=\"document.body.style.overflow = 'hidden';\">\r\n" + 
                    "       <div class=\"chatlogs\">\r\n" + 
                    "           <div class=\"animated animatedFadeInUp fadeInUp\">" +
                    "                   <div class=\"chat friend\">\r\n" + 
                    "                   <div class=\"user-photo\"><img src=\"" + pic1 + "\"></div>\r\n" + 
                    "                   <p class=\"chat-message\">Whats up!</p>\r\n" + 
                    "                   <span class=\"timefriend\">11:01pm Oct 25 2019</span>\r\n" + 
                    "               </div>\r\n" + 
                    "           </div>" +
                    "           <div class=\"animated animatedFadeInUp fadeInUp\">" +
                    "               <div class=\"chat self\">\r\n" + 
                    "                   <div class=\"user-photo\"><img src=\"" + pic2 + "\"></div>" + 
                    "                   <p class=\"chat-message\">Not much yo!</p>\r\n" + 
                    "                   <span class=\"timeself\">11:01 PM | Oct 11 2019</span>\r\n" + 
                    "               </div>\r\n" + 
                    "           </div>\r\n" + 
                    "           <div class=\"animated animatedFadeInUp fadeInUp\">" +
                    "               <div class=\"chat friend\">\r\n" + 
                    "                   <div class=\"user-photo\"><img src=\"" + pic1 + "\"></div>" + 
                    "                   <p class=\"chat-message\">Whats up!</p>\r\n" + 
                    "                   <span class=\"timefriend\">11:01 PM | Oct 11 2019</span>\r\n" + 
                    "               </div>\r\n" + 
                    "           </div>\r\n" + 
                    "           <div class=\"animated animatedFadeInUp fadeInUp\">" +
                    "               <div class=\"chat friend\">\r\n" + 
                    "                   <div class=\"user-photo\"><img src=\"" + pic1 + "\"></div>" + 
                    "                   <p class=\"chat-message\">Whats up!</p>\r\n" + 
                    "                   <span class=\"timefriend\">11:01 PM | Oct 11 2019</span>\r\n" + 
                    "               </div>\r\n" + 
                    "           </div>\r\n" + 
                    "           <div id=\"nextChatHolder\"></div>" +
                    "       </div>\r\n" + 
                    "   </div>\r\n" +
                    "   <div class=\"footer\"></div>" + 
                    "   <script language=\"javascript\">\r\n" + 
                    "       function app.test() {\r\n" + 
                    "           window.scrollBy(0, 20); \r\n" + 
                    "           alert('done');\r\n" +
                    "       }\r\n" + 
                    "   </script>" +
                    "</body>\r\n" + 
                "</html>");

И это ява, которую я использую (и пытаюсь заставить работать):

webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>()
            {
                public void changed(ObservableValue<? extends State> o, State old, final State state)
                {
                    if (state == State.SUCCEEDED)
                    {
                        JSObject win = (JSObject) webView.getEngine().executeScript("window");
                        win.setMember("app", new JavaApp());
                        //webView.getEngine().executeScript("javaObj.start()");
                    }
                }
            });

private class JavaApp {
        public void test() {
            Platform.exit();
        }
    }

Я думаю, что делает:

function app.test() {\r\n" + 
    window.scrollBy(0, 20); \r\n" + 
    alert('done');\r\n" +
}

и вызов по телефону:

webView.getEngine().executeScript("test()");

Даже это не работает ..... /

webView.getEngine().executeScript("alert('testing')");

1 Ответ

1 голос
/ 06 апреля 2019

Вызов Java-метода из JavaScript

Для вызова Java-метода JavaApp#test() из JavaScript наиболее важная часть реализации уже включена в ваш второй фрагмент кода.По-прежнему отсутствует только сам вызов, например,

<button onclick='app.test();'>Call JavaApp#test-method</button>

Однако необходимо учитывать две важные вещи: во-первых, вложенный класс JavaApp должен быть public.Во-вторых, приложение должно содержать ссылку на JavaApp -экземпляр, необходимый для обратного вызова из JavaScript для выполнения метода (см. здесь , раздел Calling back to Java from JavaScript).

Таким образом, вы должны изменить свой код следующим образом:

JavaApp javaApp = new JavaApp();             // Hold a reference...
webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
    public void changed(ObservableValue<? extends State> o, State old, final State state) {
        if (state == State.SUCCEEDED) {
            JSObject win = (JSObject) webView.getEngine().executeScript("window");
            win.setMember("app", javaApp);   // Use the reference...
        }
    }
});

и

public class JavaApp {                       // Change the access modifier from private to public...
    public void test() {
        Platform.exit();
    }
}

Вызов JavaScript-метода из Java

Если вы хотите вызвать метод JavaScript из Java, например, test(), это делается с помощью

webView.getEngine().executeScript("test()");

В качестве примера я использую test() -метод, указанный в вашем третьем фрагмент, где, однако, имя должно быть изменено с app.test() на test().Если вызывается webView.getEngine().executeScript("test()");, выполняется test() , за исключением метода alert().Это связано с тем, что для некоторых JavaScript-методов (например, window.alert()) WebEngine перенаправляет запрос на обратный вызов (onAlert в случае window.alert()).Если обратный вызов не определен, запрос игнорируется (см. здесь , раздел Обратные вызовы интерфейса пользователя ).Например, обратный вызов для alert() может быть определен следующим образом:

webView.getEngine().setOnAlert(event -> showAlert(event.getData()));

, где showAlert(String msg) - это собственный метод, а msg содержит исходное сообщение (done в случае вашего * 1061).* -method), например:

private void showAlert(String msg){
    Alert alert = new Alert(AlertType.INFORMATION);
    alert.setTitle("Custom Alert");
    alert.setHeaderText("");
    alert.setContentText(msg);
    alert.showAndWait();
}

Больше примеров можно найти в Как сделать, чтобы веб-браузер JavaFX отображал предупреждение и подтверждающее сообщение .

РЕДАКТИРОВАТЬ:

Пример кода для вызова Java-метода из JavaScript: при нажатии кнопки вызывается Java-метод JavaApp#test() из JavaScript, который выводит текст doneв текстовой области.

import javafx.application.Application;
import javafx.concurrent.Worker.State;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

public class WebViewExecuteJavaFromJavaScript extends Application {

    private TextArea textArea;

    private static String HTML_STRING = "" +
        "<!DOCTYPE html>\r\n" + 
        "<html>\r\n" + 
        "    <head>\r\n" + 
        "    </head>\r\n" +
        "    <body>" +
        "        <button onclick='app.test();'>Call Java-method JavaApp#test()...</button>" +    // Call Java-method JavaApp#test()...
        "    </body>\r\n" + 
        "</html>";

    @Override
    public void start(final Stage stage) {

        WebView webView = new WebView();
        WebEngine webEngine = webView.getEngine();
        webEngine.setJavaScriptEnabled(true);
        webEngine.loadContent(HTML_STRING);

        JavaApp javaApp = new JavaApp();    
        webEngine.getLoadWorker().stateProperty().addListener((o, oldState, newState) -> {
            if (newState == State.SUCCEEDED) {
                JSObject win = (JSObject) webView.getEngine().executeScript("window");
                win.setMember("app", javaApp);                                                   // Enable call of Java-method from JavaScript...
            }
        });

        textArea = new TextArea();
        textArea.setWrapText(true);

        VBox root = new VBox();
        root.setPadding(new Insets(5));
        root.setSpacing(5);
        root.getChildren().addAll(webView, textArea);

        Scene scene = new Scene(root); 
        stage.setTitle("Demo: Execute Java from JavaScript");
        stage.setScene(scene);
        stage.setWidth(450);
        stage.setHeight(300); 
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    public class JavaApp {
        public void test() {
            textArea.setText(textArea.getText() + "done ");
        }
    }
}

Пример кода для вызова JavaScript-метода из Java: при нажатии кнопки вызывается JavaScript-метод test() из Java, который выводит текст done в текстовой области и в диалоговом окне.

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class WebViewExecuteJavaScriptFromJava extends Application {

    private static String HTML_STRING = "" +
        "<!DOCTYPE html>\r\n" + 
        "<html>\r\n" + 
        "    <head>\r\n" + 
        "    </head>\r\n" +
        "    <body>" +
        "        <textarea id=\"textarea\" name=\"textarea\" cols=55 rows=3 wrap=\"virtual\"></textarea>" + 
        "        <script language=\"javascript\">\r\n" + 
        "            function test() {\r\n" + 
        "                textarea.value+='done '; \r\n" + 
        "                alert('done');\r\n" +                                      // Is ignored as long as no callback is defined...
        "            }\r\n" + 
        "        </script>" +
        "    </body>\r\n" + 
        "</html>";

    @Override
    public void start(final Stage stage) {

        WebView webView = new WebView();
        WebEngine webEngine = webView.getEngine();
        webEngine.setJavaScriptEnabled(true);
        webEngine.loadContent(HTML_STRING);
        webEngine.setOnAlert(event -> showAlert(event.getData()));                  // Define callback for JavaScript-alert...

        Button button = new Button("Call JavaScript-method test()...");
        button.setOnAction(event -> webView.getEngine().executeScript("test()"));   // Call JavaScript-method test()...

        VBox root = new VBox();
        root.setPadding(new Insets(5));
        root.setSpacing(5);
        root.getChildren().addAll(button, webView);

        Scene scene = new Scene(root); 
        stage.setTitle("Demo: Execute JavaScript from Java");
        stage.setScene(scene);
        stage.setWidth(450);
        stage.setHeight(300); 
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    private void showAlert(String msg){
        Alert alert = new Alert(AlertType.INFORMATION);
        alert.setTitle("Custom Alert");
        alert.setHeaderText("");
        alert.setContentText(msg);
        alert.showAndWait();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...