You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不冻结SWT GUI的前提下等待线程完成并获取用户输入

问题核心原因

  1. SWT 是单线程 UI 框架,所有 UI 组件的创建、属性修改、事件绑定操作都必须在 UI 线程(也就是 Display 线程)执行,你在自定义的 Openbox 子线程中创建 Text 组件、修改组件属性属于违规操作,会导致组件异常甚至程序崩溃。
  2. 你写的 while(!inputted) {continue;} 属于忙等待逻辑,如果你是在 UI 线程执行这段循环,会直接卡住 UI 事件的处理,导致界面冻结;你自定义的 Thread 子类里写的带 Test 参数的 run 方法是自定义方法,线程启动后只会调用无参的 run(),所以你写的等待逻辑根本没有执行。
  3. 你设计的「调用 input 方法后同步等待用户输入完成再返回内容」的逻辑,不能用空循环实现,要配合 SWT 内置的事件分发机制实现。

解决方案

不需要自己额外创建子线程处理 UI 逻辑,直接用 SWT 内置的事件循环方法处理等待逻辑即可,修改后的参考代码如下:

public String input(String prompt) {
    inputted = false;
    consoleText += prompt;
    console.setText(consoleText);
    
    // 直接在UI线程创建输入框,不要开子线程
    consoleInput = new Text(shell, SWT.NONE);
    consoleInput.setBackground(SWTResourceManager.getColor(SWT.COLOR_DARK_CYAN));
    consoleInput.setBounds(10, 10, 414, 21);
    consoleInput.setFocus(); // 自动聚焦到输入框
    
    // 绑定回车事件
    consoleInput.addListener(SWT.DefaultSelection, event -> {
        // 输入完成处理逻辑
        String inputContent = consoleInput.getText();
        consoleText += inputContent + "\n";
        console.setText(consoleText);
        returnStr = inputContent;
        inputted = true;
        consoleInput.dispose(); // 销毁输入框
    });

    // 等待输入完成,主动处理UI事件避免冻结
    Display display = shell.getDisplay();
    while (!inputted) {
        // 处理所有待执行的UI事件
        if (!display.readAndDispatch()) {
            // 无事件时休眠10ms,避免占用过高CPU
            display.sleep();
        }
    }
    return returnStr;
}

你之前写的 Input、Openbox 两个线程类可以直接删除,没有作用。

额外注意事项

如果后续你确实需要在业务子线程中操作 UI 组件,必须用 SWT 提供的线程切换方法包装操作:

Display.getDefault().asyncExec(() -> {
    // 这里写UI操作代码
});

内容的提问来源于stack exchange,提问作者maxbear123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 20:48:00