Kotlin 視窗設定

      在〈Kotlin 視窗設定〉中尚無留言

Kotlin 的視窗開發可以延用 Java 的 API。底下就對每種 API 進行說明。

各種 API 比較

Java AWT

AWT 是 Java 最早期的視窗 framework。不過沒多久就被 Java Swing 取代,所以請不要使用

Java Swing

Java Swing 是架構在 AWT 之上的 API,可建立輕量級的視窗程式,紅極一時,但是對中文輸入的支援度有 bug,而且現在也已經退流行了,所以也請不要使用

JavaFX

JavaFX 可以用來設計擁有輕量且高效能使用者圖形介面 (Graphical User Interface, GUI) 的應用程式(Application),還能作為 Rich internet application 來發佈。相較於傳統 Java 使用Awt、Swing 實作Application(或是Applet) 的方式,JavaFX 提供了更多、更好的工具以及函式庫協助開發應用程式,而且製作出來的程式效能更好,畫面更美。

JavaFX 1.X 是以 JavaFX Script 的形式撰寫程式,其副檔名為 fx
由於 JavaFX Script 與傳統 Java 差異甚多,開發人員需花費較多的時間學習,也因此 JavaFX Script並未受到很大的重視。

至 JavaFX 2.0,Oracle 將 JavaFX 重新改寫,以 Java 語法取代原 JavaFX Script 語法並移除支援手機的 Mobile 版本。JDK 11 不包含 JavaFX SDK,需以第三方套件的方式導入。目前也已由社群維護

開發 JavaFX 應用程式需繼承 javafx.application.Application 抽象類別,Application 有其「生命週期」,分別為:

init():初始化 JavaFX 應用程式。
start():為 JavaFX 應用程式的進入點。
launch():啟動獨立 (Standalone) 的 JavaFX 應用程式。
stop():當 JavaFX 應用程式結束之前,將執行 stop() 方法。

Tornado FX

Tornado 為龍捲風,是架構在 JavaFX 之上,比 JavaFX 更新進,但 2021 年已停止維護了,所以也請不要使用。

Jetpack Compose for Desktop

開發者同 Tornado FX,這是一種類似 Android UI 的寫法,可以完美的和 Android 跨平台整合。Jetpack Compose 只支援 Kotlin 語法,無法使用 Java 語言開發。

Intellij JavaFX 新專案

在Intellij IDEA 開啟新專案,然後依下圖進行設定。

接著把 BootstrapFX 及 ControlsFX 二個選項打勾。

建立後會出現錯誤 JDK 版本錯誤,請開啟 build.gradle.kts,把 jvmToolchain 改成 21。然後按下上方的 Load Script Configurations

kotlin {
    jvmToolchain( 21 )
}

執行前要先設定,請開啟上方 Current File 然後選 Edit Configurations,Add new run configuation 選 Gradle,Gradle project 選專案根目錄,然後 Run 方框輸入「run」。按下 「OK」後,使用 Shift + F10 即可執行並看到視窗出現。

包裝成 exe

建立 jar

在 Intellij 執行程式時,雖說可以看到視窗彈出,而且也會在 build\lib 產生 SimpleWindow-1.0.jar,但這個檔在執行 java -jar SimpleWindow-1.0.jar 時會出現「沒有主要資訊清單屬性」的錯誤,所以我們需要重建 jar。

請由 File/Project Structure/Artifacts,按下「+」,選取 JAR/From modules with dependencies

Module : 選擇 SimpleWindow.main。請注意,一定要選有 .main 的那個。如果沒有 .main 選項,請執行 File/invalidate Caches,清除所有的 Cache 後重啟 Intellij,然後再執行 Build/Rebuile Module,這樣 .main 及 .test 選項即會出現。

Main Class : HelloApplication (不用選 Kt)

Directory for META-INF : 預設是 src\main\resources,這會造成沒有主要資訊清單屬性的錯誤所以要改成 build\resoruces\main。

按 +/Directory content,選取 build\resources\main,把資源檔包入。
按 +/Directory content,選取 build\class\merged,把 .class 檔包入。

接下來從 build/build artifacts 開始編譯,編譯好的 jar 會在 out\artifacts\SimpleWindow_main_jar 目錄下。最後把裏面的 SimpleWindow.main.jar copy 到 build\lib 之下,並改成 SimpleWindow.jar。

測試

進入專案根目錄下,執行如下指令,如果有看到視窗彈出,表示 jar 包裝成功了。

java --module-path e:\java\javafx-sdk-21.0.7\lib --add-modules javafx.controls,javafx.fxml -jar build\libs\SimpleWindow.jar

建立 RuntimeImage

RuntimeImage 是 exe 檔要執行時所需的環境,需把所需的 jar 全部都 copy 進來。

請開啟命令視窗,進入專案的 app 目錄,然後執行如下執令

jlink --module-path "%JAVA_HOME%\jmods;E:\java\javafx-sdk-21.0.7\lib" --add-modules ALL-MODULE-PATH --output custom-runtime

 上述是把所有的 jar 都加入,如果只想把有用到的 jar 加入,可以使用如下

jlink --module-path "%JAVA_HOME%\jmods;E:\java\javafx-sdk-21.0.7\lib" --add-modules java.base,javafx.controls,javafx.fxml --output custom-runtime

修正 RuntimeImage 錯誤

如果有使到 JavaFX,那麼上述的 custom-runtime\bin 還是原生的 dll 檔,並沒有包含 JavaFX,這應該是 jpackage 的 bug。所以需手動把 e:\java\javafx-sdk-21.0.7\bin 目錄下的所有檔案 copy 到專案下的 app\custom-runtime\bin這個很重要,本人花了整整一天才找出這個 bug

編譯成 exe

使用如下指令編譯成 exe 安裝檔


jpackage --name SimpleWindow --input .\build\libs --main-jar simplewindow.jar --main-class net.ddns.mahaljsp.simplewindow.HelloApplication --app-version 1.0.0 --vendor "MahalJSP" --type exe --win-shortcut --win-menu --win-dir-chooser --win-per-user-install --java-options -Xmx512m --runtime-image custom-runtime --dest .\output --icon e:\java\xxx.ico

–runtime-image 非常重要,這選項會把上述 custom-runtime 目錄裏所有的資料包進去。如果少了這個選項,就會使用系統預設安裝的 JDK。但一般使用者根本不會裝 OpenJDK,後果就是無法執行。

–name 為程式名稱
–vendor 為公司名
–app-version 為程式版本
–dest 為 exe 輸出目錄
–icon 為圖示,一定要使用 ico 檔,不可使用 jpg、png。

包裝成功後, output 目錄下會產生 SimpleWindow-1.0.0.exe,此為安裝檔。安裝後桌面就會有 SimpleWindow 圖示,開始選單中也會有 SimpleWindow 選項。

如果還有使用 javaFX 的媒体播放,還要加入 javafx.media,使用 WebView,則要加入 javafx.web,使用 3D 功能則要加入 javafx.graphics

重新簽章

在 Intellij artifacts 編譯出來的 jar 有時會出現如下錯誤

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

這是因為簽章錯誤,所以需使用如下方式重新簽章。當然如果沒有此錯誤,就不用操作。

mkdir temp
cd temp
jar xf ../SimpleWindow.jar

然後使用檔案總管,把 META-INF 底下的 *.SF、*.RSA、*.DSA 砍掉。然後再使用底下指令重新簽章並包裝

jar cfm ..\SimpleWindow.jar META-INF\MANIFEST.MF .

Exe4j

網路上常有人提到 Exe4j,可以把 jar 包裝成 .exe 檔,不過此程式一來要付費,二來它是用 java Swing 寫成的,所以輸入中文時畫面馬上就亂掉,所以只是先記錄而以,並不建議使用。

請先到 https://www.ej-technologies.com/exe4j/download 下載程式並安裝。

安裝後,在 Change License 中,名稱及公司隨便輸入即可,然後 License 請輸入底下任何一組即可。

A-XVK258563F-1p4lv7mg7sav
A-XVK209982F-1y0i3h4ywx2h1
A-XVK267351F-dpurrhnyarva
A-XVK204432F-1kkoilo1jy2h3r

接下來的操作蠻簡單的,請自行測試。

SceneBuilder

SceneBuilder 原本是由 Oracle 開發的可視覺化 UI 設計程式,讓開發者可以使用拖曳的方式設計 UI。請到 https://gluonhq.com/products/scene-builder/ 下載 23 版本

Intellij Jetpack Compose 新專案

在 Intellij 要開啟 Jetpack 視窗專案需新增外掛,請在新增專案時,按下左下角的 More via plugins/Manage plugin,然後搜尋 jetpack compose,進行安裝後,需重啟 Intellij。

新增專案時選擇 Compose Multiplatform,然後輸入專案名稱及路徑,如下所示。

建立好按下 Shift + F10 即可執行並看到視窗彈出。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *