JAVA - 如何在线程中循环时修改SWT UI

标签 java multithreading loops swt

我正在尝试实现一个桌面应用程序,该应用程序循环通过一个函数并每 1 秒在 UI 上设置一个文本字段。

但我要么得到

org.eclipse.swt.SWTException: Invalid thread access

当我不使用显示器时

或者当我这样做时,用户界面真的很慢

display.asyncExec(new Runnable() {

我的代码如下所示:

public void open() {
    Display display = Display.getDefault();
    shell = new Shell();
    shell.setSize(486, 322);
    shell.setText("SWT Application");

    Button btnStartLoop = new Button(shell, SWT.NONE);
    btnStartLoop.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseDown(MouseEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() // updates displayArea
                {
                    while (true) {
                        try {
                            text.setText("Text has been set");
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            });
        }
    });
    btnStartLoop.setBounds(35, 30, 75, 25);
    btnStartLoop.setText("Start Loop");

    text = new Text(shell, SWT.BORDER);
    text.setText("0");
    text.setBounds(116, 32, 177, 21);
    shell.open();
    shell.layout();
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
}

有什么办法可以克服这个问题吗?

最佳答案

您绝不能在 UI 线程中 hibernate 。您必须为后台 Activity 使用新的Thread。您可以从线程内调用 Display.asyncExec 来在 UI 线程中运行 UI 更新代码。

btnStartLoop.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseDown(final MouseEvent e) {
        final Thread background = new Thread(new Runnable() {
            public void run()
            {
                while (true) {
                    try {
                        Display.getDefault().asyncExec(() -> text.setText("Text has been set"));
                        Thread.sleep(1000);
                    } catch (final InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        });
        background.start();
    }
});

注意:SwingUtilities 适用于 Swing 应用程序,请勿在 SWT 应用程序中使用它。

您还可以使用 DisplaytimerExec 方法在特定延迟后运行代码,从而避免需要后台线程。

btnStartLoop.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseDown(final MouseEvent e) {
        final Runnable update = new Runnable() {
          public void run()
          {
            text.setText("Text has been set");

            Display.getDefault().timerExec(1000, this);
          }
        };
        Display.getDefault().timerExec(0, update);
    }
});

关于JAVA - 如何在线程中循环时修改SWT UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51121388/

相关文章:

java - 如何在Java中获取 "last saved by"Office文件属性

java - 使用嵌入式 Jetty 进行 JNDI 数据源查找失败

java - java中的线程概念

java - java中的多线程HashTable

r - 为 (i, j, k) 形成一个循环,其中 i,j 和 k 在 R 3.4.4 版本中位于 [0,5] 中

ruby - 在 Ruby 中,循环中的返回值是什么?

java - hasNextInt() 和 nextInt() 方法流程

c# - 在单独的后台线程与进程中运行长时间后台任务

loops - 替换具有初始值的变量

java - Docker - "image operating system "linux“无法在此平台上使用”尝试构建镜像时