当前位置: 首页 > 面试题库 >

定期更新SWT会导致GUI冻结

宋新知
2023-03-14
问题内容

问题 :定期更新GUI字段时,SWT冻结。

我想有一个带有文本字段的基于SWT的GUI,其值会定期增加。

  1. 最初,我从单独的线程访问textField导致抛出异常:

线程“
Thread-0”中的异常org.eclipse.swt.SWTException:在org.eclipse.swt.SWT.error(SWT.java)的org.eclipse.swt.SWT.error(SWT.java:4533)处无效的线程访问:4448),位于org.eclipse.swt.SWT.error(SWT.java:4419),位于org.eclipse.swt.widgets.Widget.error(Widget.java:482),位于org.eclipse.swt.widgets.Widget。在org.eclipse.swt.widgets.Text.setText(Text.java:2311)在regreon处检查Widget(Widget.java:373)在java.lang.Thread.run(0在Incrementing.lambda
$ 0(Incrementing.java:62)线程(java:745)

  1. 阅读SWT文档(由于@ marko-topolnik)之后,我尝试在循环中使用display.SyncExec(Runnable r)display.AsyncExec(Runnable r)与runnable一起使用Thread.sleep。但这导致 整个事情冻结。 这是代码:

包装任何东西;导入org.eclipse.swt.widgets.Display; 导入org.eclipse.swt.widgets.Shell;
导入org.eclipse.swt.widgets.Text; 导入org.eclipse.swt.SWT;

公共类FreezingGUI {

    protected Shell shell;
private Text text;

public static void main(String[] args) {
    try {
        FreezingGUI window = new FreezingGUI();
        window.open();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void open() {
    Display display = Display.getDefault();
    createContents();
    shell.open();
    shell.layout();

    // HOW TO DO THAT???
    display.syncExec(() -> {
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Integer i = Integer.parseInt(text.getText()) + 1;
                text.setText(i.toString());
            }
        }
    }
    );
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
}

protected void createContents() {
    shell = new Shell();
    shell.setSize(450, 300);
    shell.setText("SWT Application");

    text = new Text(shell, SWT.BORDER);
    text.setEditable(false);
    text.setText("0");
    text.setBounds(30, 32, 78, 26);
}

}

如何避免冻结和引发异常?


问题答案:

任何更改UI对象的SWT操作都必须在SWT用户界面线程上运行。

在您的情况下,该text.setText(i.toString());行是SWT UI操作,并且在其他线程中运行。

您可以使用的asyncExecsyncExec方法Display在UI线程中运行一些代码。因此,请替换:

text.setText(i.toString());

final String newText = i.toString();
Display.getDefault().asyncExec(() -> text.setText(newText));

(这是假设您使用的是Java 8)。

使用asyncExec将异步进行UI更新。syncExec如果您想暂停线程直到更新完成,请改用。

如果您使用的是Java 7或更早版本,请使用:

 final String newText = i.toString();
 Display.getDefault().asyncExec(new Runnable() {
    @Override
    public void run() {
      text.setText(newText);
    }
 });

请注意,您还应该检查是否Shell正在处理该线程并停止后台线程。如果不这样做,则在关闭应用程序时会出现错误。您的代码增量i也是错误的。该线程有效:

new Thread(() -> {
    for (int i = 1; true; i++) {
        try {
            Thread.sleep(1000);
        } catch (final InterruptedException e) {
            return;
        }

        if (shell.isDisposed())  // Stop thread when shell is closed
          break;

        final String newText = Integer.toString(i);
        Display.getDefault().asyncExec(() -> text.setText(newText));
    }
}).start();


 类似资料:
  • 描述 我有一个小应用程序,它使用hook更新状态,但每次更新时,都会导致页面延迟。我指的是实际的延迟,而不仅仅是“等待异步”延迟。 我的理论是,更新状态会重新呈现太多的组件,因为如果我将状态减少到更少的值,滞后就会消失。 从本质上说,我担心我更新状态的方式没有隔离我想要的值。 密码 我将回购加载到CodeSandbox:https://codesandbox.io/s/long-forest-y9

  • 今天我将Android studio从3.0.1升级到3.1。 我和Gradle遇到了一个奇怪的问题。每次我试着编辑一篇文章。gradle文件,Android Studio冻结。 通过一些研究,我发现每次你编辑一个。gradle文件,Android Studio发送搜索请求”http://search.maven.org/". 我在工作中落后于代理,一切都配置好了,在更新之前一切都正常工作。 是否

  • 我一直在尝试开始react原生开发。我遵循了文档中的安装步骤,一切都很好。但是,当我尝试运行应用程序时,我的模拟器会冻结,我的整个PC也是如此,它几乎不会对任何事情做出响应。 JS服务器...安装应用程序得信息... 任务:app:installdebug 02:13:54 v/ddms:execute:正在运行am get-config 02:13:54 v/ddms:在“emulator-55

  • 问题内容: 我有一个问题,我的Swing GUI组件在程序忙时没有为我更新。我正在创建一个图像编辑器,并且在进行大量处理时,我尝试在其工作时更改“状态”标签,以使用户了解正在发生的事情。标签直到处理完成后才会更新。 如何立即更新标签,而不必等待?顺便说一下,我的标签都放在了JPanel上。 在for循环和以下方法完成之前,不会设置我的标签。 问题答案: 你可以做这样的事情,不是最好的,但是它可以给

  • 问题内容: http://i.stack.imgur.com/XvHm5.png 当我单击“打开”按钮时,它将开始在JTextField上发送垃圾邮件1。而是冻结整个GUI,包括关闭按钮。我正在使用while循环,当您再次单击jButton时,它将停止。因为jButton被冻结,所以我无法停止该程序。我已经读过线程和多线程将有所帮助,但是所有教程都太复杂了,以至于我无法理解。他们说将循环和GUI放

  • 问题内容: 运行Tomcat(7.0.28)的Java Web应用程序会定期变得无响应。我希望对可能的罪魁祸首(同步?)提出一些建议,以及一些建议的工具,以收集有关崩溃期间发生的事情的更多信息。我积累的一些事实: 当Web应用程序冻结时,tomcat继续将请求线程送入应用程序,但该应用程序不会释放它们。线程池已满(当前为250),然后后续请求立即失败。在正常操作期间,活动线程永远不会超过2或3。