【问题标题】:JAVA - how to modify SWT UI while looping in threadJAVA - 如何在线程中循环时修改 SWT UI
【发布时间】:2018-07-01 07:49:49
【问题描述】:

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

但我要么得到 ​​p>

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();
        }
    }
}

有什么办法可以克服吗?

【问题讨论】:

    标签: java multithreading loops swt


    【解决方案1】:

    您绝不能在 UI 线程中休眠。您必须为后台活动使用新的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);
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-23
      • 2013-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-23
      相关资源
      最近更新 更多