作為長期從事 JavaEE 開發的工程師,作者因專案需求接觸 JavaFX,並在兩個月內完成 PC 客戶端開發。本文總結 JavaFX 對比 Swing 的核心優勢、遷移心得與關鍵技術點。
| 維度 | Swing | JavaFX | 優勢結論 |
|---|---|---|---|
| UI 美觀度 | 平台風格、外觀過時 | 現代化、支持 CSS 樣式、FXML 聲明式佈局 | ✅ JavaFX 完勝 |
| 瀏覽器嵌入 | 無原生支持 (需 JxBrowser 等商業庫) | 內置 WebView (WebKit),完整支持 HTML5/CSS3/JS | ✅ JavaFX 獨有 |
| 資源加載 | 打包 JAR 後資源路徑易出錯 | src 目錄資源打包無感知,getClass().getResource() 穩定 | ✅ JavaFX 更可靠 |
| 圖形渲染 | CPU 軟渲染 | 硬件加速 (Prism 渲染管線,支持 DirectX/OpenGL) | ✅ JavaFX 效能更強 |
| 綁定與屬性 | 手動監聽器模式 | 綁定 API,聲明式數據同步 | ✅ JavaFX 開發效率高 |
| 學習曲線 | 成熟、資料多 | 概念新 (FXML、CSS、Property、Binding) | ⚠️ Swing 入門易 |
StringProperty, IntegerProperty 等可觀察屬性,雙向綁定自動同步 UI 與模型WebEngine.executeScript() 雙向通信public class LoginController {
@FXML private TextField usernameField;
@FXML private PasswordField passwordField;
@FXML void handleLogin() {
String user = usernameField.getText();
// 業務邏輯...
}
}
WebView webView = new WebView();
WebEngine engine = webView.getEngine();
engine.load("https://example.com");
// Java -> JS
engine.executeScript("alert('Hello from Java')");
// JS -> Java (需配置 JSObject)
engine.getLoadWorker().stateProperty().addListener((obs, old, newState) -> {
if (newState == Worker.State.SUCCEEDED) {
JSObject window = (JSObject) engine.executeScript("window");
window.setMember("javaBridge", new JavaBridge()); // 暴露 Java 對象
}
});
public class JavaBridge {
public void callFromJS(String msg) { System.out.println("JS 調用: " + msg); }
}
/* style.css */
.root { -fx-font-family: "Microsoft YaHei"; -fx-base: #f0f0f0; }
.button { -fx-background-color: linear-gradient(#4287f5, #1e5fd8); -fx-text-fill: white; }
.button:hover { -fx-background-color: linear-gradient(#5a9bff, #3a7ae0); }
scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm());
javafx-maven-plugin、gradle-javafx-plugin 自動化構建module-info.java,requires javafx.controls; requires javafx.fxml; requires javafx.web;Task/Service 異步執行