我想在一个java.util.TimerTask 类里根据条件来改变界面类的LABLE的TEXT属性 
我把改变LABLE的TEXT属性的方法放在构造函数里没问题,但放在RUN方法里却不行..求教高手..public void run() {
this.authenticate(); 
if (iAuthenticate != 1) {
readCardStatus.setStatusNum(92);//此处为改变LABLE的TEXT属性的方法,放在构造函数里没有错
}else{
readCardStatus.setStatusNum(100);//此处为改变LABLE的TEXT属性的方法,,放在构造函数里没有错
this.read();
String info = this.readfile();
System.out.println(info);
}
}报一下错误
Exception in thread "Timer-0" org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:3777)
at org.eclipse.swt.SWT.error(SWT.java:3695)
at org.eclipse.swt.SWT.error(SWT.java:3666)
at org.eclipse.swt.widgets.Widget.error(Widget.java:463)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:355)
at org.eclipse.swt.widgets.Label.setText(Label.java:375)
at net.pyp.readCardClient.views.ReadCardView.changeStatus(ReadCardView.java:137)
at com.readCardSystem.read.ReadCardStatus.setStatusNum(ReadCardStatus.java:48)
at com.readCardSystem.read.ReadCardTask.run(ReadCardTask.java:76)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)是不是当Timer线程启动后他就不能改变界面程的控件属性?

解决方案 »

  1.   

    只是提示你当前线程不可见  应该是你启动线程的地方有问题了  ,简单点 用timer 在构造方法里启动timer
    int delay = 1000; //milliseconds
      ActionListener taskPerformer = new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
              //...Perform a task...
          }
      };
      new Timer(delay, taskPerformer).start();
      

  2.   

    在任何操作平台的GUI系统中,对构件或一些图形API的访问操作都要被严格同步并串行化。例如,在一个图形界面中的按键构件可被设成可用状态 (enable)或禁用状态(disable),正常的处理方式是,用户对按键状态设置操作都要被放入到GUI系统的事件处理队列中(这意味着访问操作被串行化),然后依次处理(这意味着访问操作被同步)。想象当按键可用状态的设置函数还没有执行结束的时候,程序就希望再设置该按键为禁用状态,势必会引起冲突。实际上,这种操作在任何GUI系统都会触发异常。Java语言本身就提供了多线程机制,这种机制对GUI编程来说是不利的,它不能保证图形构件操作的同步与串行化。SWT采用了一种简单而直接的方式去适应本地GUI系统对线程的要求:在SWT中,通常存在一个被称为"用户线程" 的唯一线程,只有在这个线程中才能调用对构件或某些图形API的访问操作。如果在非用户线程中程序直接调用这些访问操作,那么SWTExcepiton异常会被抛出。但是SWT也在*.widget.Display类中提供了两个方法可以间接的在非用户线程的进行图形构件的访问操作,这是通过的 syncExec(Runnable)和asyncExec(Runnable)这两个方法去实现的。例如://此时程序运行在一个非用户线程中,并且希望在构件panel上加入一个按键。
    Display.getCurrent().asyncExec(new Runnable() {
        public void run() {
            Button butt = new Button(panel,SWT.PUSH);
            butt.setText("Push");
        }
    });方法syncExec()和asyncExec()的区别在于前者要在指定的线程执行结束后才返回,而后者则无论指定的线程是否执行都会立即返回到当前线程。