2012-10-07 220 views
2

我試圖將剪貼板的內容複製到文本框,但我得到了「無效的線程訪問」消息。從非UI線程訪問UI線程

我在剪貼板上使用了一個偵聽器,如果有一些更改,它會通知我。

我創建了一個新線程來包裝偵聽器,但它似乎無法正常工作。

這裏是代碼:

public class ClipboardDialog extends TitleAreaDialog { 

    // Local attributs 
    private Text mTextClipboardcontent; 


    public ClipboardDialog (Shell parentShell) { 

     super(parentShell); 

    } 


    @Override 
    protected Control createDialogArea(Composite parent) { 

     // Creating display and controls 

     setTitle("ClipBoard content"); 
     Composite area = (Composite) super.createDialogArea(parent); 
     Composite container = new Composite(area, SWT.NONE); 
     container.setLayout(new FormLayout()); 
     GridData gd_container = new GridData(GridData.FILL_HORIZONTAL); 
     // gd_container.grabExcessVerticalSpace = true; 
     gd_container.horizontalAlignment = SWT.LEFT; 
     gd_container.verticalAlignment = SWT.TOP; 
     container.setLayoutData(gd_container); 

     // Group control 
     Group grpInputData = new Group(container, SWT.NONE); 
     FormData fd_grpInputData = new FormData(); 
     fd_grpInputData.bottom = new FormAttachment(0, 303); 
     fd_grpInputData.right = new FormAttachment(0, 467); 
     fd_grpInputData.top = new FormAttachment(0, 5); 
     fd_grpInputData.left = new FormAttachment(0, 5); 
     grpInputData.setLayoutData(fd_grpInputData); 
     grpInputData.setText("Input Data"); 
     GridLayout gl_grpInputData = new GridLayout(4, false); 
     gl_grpInputData.marginLeft = 4; 
     gl_grpInputData.marginHeight = 0; 
     gl_grpInputData.marginWidth = 2; 
     gl_grpInputData.verticalSpacing = 10; 
     gl_grpInputData.horizontalSpacing = 10; 
     grpInputData.setLayout(gl_grpInputData); 
     new Label(grpInputData, SWT.NONE); 
     new Label(grpInputData, SWT.NONE); 
     new Label(grpInputData, SWT.NONE); 
     new Label(grpInputData, SWT.NONE); 
     new Label(grpInputData, SWT.NONE); 


     // Input control 
     mTextClipboardcontent = new Text(grpInputData, SWT.BORDER); 
     GridData gdContent = new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 
       1); 
     gdContent.heightHint = 18; 
     gdContent.widthHint = 250; 
     mTextClipboardcontent.setLayoutData(gdContent); 
     mTextClipboardcontent.setBounds(0, 0, 76, 21); 
     mTextClipboardcontent.setTextLimit(8); 



     new Thread(new Runnable() { 
      public void run() { 
       while (true) { 
        try { 
         Thread.sleep(1000); 
        } catch (Exception e) { 
        } 
        Display.getDefault().syncExec(new Runnable() { 
         public void run() { 

          Toolkit.getDefaultToolkit().getSystemClipboard() 
            .addFlavorListener(new FlavorListener() { 

             @Override 
             public void flavorsChanged(FlavorEvent e) { 

              String result = ""; 
              Clipboard clipboard = Toolkit 
                .getDefaultToolkit() 
                .getSystemClipboard(); 

              Transferable contents = clipboard 
                .getContents(null); 
              boolean hasTransferableText = (contents != null) 
                && contents 
                  .isDataFlavorSupported(DataFlavor.stringFlavor); 

              if (hasTransferableText) { 

               try { 

                // Getting the content of 
                // the ClipBoard 
                result = (String) contents 
                  .getTransferData(DataFlavor.stringFlavor); 

                mTextContent.settext(result); 
               } catch (UnsupportedFlavorException ex) { 

                // Loggin the exception 
                Log.LogError(
                  ex.getClass() 
                    .getCanonicalName(), 
                  ex.getMessage()); 

               } catch (IOException ex) { 


                // Loggin the exception 
                Log.LogError(
                  ex.getClass() 
                    .getCanonicalName(), 
                  ex.getMessage()); 
               } 

              } 
             } 
            }); 

         } 
        }); 
       } 
      } 
     }).start(); 

     return area; 
    } 

    /** 
    * Create contents of the button bar. 
    * 
    * @param parent 
    */ 
    @Override 
    protected void createButtonsForButtonBar(Composite parent) { 
     Button mBtnOK = createButton(parent, IDialogConstants.OK_ID, 
       IDialogConstants.OK_LABEL, true); 
     mBtnOK.setEnabled(false); 
     createButton(parent, IDialogConstants.CANCEL_ID, 
       IDialogConstants.CANCEL_LABEL, false); 
    } 

    /** 
    * Return the initial size of the dialog. 
    */ 
    @Override 
    protected Point getInitialSize() { 
     return new Point(479, 400); 
    } 
} 
+0

你爲什麼把這個問題[AWT]標籤?我可以刪除它嗎? –

+0

是的,你可以!我把它放在剪貼板聽衆 – GoodSpeed

+0

我忘了剪貼板是在awt.datatransfer ...但是,因爲它不是問題的本質,我會讓沒有[awt]標籤的問題。 –

回答

4

你的味道監聽器被稱爲一個線程這不是UI線程。

您需要在Runnable,以執行其代碼傳遞給你的Display使用asyncExec(或syncExec,只要你想)方法:

Toolkit.getDefaultToolkit().getSystemClipboard().addFlavorListener(
    new FlavorListener() { 

    @Override 
    public void flavorsChanged(FlavorEvent e) { 
     Display.getDefault().asyncExec(new Runnable(){ 
      public void run(){ 
       // do things on the UI thread 
       String result = ""; 
       Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 
       Transferable contents = clipboard.getContents(null); 
       ... 
      } 
     } 
    }); 

可運行將在UI線程上執行,從而避免你有錯誤。

請注意,你可能並不需要在UI線程中執行此:

Toolkit.getDefaultToolkit().getSystemClipboard() 
            .addFlavorListener(
+0

我試過了,但沒有工作!我使用Display.getCurrent()。asyncExec(new Runnable(){ \t \t \t public void run(){}); – GoodSpeed

+0

我編輯使其更清晰。問題是flavorListener不在線程註冊表中調用它。 –

+0

非常感謝。有用! – GoodSpeed