Swing 现代化改造
从 Swing 迁移到 Web, 每次一个屏幕
您的 Swing、JavaFX 或 SWT 应用无需修改源代码即可在网页浏览器中运行。然后,您可以围绕它使用 webforJ 构建新界面,并按自己的节奏替换旧界面。Java 团队和代码都保留。
- 桌面工具包:Swing、JavaFX 和 SWT
- 3
- 修改源代码以在浏览器中运行
- 0
- 客户Swing
- 订单webforJ
- 报告Swing
保持不变的内容
仅限屏幕 更改
webforJ 是用于构建企业 Web 应用的全栈 Java 框架:整个应用(包括界面)都用 Java 构建。因此,迁移 Swing 应用时,界面及其底层内容都能一并迁移。
有哪些变化
这些屏幕可按业务重要性逐个切换,同时 Swing 应用的其余部分继续在同一个浏览器标签页中运行。
- 01
团队
如今维护 Swing 应用的人员用 Java 构建 Web 页面,无需组建第二支团队,也不必学习前端工具链。
- 02
代码
Webswing 可直接运行应用。同一代码库既可作为桌面应用运行,也可在浏览器中运行,因此您只需维护一个应用,而不是两个。
- 03
逻辑
与
javax.swing无关的领域类、服务和验证规则会直接从新界面调用,不会先转换为端点。 - 04
工具链
Maven、你的 IDE、调试器和现有测试仍然适用。
这项行动分三个阶段
逐步查看这一步 从桌面端到 Web
每个阶段都会交付用户可见的内容。选择一个阶段,查看该阶段的界面及其实现代码。
在浏览器中运行桌面应用
Webswing 在服务器上运行您的 Swing、JavaFX 或 SWT 应用,并将界面以 HTML5 canvas 的形式传输到浏览器。鼠标和键盘输入会传回实际应用。无需更改源代码。
将其嵌入到带有 WebswingConnector 的 webforJ 视图中。将连接器添加到页面时,它会连接到 Webswing 服务器。
@Route
public class SwingAppView extends Composite<Div> {
private final Div self = getBoundComponent();
private WebswingConnector connector;
public SwingAppView() {
// Initialize the connector with your Webswing application URL
connector = new WebswingConnector("http://localhost:8080/myapp/");
// Set the display dimensions
connector.setSize("100%", "600px");
// Add to the view container
self.add(connector);
}
}
第 1 阶段,共 3 个阶段
双向通信
旧版和新版界面 彼此交流
消息是一种操作:包含一个名称、可选的字符串载荷和可选的二进制载荷。名称可自行定义。通信双方都使用纯 Java,因此无需编写浏览器脚本来进行交互。
- 1
Swing 宣布
双击会发送
select-customer,并将该行作为 JSON。在桌面端,同样的点击仍会打开 Swing 对话框。Application.java (Swing)private void handleDoubleClick(MouseEvent e) {int row = table.rowAtPoint(e.getPoint());if (row >= 0 && row < customers.size()) {Customer customer = customers.get(row);if (isWebswing) {api.sendActionEvent("select-customer", gson.toJson(customer), null);} else {showEditDialog(customer);}}}CustomerBridgeView.java (webforJ)connector.onAction(e -> {switch (e.getActionName()) {case "select-customer" -> e.getActionData().ifPresent(this::openEditor);case "export-ready" -> e.getActionBinaryData().ifPresent(d -> status.setText("Got " + d.length() + " characters"));default -> { }}}); - 2
webforJ 回复
保存时,Web 表单会将
update-customer发回,Swing 应用会刷新其表格。双方都不会调用对方的内部实现。Application.java (Swing)private void setupWebswingListeners() {api.addBrowserActionListener(event -> {if ("update-customer".equals(event.getActionName())) {Customer updated = gson.fromJson(event.getData(), Customer.class);updateCustomer(updated);}});}CustomerTableView.java (webforJ)dialog.onSave(() -> {// Send updated customer back to Swingconnector.performAction("update-customer", gson.toJson(customer));});
向 Swing 发送命令
performAction() 会发送一个名称(可单独发送,也可附带数据)。Swing 应用决定每个名称的含义。
// Trigger a refresh in the Swing application from webforJ
connector.performAction("refresh");
// Send a command with data from webforJ
connector.performAction("selectRecord", "12345");
了解 Swing 何时就绪
连接就绪时触发 onInitialize。Swing 应用完全加载后触发 onStart。请在 onStart 中发送第一个操作。
connector.onInitialize(e -> status.setText("Connected"));
connector.onStart(e -> status.setText("Swing app running"));
使用 AI 助手移植
让助手移植它 逐屏
逐个屏幕操作是重复性工作,正适合交给 AI 编码助手。webforJ AI 插件将其连接到 webforJ MCP server 和 Agent Skills——这些结构化工作流会告诉它何时使用这些工具、按什么顺序使用,以及如何验证结果。
- 1
给它做一个 Swing 界面
询问可调用现有服务的 webforJ 等效方案。
- 2
检查真实 API
MCP 服务器会按需查询 webforJ 文档和 API 详情,而不是猜测。
- 3
您负责审核和测试
对照 Swing 原版检查行为,然后继续下一个界面。
如何开始
来自 JAR 文件 转到浏览器中的页面
您需要一个打包为 JAR 文件的 Swing、JavaFX 或 SWT 应用、Webswing 服务器,以及 webforJ 25.10 或更高版本。
- 1
下载并启动 Webswing
下载 Webswing,解压压缩包,然后运行适用于您平台的脚本启动服务器。服务器将在
http://localhost:8080上响应。
webswing.sh - 2
注册您的应用
在
http://localhost:8080/admin管理控制台中设置应用名称、主类、classpath、JVM 参数和主目录。随后可通过http://localhost:8080/[app-name]/访问该应用。- CORS
- 将您的 webforJ 应用源添加到“允许的源”,例如
http://localhost:8090。 - 端口
- 两者通常都使用 8080。请更改其中一个以避免冲突。
- 3
添加依赖项
webforj-webswing 模块提供 WebswingConnector 及其相关类。
<dependency><groupId>com.webforj</groupId><artifactId>webforj-webswing</artifactId><version>${webforj.version}</version></dependency> - 4
嵌入并配置
向视图添加 WebswingConnector,与第一阶段相同。WebswingOptions 可更改其行为,例如在 webforJ 应用处理登录时隐藏注销按钮。
WebswingConnector connector = new WebswingConnector("http://localhost:8080/myapp/");WebswingOptions options = new WebswingOptions().setDisableLogout(true); // Hide the logout buttonconnector.setOptions(options);
选择你的 首屏
从简单的列表和编辑表单开始。嵌入应用,将这个页面迁移到 webforJ,看看它如何与其他部分协同运行。