从另一个线程更新SWT对象 [英] Updating SWT objects from another thread

查看:105
本文介绍了从另一个线程更新SWT对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Java应用程序中,当调用主模块时,我在一个单独的线程中启动我的SWT GUI。我需要在主线程中执行一些长操作并更新GUI线程。当我尝试从主线程更新GUI线程,即更改标签文本或其他内容时,我得到 java.lang.NullPointerException 。从我在网上看到的是因为SWT不允许非UI线程更新UI对象。如何从主线程更新GUI线程。

In my Java application, when the main module is invoked, i start my SWT GUI in a separate thread. I need to perform some long opertations in the main thread and update the GUI thread. When I try to update the GUI thread from the main thread i.e. change a label text or something, i get a java.lang.NullPointerException. From what I've read online is because SWT doesn't allow non-UI threads to update UI objects. How can I update the GUI thread from the main thread.

我在网上找到了一些例子,但它们都处理了GUI在主线程中运行的场景并且长操作在单独的线程中。我的情况完全相反。

I've found some examples online but they all deal with the scenario in which the GUI runs in the main thread and long operation is in separate thread. My scenario is the total opposite.

有人能告诉我如何更新GUI线程中的小部件吗?

Could someone tell me how I can update widgets in the GUI thread?

推荐答案

我认为你得到的是 java.lang.NullPointerException ,因为你在创建之前试图访问GUI组件。理想情况下,你应该等待gui组件被创建...例如......

I think you are getting java.lang.NullPointerException because you are trying to access the GUI component before it is created. Ideally you should wait for the gui component to get created... for example...

我在一个单独的线程中创建一个GUI ...像这样

I create a single GUI in a separate thread... like this

package test;


import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class GUIThread implements Runnable 
{
    private Display display;
    private Label label;
    public Display getDisplay(){
        return display;
    }
    public void run() 
    {
        display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new GridLayout());
        shell.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,false));
        label = new Label(shell,SWT.NONE);
        label.setText(" -- ");
        shell.open();
        shell.pack();

        while (!shell.isDisposed()) {
        if (!display.readAndDispatch ()) display.sleep ();
        }
        display.dispose();
    }

    public synchronized void update(final int value)
    {
        if (display == null || display.isDisposed()) 
            return;
        display.asyncExec(new Runnable() {

            public void run() {
                label.setText(""+value);
            }
        });

    }

}

在我的主要方法我做这样的事情....

And in my main method i do something like this....

package test;

import org.eclipse.swt.widgets.Display;

public class Main 
{

    public static void main(String[] args) throws Exception
    {
        final GUIThread gui = new GUIThread();
        Thread t = new Thread(gui);
        t.start();

        Thread.sleep(3000); // POINT OF FOCUS
        Display d = gui.getDisplay();

        for(int i = 0; i<100; i++)
        {           
            System.out.println(i + "  " + d);
            gui.update(i);  
            Thread.sleep(500);
        }
    }
}

现在,如果我们注释掉在上面的代码中焦点然后我将始终得到 NullPointerException ...但延迟3秒给我的GUI线程有足够的时间处于就绪状态,因此它不会通过 NullPointerException .....

Now if we comment out the POINT OF FOCUS in the above code then I will always get NullPointerException... But a delay of 3 seconds gives my GUI thread enough time to be in ready state and hence it doesn't through NullPointerException.....

在这种情况下你必须有效地使用等待 yield 方法......否则会导致硬找到Bugs...即等待UI正确实例化然后产生...

In scenario like this you have to efficiently use the wait and yield methods... otherwise it would result in "Hard to find Bugs"... i.e. wait for UI to properly instantiate and then yield...

此外,实际处理在主线程中完成,GUI在单独运行线程...正确通信最好有一些共享和同步的数据结构...或者它可以使用套接字通信完成...你的主线程填充一些端口和您的GUI线程异步在该端口上侦听....

Also the actual processing is done in main thread and GUI is running in separate thread... to communicate properly it is good to have some shared and synchronized data structure... or it could be done using socket communication... your main thread populating some port and your GUI thread asynchronously listening on that port....

希望这将通过s ome解决你的问题....

Hope this will through some light on your problem....

这篇关于从另一个线程更新SWT对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆