2013-04-06 53 views
4

我见过this但它不会对我的代码工作。这是我唯一的类:的Java SWT和无效的线程访问

public static void main(String[] args) { 
     try { 
      Main window = new Main(); 
      window.open(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

public void open() { 
     Display display = Display.getDefault(); 
     createContents(); 
     shell.open(); 
     shell.layout(); 
     while (!shell.isDisposed()) { 
      if (!display.readAndDispatch()) { 
       display.sleep(); 
      } 
     } 
    } 

protected void createContents() { 
     shell = new Shell(SWT.CLOSE | SWT.MIN | SWT.TITLE | SWT.ON_TOP); 
     shell.setSize(301, 212); 
     shell.setText("MyShell"); 
     // ...Other contents... 
     btn = new Button(shell, SWT.NONE); 
     btn.setBounds(114, 151, 76, 25); 
     btn.setText("BUTTON!"); 
     btn.addSelectionListener(new SelectionAdapter() { 
      public void widgetSelected(SelectionEvent e) { 
       doSomething(); 
      } 
     }); 
} 

方法doSomething()是另一种方法的调用者,就像这样:

private void doSomething() 
{ 
    Thread th = new Thread() { 
     public void run() { 
     threadMethod(); 
     } 
    }; 
    th.start(); 
} 

当我点击我的按钮,“无效的线程访问”从线程0提高和它指向的threadMethod()第一个指令(至极不访问到UI窗口小部件)。我试图围绕我的按钮侦听器

Display.getDefault().asyncExec(new Runnable() { 
    public void run() { 
     // ... 
    } 
}); 

但它也不起作用。我需要doSomething()方法,因为它在创建线程之前会检查一些代码。 这是threadMethod()

private void threadMethod() 
    { 
     String[] listItems = list.getItems(); 
     String fileName; 
     Path source, target; 
     File folder = new File(dir + File.separator); 
     if (!folder.exists()) { 
      folder.mkdir(); 
     } 
     try 
     { 
      for(int i = 0; i < list.getItemCount(); i++) 
      { 

       // do something with non UI widgets 
      } 

      list.removeAll(); 

     } 
     catch(IOException | InterruptedException e) 
     { 
      //print error 

     } 
    } 

为什么我有无效的线程访问?谢谢!

+0

是什么'threadMethod()'做什么? – 2013-04-06 13:41:05

+0

你是对的问它做了什么,我省略了它! – Angelo 2013-04-06 13:46:46

+0

什么是列表中的字符串[] listItems = list.getItems();' – 2013-04-06 13:49:26

回答

6

List是一个SWT小部件,如果你在UI线程之外调用getItems()方法(在这里是你的主线程),你会得到一个ERROR_THREAD_INVALID_ACCESS SWTException。这在List API中定义:ERROR_THREAD_INVALID_ACCESS - 如果未从创建接收器的线程调用

创建接收器的线程是创建显示的线程。如果Display不存在,则第一次调用Display.getDefault()将创建一个。因此,调用open()方法的主线程是UI线程。如果您将threadMethod()的内容包装起来,您的代码将会工作:

private void threadMethod() { 
    Display.getDefault().asyncExec(new Runnable() { 
     public void run() { 
      // threadMethod contents 
     } 
    }); 
} 

然后它将在UI线程中执行。

相关问题