JavaFXでWebViewを操作

JavaFXでWeb画面のテストをしたかったのですが、まだまだ実装でよくわからないことがあるので、WebViewを使って動作することから実装してみることにしました。

  • 起動直後の画面

この画面の上部をWebViewを使って表示しています。

engine.loadの箇所がノンブロッキング処理になっているので、

        WebView webView = new WebView();
        engine = webView.getEngine();
        engine.load("http://localhost:8080/HelloSample");

load処理が完了した時点で、各ボタンを使用できるようにしています。

        engine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
            @Override
            public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
                if (newState == State.SUCCEEDED && engine.getTitle().equalsIgnoreCase("Hello")) {
                    btnHello.setDisable(false);
                    btnMorning.setDisable(false);
                    btnClear.setDisable(false);
                    btnNotClear.setDisable(false);
                } else {
                    btnHello.setDisable(true);
                    btnMorning.setDisable(true);
                    btnClear.setDisable(true);
                    btnNotClear.setDisable(true);
                }
            }
        });
  • 「Greet Hello」ボタンをクリック後


実装は、nameテキストに「JavaFX」、Greet Selectラジオボタンで「Hello」、Languageセレクトメニューで「English」を選択して、「Greet」ボタンをクリックの順でjavascriptで実行。

            public void handle(ActionEvent t) {
                engine.executeScript("document.getElementById('form1:name').value = 'JavaFX'");
                engine.executeScript("document.getElementsByName('form1:greetSel')[0].checked = true");
                engine.executeScript("document.getElementById('form1:language').options[0].selected = true");
                engine.executeScript("var btn = document.getElementById('form1:greet'); btn.click();");
            }
  • 「Greet おはよう」ボタンをクリック後

「Greet Hello」ボタンをクリック後は上記の「Greeting」画面になっているので「Load Hello Screen」ボタンをクリックして起動直後の画面を表示、その後「Greet おはよう」ボタンをクリックする順で処理しています。(できれば再度engine.loadで最初の画面を表示するように実装したいのですが、画面のLoadとボタンの使用制御の連携がうまくいかなくて、、、)

この実装も上記と同じ方法で、選択しているのが「Good Morning」「Japanese」

            public void handle(ActionEvent t) {
                engine.executeScript("document.getElementById('form1:name').value = 'JavaFX'");
                engine.executeScript("document.getElementsByName('form1:greetSel')[1].checked = true");
                engine.executeScript("document.getElementById('form1:language').options[1].selected = true");
                engine.executeScript("var btn = document.getElementById('form1:greet'); btn.click();");
            }

「Clear Name」ボタンをクリックしてもconfirm画面は表示されません。
変わりに「engine.setConfirmHandler」で「OK」「キャンセル」を制御するようですが、メンバ変数「isConfirmOK」を使って「ClearName(OK)」「ClearName(cancel)」ボタンの動作を制御しているのですが、本来は、Propertyを使って制御すると思うのですが、実装方法が?です。

        btnClear.setOnAction(getClearNameAction(true));          // 「ClearName(OK)」ボタンではconfirmで「OK」をクリックした実装に
        btnNotClear.setOnAction(getClearNameAction(false));   // 「ClearName(cancel)」ボタンではconfirmで「キャンセル」をクリックした実装に
...
    private EventHandler<ActionEvent> getClearNameAction(final boolean isOK) {
        return new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                isConfirmOK = isOK;
                engine.executeScript("var btn = document.getElementById('form1:clearButton'); btn.click();");
            }
        };
    }
.....
        engine.setConfirmHandler(getConfirmAction());
......
    private Callback<String, Boolean> getConfirmAction() {
        return new Callback<String, Boolean>() {
            @Override
            public Boolean call(String p) {
                if (isConfirmOK) {
                    return true;
                }
                return false;
            }
        };
    }
  • ブラウザで「Clear Name」ボタンをクリック後の画面、このconfirm画面がJavaFXのWebViewでは表示されません。

まだまだ前途多難な感じですが、少しずつでも実装していこうと思っています。

実装はJavaFX using WebView · GitHubにアップしています。