2013-04-06 55 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線程中執行。

相關問題