目次
・本日の成果・考え
・最後に
本日の成果
本日よりようやくウィンドウを表示するソースの作成に移りたいと思います。
では、そのソースです。
package app.windowView.window;
import java.util.List;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
/**
* デスクトップアプリのウィンドウ表示クラス。
* @author
* @version 1.0
*/
public class WindowView extends Application{
public static void main() {
launch(null);
}
/************
* メソッド名:ウィンドウ表示処理
* 処理内容:JavaFXのApplicationクラスの抽象メソッドの実装。ウィンドウの設定値をセットする。
* @param stage 呼び出し元のlaunchメソッドの第2引数、可変長のString型。
* @return void
* @throws IllegalStateException 実行時の引数のうち整数の項目が整数でなかった場合例外。
/************/
@Override
public void start(Stage stage) throws Exception {
//System.out.println("Startメソッド実行されました。");
//呼び出しメソッドlaunchの引数受け取り(1,title 2,windUrl 3,windWidth 4,windHeight)全てStrin型
List<String> laParams = getParameters().getRaw();
System.out.println("受け取った引数;"+laParams);
//引数の中身が存在しない場合エラー
if(laParams.size() == 0) {
throw new IllegalStateException("引数に必要な項目がありません。");
}
String title = laParams.get(0);
String difyUrl = laParams.get(1);
int width,height;
//整数に格納
try {
width = Integer.parseInt(laParams.get(2));
height = Integer.parseInt(laParams.get(3));
} catch (NumberFormatException e) {
//整数以外例外
throw new IllegalStateException("幅または高さが整数ではありません。:"+e.getMessage());
}
//URL読み込み
WebView webView = new WebView();
webView.getEngine().load(difyUrl);
//ウィンドウ表示
Scene scene = new Scene(webView, width, height);
stage.setTitle(title);
stage.setScene(scene);
stage.show();
}
}
JavaFXによるウィンドウ表示機能を使用します。
使い方は以下です。
import javafx.application.Application;のstartメソッドをオーバロイドし、launchメソッドを起動するだけです。
JVMに正しくJavaFXが認識されてGUI用のスレッドが立ち上がれば使えます。
基本設定は以下を参考にしました。
では、テストソースです。
package app.test;
import static java.lang.System.*;
import app.windowView.window.WindowView;
import javafx.application.Application;
public class WindowViewTest {
public static void main(String[] args) {
String className = new Object() {
}.getClass().getName();
String resultOutput = className + "のテストパターン1";
try {
out.println("**********************************************");
out.println(resultOutput + "が開始されました。");
String testTitle = "テスト";
String testUrl = "https:~~~~~~~~~";
String testWidth = "800";
String testHeight = "600";
//ウィンドウ表示実行。
Application.launch(WindowView.class,testTitle,testUrl,testWidth,testHeight);
out.println(resultOutput + "が正常終了しました。");
} catch (Exception e) {
String resultError = String.format("エラーが発生しました。内容は{%s}", e);
out.println(resultError);
} finally {
out.println(resultOutput + "が終了しました。");
out.println("**********************************************");
}
}
}
ウィンドウ表示などの画面で確認したい系のテストでは、Junitは使いません。実行されたスレッドがすぐに終了するみたいで、画面に映ってもすぐに消えてしまいました。
では、実行。
Javaアプリとして実行されているみたいだが、画面には表示されない。
デバックしてみた限り、lauch経由で実装したstartメソッドが起動していないみたい。
先ほどお見せしたWindouView.javaのstartメソッドの直下にコメントアウトしている起動したらコンソール出力する処理がでていないことからも判断できます。
その後もいろいろ試した結果として以下が原因と推測しています。
・実行時のVM引数が正しくない。
・JavaFXのSDKのクラスパスがスレッド実行時に正しく認識できていない。
※コンパイルはできているので、Eclipseとしては認識できているみたいです。
また、ターミナルにコマンドを打ち込んで無理やりテストソースを実行してみると
DifyのWeb画面でウィンドウ表示ができます。
その時の実行コマンドが以下
"$JAVA_HOME/bin/java" \
--module-path "/JavaFXの「lib」フォルダまでの絶対パス/javafx-sdk-21.0.7/lib" \
--add-modules javafx.controls,javafx.web \
-classpath "Javaプロジェクトまでのパス/Dify_desktop/bin:/JavaFXの「lib」フォルダまでの絶対パス/javafx-sdk-21.0.7/lib/*" \
app.test.WindowViewTest
上記コマンドで実行できた時点で以下が判明しました。
・EclipseのJVMでJavaFXが起動できる。
・実行ソースの問題ではない。
EclipseのVM引数が間違っているか?
もともとの起動引数
--module-path /path/to/javafx-sdk-21/lib
--add-modules javafx.controls,javafx.web
-XstartOnFirstThread
起動できたコマンドと比較すると
-XstartOnFirstThread
これか?
しかし、macOsでJavaFXを起動する際は必須?という情報がある。
ものは試しでVM引数から排除して、再トライ
2025/8/28追記
調べてみるとJavaFX自体にUIランタイム初期化処理が走るみたいで、それに対して-XstartOnFirstThread を走らせると、競合する可能性があるみたいです。
加えて、Eclipseのクラスパスにjavafx-swt-jarをビルドすると同様にSWT側での初期化処理が誤爆する可能性があるみたいですのでご注意ください。
著者はちょっとした対応で追加してウィンドウ起動できなくて無駄に時間使ってしまいました。
結果は同様。
しかし、Eclipseの起動構成を一つ一つ見ていく
上記画像のチェックを外して再度トライ。
いけました〜〜
しかし
実は、DifyのWebページですが、JavaFXで表示できてもチャットを入力してもDify側に送信ができないみたいでした。
今回の企画の主旨である「ページ表示で簡単にやりとり!」の案はおそらく頓挫しました。
いや〜、人生楽できないもんですね😢
大人しく外部APIでやり取りするものを作ろうと思います。
ちょっとどういう構成にするか練り直しです。
けど、JavaFXの起動はできたので、ウィンドウで表示するのは続行しようと思います。
最後に
実はこのJavaFXの起動で、2日ほど潰してようやく解決しました。
しかし、Difyでは通信できないとなりちょっとメンタルきてます。
他のYoutubeとかは表示して、動画も視聴できたのでDify側の仕様の話だと思われます。
まぁ、これを機にAPI通信でのチャットbotの実装ができれば今後はAPI通信の実装もできるようになると考えればエンジニアとしては成長できますね。
いや〜面倒です。
以上、ここまでお付き合いありがとうございます。



