开发者社区> 问答> 正文

swt UI线程中开启新线程,并将UI组件传入新线程中,报 Invalid thread acces

这是代码

package 下载;

import java.io.File;

public class Window {

 protected Shell shell;
 private Text name;
 private Text info;
 private Text address;
 Button stop,start,goon,giveup;
 ProgressBar progressBar;
 //
 static int len;//线程平均下载文件长度
 static int bn ;//每个线程写入文件的字节数
 static int tn; //线程数
 static String fileName;
 static RandomAccessFile osf; //文件操作

 /**
  * Launch the application.
  * @param args
  */
 public static void main(String[] args) {
  Display display = Display.getDefault();
  Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
   public void run() {
    try {
     Window window = new Window();
     window.open();
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  });
 }

 /**
  * Open the window.
  */
 public void open() {
  Display display = Display.getDefault();
  createContents();
  Add();
  shell.open();
  shell.layout();
  while (!shell.isDisposed()) {
   if (!display.readAndDispatch()) {
    display.sleep();
   }
  }
 }

 /**
  * Create contents of the window.
  */
 protected void createContents() {
  shell = new Shell();
  shell.setSize(796, 543);
  shell.setText("\u4E0B\u8F7D\u5668");
  
  Menu menu = new Menu(shell, SWT.BAR);
  shell.setMenuBar(menu);
  
  MenuItem newdown = new MenuItem(menu, SWT.NONE);
  newdown.addSelectionListener(new SelectionAdapter() {
   @Override
   public void widgetSelected(SelectionEvent e) {
    Test3 test=new Test3();
    test.open();
   }
  });
  newdown.setText("    \u65B0\u5EFA\u4E0B\u8F7D    ");
  
  MenuItem menuItem = new MenuItem(menu, SWT.NONE);
  menuItem.setText("    \u4E0B\u8F7D\u6E05\u5355    ");
  
  CTabFolder tabFolder = new CTabFolder(shell, SWT.BORDER);
  tabFolder.setBounds(0, 10, 770, 475);
  tabFolder.setSelectionBackground(Display.getCurrent().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT));
  
  CTabItem download1 = new CTabItem(tabFolder, SWT.NONE);
  download1.setText("My Download  1");
  
  Composite composite = new Composite(tabFolder, SWT.NONE);
  download1.setControl(composite);
  
  name = new Text(composite, SWT.BORDER | SWT.READ_ONLY);
  name.setBounds(183, 111, 410, 36);
  
  Label lblName = new Label(composite, SWT.SHADOW_IN);
  lblName.setFont(SWTResourceManager.getFont("微软雅黑", 14, SWT.NORMAL));
  lblName.setBounds(73, 107, 93, 36);
  lblName.setText("Name");
  
  info = new Text(composite, SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL | SWT.MULTI);
  info.setBounds(183, 174, 410, 111);
  
  Label lblInfomation = new Label(composite, SWT.NONE);
  lblInfomation.setFont(SWTResourceManager.getFont("微软雅黑", 14, SWT.NORMAL));
  lblInfomation.setBounds(73, 174, 104, 44);
  lblInfomation.setText("Infomation");
  
  progressBar = new ProgressBar(composite, SWT.NONE);
  progressBar.setBounds(183, 300, 410, 27);
  
  Label lblProcess = new Label(composite, SWT.NONE);
  lblProcess.setFont(SWTResourceManager.getFont("微软雅黑", 14, SWT.NORMAL));
  lblProcess.setBounds(73, 300, 104, 27);
  lblProcess.setText("Process");
  
  stop = new Button(composite, SWT.NONE);
  stop.setBounds(248, 364, 80, 27);
  stop.setText("stop");
  
  goon = new Button(composite, SWT.NONE);
  goon.setBounds(377, 364, 80, 27);
  goon.setText("go on");
  
     giveup = new Button(composite, SWT.NONE);
  giveup.setBounds(508, 364, 80, 27);
  giveup.setText("give up");
  
  start = new Button(composite, SWT.NONE);
  start.setBounds(125, 364, 80, 27);
  start.setText("start");
  
  address = new Text(composite, SWT.BORDER);
  address.setBounds(183, 51, 410, 36);
  address.setText("http://im.baidu.com/download/BaiduHi_4.2_Beta.exe");
  
  Label lblAddress = new Label(composite, SWT.NONE);
  lblAddress.setFont(SWTResourceManager.getFont("微软雅黑", 14, SWT.NORMAL));
  lblAddress.setBounds(73, 54, 80, 36);
  lblAddress.setText("Address");
    }
 
 private void Add(){
  start.addSelectionListener(new SelectionAdapter() {
   @Override
   public void widgetSelected(SelectionEvent e) {
    String urlt=address.getText();
    Download(urlt);
   }
  });
 }
    private void Download(String urlt){
     try {
   fileName = "F:\\" + urlt.split("//")[1].split("/")[urlt.split("//")[1].split("/").length-1];
   System.out.println(fileName);
   URL url = new URL(urlt);
   HttpURLConnection http = (HttpURLConnection) url.openConnection();
   /**
    * 此处设定5个线程下载一个文件tn =3;
    * 判断平均每个线程需下载文件长度:
    */
   System.out.println("file size:" + http.getContentLength());
   progressBar.setMaximum(http.getContentLength());
   
      info.append("文件大小"+http.getContentLength()+"\n");
      info.append("主机:" + url.getHost() + "\n");
   info.append("端口:" + url.getDefaultPort() + "\n");
   info.append("网络文件的类型: " + http.getContentType() + "\n");
   info.append("长度:" + http.getContentLength() + "\n");
   info.append("正在下载..."+"\n");
   tn = 5;   
   len = http.getContentLength() / tn ;//舍去余数(余数自动舍去)计算每个线程应下载平均长度,最后一个线程再加上余数,则是整个文件的长度,
   File f = new File(fileName);
   if (f.exists()){
    f.delete();
    osf = new RandomAccessFile(f, "rw");
    osf.seek(http.getContentLength()-1);
    osf.write(0);
   }else{
    osf = new RandomAccessFile(f, "rw");
    osf.seek(http.getContentLength()-1);
    osf.write(0);
   }
   System.out.println("temp 文件长度:" + f.length());
   //下载子线程,
   for (int j = 0; j < tn; j++) {
    Thread t;
    if(j == tn - 1){//如果最后一个线程则加上余数长度字节
     bn = len + (http.getContentLength() % tn);
    }else{
     bn = len;
    }
    System.out.println("t"+ j + "线程下载长度:" + bn + "起始字节:" + len*j);
    info.append("t"+ j + "线程下载长度:" + bn + "起始字节:" + len*j+"\n");
    t = new DT(j,urlt,fileName,len*j,bn,info,progressBar);
    t.start();
   }

  } catch (IOException e) {
   e.printStackTrace();
  }
    }
    protected static void Info(){
     //Info2();
    }
    protected  void Info2(){
     
    }
}

 

import java.util.Date;

import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Text;


public class DT extends Thread {

 String urlt;
 int startl;
 int end;
 String fileName;
 RandomAccessFile osf;
 Text text;
 ProgressBar progressBar;
 public DT(int i ,String url,String fileName,int start,int end,Text text,ProgressBar progressBar){
  this.setName("t"+i); //子线程名称
  this.urlt = url; //下载地址
  this.fileName = fileName;
  this.startl = start; //子线程读取/写入起始字节
  this.end = end;//子线程写入结束字节长度
  this.text=text;
  this.progressBar=progressBar;
 }
 public void run(){
  
   try {
    osf = new RandomAccessFile(fileName, "rw");
    URL url = new URL(urlt);
    HttpURLConnection http2 = (HttpURLConnection) url.openConnection();
    http2.setRequestProperty("User-Agent","NetFox");

http2.setRequestProperty("RANGE", "bytes="+startl+"-");//设置断点位置,向服务器请求从文件的哪个字节开始读取。
    osf.seek(startl);//设置本地文件从哪个字节开始写入
    
    InputStream input = http2.getInputStream();
    byte b[] = new byte[1024];//设置缓冲池,每次只读1024字节
    Date d = new Date();//子线程开始下载时间
    int l;//计算子线程读取和写入的文件长度,当长度大于每个子线程平均下载长度则终止线程
    int i;
    l = 0;
    System.out.println(this.getName() + " 开始下载。。。");
    text.append(this.getName() + " 开始下载。。。"+"\n");

到这就报错了

t1 开始下载。。。
Exception in thread "t1" org.eclipse.swt.SWTException: Invalid thread access
 at org.eclipse.swt.SWT.error(SWT.java:4282)
 at org.eclipse.swt.SWT.error(SWT.java:4197)
 at org.eclipse.swt.SWT.error(SWT.java:4168)
 at org.eclipse.swt.widgets.Widget.error(Widget.java:468)
 at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:359)
 at org.eclipse.swt.widgets.Text.append(Text.java:383)
 at 下载.DT.run(DT.java:66)

展开
收起
kun坤 2020-06-07 20:09:26 680 0
1 条回答
写回答
取消 提交回答
  • 出现Exception in thread "t1" org.eclipse.swt.SWTException: Invalid thread access错误的原因是,你在线程中直接访问的界面组件,你应该在线程中用display.asyncExec(Runnable)去访问,具体的应该是

    text.append(this.getName() + " 开始下载。。。"+"\n");


    这一句写的有问题


    2020-06-07 20:09:51
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Fusion Design - 企业级UI解决方案揭秘 立即下载
多IO线程优化版 立即下载
使用TensorFlow搭建智能开发系统自动生成App UI 立即下载