我后台有一个类负责接收数据,数据随时可能到来,我想在数据到来时实时的更新界面,不在同一个类里面,在数据到来时我直接调用界面类里的更新函数,出错,请问这种问题有什么好的解决方案没?

解决方案 »

  1.   

    界面类里面的更新函数是否运行在UI thread? 
      

  2.   

    界面里面有一个刷新函数
    public class ClientUI
    {
    private Text subText;
    public static void refreshSub()
    {subText.append("\naaaaaa");}
    }在后台有这样一个函数:消息一来就会调用
    public void onMessage(Message message) 
    {
       ClientUI.refreshSub();
    }错误信息:
    org.eclipse.swt.SWTException: Invalid thread access
    at org.eclipse.swt.SWT.error(SWT.java:3450)
    at org.eclipse.swt.SWT.error(SWT.java:3373)
    at org.eclipse.swt.SWT.error(SWT.java:3344)
    at org.eclipse.swt.widgets.Widget.error(Widget.java:433)
    at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:326)
    at org.eclipse.swt.widgets.Text.setText(Text.java:1682)
    at client.Subscribe.onMessage(Subscribe.java:62)
    at org.exolab.jms.client.JmsMessageConsumer.onMessage(JmsMessageConsumer.java:254)
    at org.exolab.jms.client.JmsSession.onMessage(JmsSession.java:1023)
    at org.exolab.jms.client.net.JmsSessionStubImpl.onMessage(JmsSessionStubImpl.java:478)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.exolab.jms.net.orb.DefaultORB$Handler.invoke(DefaultORB.java:553)
    at org.exolab.jms.net.orb.DefaultORB$1.run(DefaultORB.java:511)
    at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)2楼说的很正确,更新函数没运行在UI thread里,请问怎么解决!thread问题,
      

  3.   

    SWT不允许其他线程修改自己的display里面的可视化控件,所以你的是不能执行。我做过相关的工作,要解决这个情况,那么你就必须用到display.asyncExec()这个方法。我给你一段代码,你自己研究下:
    import java.util.Iterator;import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Text;
    /**
     * 该类为一个监听器,主要作用是新开一个线程,把结果写入主窗口的结果框
     * @author admin
     *
     */
    public class ResultListen implements Runnable {
    RaidcmdAgent agent;
    Display display;
    Runnable runnable = null;
    Text displayText;
    //构造函数,对传入的RaidcmdAgent、Display、Text进行赋值,并且启动本线程
    public ResultListen(RaidcmdAgent agent, Display display, Text displayText) {
    this.agent = agent;
    this.display = display;
    this.displayText = displayText;
    new Thread(this, "RAID").start();
    }
    /**
     * 一个内部类,主要作用是新开一个线程,把传入的结果写入主窗口的结果框
     * @author admin
     *
     */
    private class Time implements Runnable {
    Text displayText;
    RaidcmdAgent agent;
    //构造函数,对传入的RaidcmdAgent、Text进行赋值
    public Time(RaidcmdAgent agent, Text displayText) {
    this.agent = agent;
    this.displayText = displayText;
    }
    //线程代码,调用通讯类RaidcmdAgent的getResult方法,取得结果,并且把结果存入一个StringBuffer里面,然后写到主窗口结果框
    public void run() {
    Iterator<String> resultList = this.agent.getResult().iterator();
    while (resultList.hasNext()) {
    displayText.setText(resultList.next());
    }
    }
    }
    //主类的线程代码,主要作用是把主类线程永远循环,每次休眠1秒,然后执行内部类Time,并且确定该线程是在主窗口线程空闲的时候运行
    public void run() {
    while(true) {
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    if (!this.display.isDisposed()) {
    runnable = new Time(this.agent, this.displayText);
    }
    display.asyncExec(runnable);
    }
    }
    }