0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

既存のSWTアプリをJavaFX

Last updated at Posted at 2025-04-08

あなたの目的は:

既存のSWTアプリのUIをHTMLで置き換えつつ、完全ローカルでJavaFXを使って表示する構成

ということなので、以下のような構成の 最小サンプルコード を用意しました:


✅ サンプルの構成概要

  • UI → HTML + JavaScript
  • 表示 → JavaFX WebView
  • ロジック → Javaで受け取り(JavaBridge
  • ネットワークなし・完全ローカル

📁 プロジェクト構成(例)

your-project/
├─ src/
│  └─ App.java
├─ resources/
│  └─ ui.html

🖥️ App.java(JavaFX + HTML連携)

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

public class App extends Application {

    @Override
    public void start(Stage stage) {
        WebView webView = new WebView();
        WebEngine engine = webView.getEngine();

        // HTML読み込み(ローカルファイル)
        String url = getClass().getResource("/ui.html").toExternalForm();
        engine.load(url);

        // JSからJavaを呼び出すためのブリッジ設定
        engine.getLoadWorker().stateProperty().addListener((obs, old, newState) -> {
            if (newState == javafx.concurrent.Worker.State.SUCCEEDED) {
                JSObject window = (JSObject) engine.executeScript("window");
                window.setMember("javaBridge", new JavaBridge());
            }
        });

        stage.setTitle("JavaFX HTML UI Sample");
        stage.setScene(new Scene(webView, 400, 300));
        stage.show();
    }

    // JavaScriptから呼び出されるクラス
    public class JavaBridge {
        public void onButtonClicked(String message) {
            System.out.println("JavaScriptから呼ばれた: " + message);

            // → ここにSWTアプリの既存処理とつなげるロジックを追加可
        }
    }

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

🌐 ui.html(resourcesフォルダに置く)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML UI</title>
</head>
<body>
    <h2>JavaFX HTML UI</h2>
    <button onclick="notifyJava()">Javaに伝える</button>

    <script>
        function notifyJava() {
            if (window.javaBridge) {
                window.javaBridge.onButtonClicked("ボタンが押されたよ!");
            } else {
                console.log("JavaBridgeが見つかりません");
            }
        }
    </script>
</body>
</html>

✅ 実行結果

  • JavaFX のウィンドウが立ち上がる
  • HTMLが表示され、ボタンを押すと Java の onButtonClicked が呼ばれる
  • System.out.println(...) で受信確認できる

🧠 ポイント解説

機能 実装場所 解説
HTML表示 WebView ローカルのHTMLファイルを読み込み
JSからJavaを呼ぶ JSObject.setMember() JavaのメソッドをJSで使えるようにする
完全ローカル動作 file:///... ネットワーク不要、セキュア
SWTアプリとの連携 JavaBridgeクラス SWTのAPI呼び出しを組み込めばOK

💬 より発展的な応用も可能

  • Java → JavaScript の呼び出し(engine.executeScript(...)
  • テキスト入力/テーブル/画面遷移など複雑なUI構成もHTML/JSで制御
  • CSS/Bootstrap/Vue.jsなどの導入(軽量ならOK)

もしこのサンプルをベースに、**「既存SWTの処理を移植したい」「UIをもっと複雑にしたい」**などあれば、それに合わせて発展版も作れますよ!

どう使っていきたいか、教えてください!

さらに質問!

engine.getLoadWorker().stateProperty().addListener((obs, old, newState) -> {これはどのタイミングで呼び出されるものですか?

めちゃくちゃ鋭いところ聞いてくれました!
この部分の理解は、JavaFXで WebView を使う上でとても重要です。


🔍 engine.getLoadWorker().stateProperty().addListener(...) の意味

これは、

HTMLの読み込み処理(=Webページのロード)の状態が変わったら実行される処理を定義するもの

です。


🧠 もう少し具体的に言うと:

engine.getLoadWorker().stateProperty().addListener((obs, old, newState) -> {
    if (newState == Worker.State.SUCCEEDED) {
        // ページの読み込みが完了したときに呼ばれる処理
    }
});

というのは、

  1. engine.load(url) でHTMLの読み込み開始
  2. 読み込み進行中は Worker.State.RUNNING
  3. 完了したら Worker.State.SUCCEEDED になる
  4. そのときにだけ、newState == SUCCEEDED の中身が実行される!

✅ なぜこれが必要か?

HTMLがまだ完全にロードされていない状態window.setMember("javaBridge", ...) を実行すると、JavaScript側の window が未定義だったり、html にアクセスできなかったりして うまくブリッジできない

→ なので、**「HTMLが完全に読み込まれてから」**JavaとJSを繋ぐのが大事!


💬 例えると…

HTMLの読み込みを「料理」にたとえるなら:

  • engine.load(url) → 料理を始める(オーブンに入れる)
  • addListener(...) → 焼き上がったかを監視してる人
  • newState == SUCCEEDED → 焼き上がった瞬間!
  • → そのときに「できたて料理を取り出して、テーブルに出す」= JavaとJSの接続を確立

🧪 もしこれが無いとどうなるか?

// 読み込み前にブリッジを設定しようとすると…
JSObject window = (JSObject) engine.executeScript("window");
window.setMember("javaBridge", new JavaBridge()); // ← ここでNullPointerになることも

上記のように HTML側がまだロードされていないと window が取得できずエラーになります。


🟢 安心して使ってOK

この LoadWorker 監視は JavaFXのWebView連携での「お約束」です。
JSとのブリッジや、JavaScriptからJavaへイベントを受け取るには必須の処理になります。


✨まとめ:このリスナーは何のため?

項目 内容
何をしている? HTMLの読み込み完了(SUCCEEDED)を監視してる
いつ呼ばれる? engine.load() の読み込みが完了した直後
何のために? JavaScript と Java を正しくブリッジするため
無くても動く? タイミングによっては動くけど、不安定・バグの元!

もっと知りたい機能(例えばJavaからJSの関数を呼ぶとか)があれば、続けて聞いてくれてOKです!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?