桌面应用开发有哪些较新的前端框架可供选择?
推荐先尝试 Compose Multiplatform,或用 Web 技术开发桌面界面
你已经有 Java 后端,也用过 Swing,如果想换一种界面开发方式,我会先推荐 Compose Multiplatform 的桌面端。它用 Kotlin 编写声明式界面,运行在 JVM 上,方便复用现有的 Java 业务代码。
如果你也想学习 Web 前端,可以考虑 Tauri,搭配 Vue、React 或 Svelte 编写界面。希望使用内置 Chromium 和 Node.js 的方案,可以选 Electron。愿意学习 Dart、希望自行控制界面样式的话,也可以试试 Flutter。
这些方案并不都是刚出现的。这里的“较新”,可以理解为尝试 Swing、JavaFX 之外的开发方式。具体选哪个,还要看现有 Java 代码如何与界面连接。
各种方案适合什么情况?
Compose Multiplatform:希望复用 Java 代码
Compose Multiplatform 支持 Windows、macOS 和 Linux 桌面应用。桌面端运行在 JVM 上,Kotlin 可以调用 Java 类。如果你的“后端”其实是本地业务模块,界面和业务代码就可以放在同一个进程中运行。桌面平台说明、Kotlin 与 Java 互操作
它与 Swing 的主要区别在于界面写法:你根据状态描述界面,状态变化后,框架会更新相关 UI。为此,需要学习 Kotlin,以及状态、重组等 Compose 概念。
Java 互操作代码应放在 JVM 源集中。桌面端可以调用 Java,不代表这些代码也能直接用于其他平台。
Tauri:希望用 Web 技术编写界面
Tauri 使用系统 WebView 显示 HTML、CSS 和 JavaScript 界面,并提供基于 Rust 的桌面集成层。界面可以采用 Vue、React、Svelte 等框架。Tauri 官方介绍、架构说明
Vue、React、Svelte 负责页面和交互,Tauri 则负责桌面窗口和系统能力接入。已有的 Java 后端可以继续保留:
- 如果它是独立服务,界面通过 HTTP 或 WebSocket 访问。
- 如果它需要随桌面应用在本机启动,就要额外处理进程启动、通信、退出和 Java 运行时分发。
Tauri 的 sidecar 机制可以随应用分发并启动外部程序,但 Java 后端及其运行时仍需要自行打包完整。外部程序集成文档
使用系统 WebView,还需要在目标操作系统上检查页面兼容性。计算最终安装包大小时,也要把 Java 后端和运行时算进去,不能只看桌面外壳。
Electron:希望采用内置浏览器运行环境
Electron 使用 HTML、CSS 和 JavaScript 构建桌面应用,内置 Chromium 和 Node.js,支持 Windows、macOS 和 Linux,也可以搭配 Vue、React 等界面框架。Electron 官方介绍
如果你希望各平台都使用随应用分发的 Chromium,避免依赖各自的系统 WebView,可以考虑 Electron。这也意味着需要把整套运行环境一起分发,具体的内存和磁盘占用要用自己的应用测量。
Java 业务代码通常仍作为独立进程或服务,通过接口与 Electron 通信。你还需要学习 Electron 的主进程、渲染进程和 IPC 机制,并按官方建议配置隔离与权限边界。Electron 安全文档
Flutter:愿意学习 Dart,重视自定义界面
Flutter 支持构建 Windows、macOS 和 Linux 桌面应用,也支持桌面插件。Flutter 桌面开发文档
如果想尝试与 Java GUI、Web 前端都不同的 UI 开发方式,可以把 Flutter 列入候选。已有 Java 后端的项目,建议先通过 HTTP 等接口连接,避免初次尝试就引入复杂的跨语言桥接。
选择前要检查所需插件是否支持目标桌面平台,尤其是打印、托盘和硬件访问等功能。插件支持 Android,不代表它也支持桌面端。
怎样开始,才能尽早判断是否合适?
先确认 Java 后端的形式:
| Java 代码的形态 | 建议优先尝试 |
|---|---|
| 本地业务类库,需要直接调用 | Compose Multiplatform |
| 已经提供 HTTP 等服务接口 | Tauri、Electron 或 Flutter |
| 需要随客户端启动的本地服务 | 可以选择上述方案,但应先验证进程管理和打包 |
接着做一个实际调用业务代码的小原型。选一个有代表性的页面,完成数据读取、编辑和错误提示,再生成目标系统的安装包,看看界面写法是否顺手、发布成本是否可以接受。如果应用依赖复杂表格、中文输入或大量快捷键,也要在这个阶段验证。
示例:Compose 界面调用 Java 类
如果业务逻辑需要保留在本地,可以先试着从 Kotlin 界面调用 Java 类。
Java 业务类 GreetingService.java:
package demo;
public final class GreetingService {
public String greet(String name) {
return "你好," + name;
}
}
在已配置 Compose Desktop 和 Material 3 依赖的 JVM 模块中,使用 Kotlin 编写 Main.kt:
package demo
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
fun main() = application {
Window(
onCloseRequest = ::exitApplication,
title = "Java 业务界面"
) {
val service = remember { GreetingService() }
var message by remember { mutableStateOf("等待操作") }
MaterialTheme {
Column(Modifier.padding(24.dp)) {
Text(message)
Button(
onClick = {
message = service.greet("开发者")
}
) {
Text("调用 Java")
}
}
}
}
}
运行这段代码的前提是,项目已配置 Java、Kotlin 混合编译,或已依赖包含该类的 Java 模块。示例不包含完整构建配置,插件和依赖版本应使用官方模板提供的兼容组合。
示例中的调用会立即返回。如果实际业务需要访问数据库、读取文件或执行耗时计算,应放到后台执行,避免阻塞界面线程。使用协程时,也要为阻塞调用选择合适的调度器。
选型时还要注意什么?
先明确自己是否愿意引入另一门语言。如果必须继续用 Java 编写全部界面,上述选择就会受到明显限制:Compose UI 使用 Kotlin,Flutter 使用 Dart,Web 界面通常使用 JavaScript 或 TypeScript。
跨平台支持需要逐项验证。窗口能显示出来后,还要检查缩放、字体、文件对话框,以及安装和升级流程。使用本地 Java 服务时,需要处理启动就绪检测、端口冲突和退出清理;如果开放本地 HTTP 接口,还应限制监听范围并设计访问校验。
按你的需求,我会先用 Compose Multiplatform 做一个能调用现有 Java 业务的页面,看看是否喜欢这种开发方式。如果更想学习 Web 前端,再用 Tauri 或 Electron 做同一个页面进行比较。
备注:内容仅供参考。
