2012-10-07 184 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