2009-10-20 69 views
0

因此,我正在开发一个工作插件,并且遇到了一个可以使用ContentProposalAdapter的好处。基本上,一个人会开始输入某人的姓名,然后一个匹配当前查询的姓名列表将以提前输入的方式返回(la )。所以,我创建了一个IContentProposalProvider类,它在调用它的getProposals()方法时触发了一个处理在后台获取提议的线程。我遇到的问题是我遇到了一个竞争条件,在那里通过HTTP获取提议的处理发生,并且我试图在他们实际检索之前获得提议。如何从互联网填充JFace ContentProposalAdapter?

现在,我试图不遇到线程地狱的问题,而且这不会让我走得太远。所以,这是我迄今为止所做的。有人对我能做什么有任何建议吗?

public class ProfilesProposalProvider implements IContentProposalProvider, PropertyChangeListener { 

    private IContentProposal[] props; 

    @Override 
    public IContentProposal[] getProposals(String arg0, int arg1) { 
     Display display = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().getDisplay(); 

     RunProfilesJobThread t1 = new RunProfilesJobThread(arg0, display); 
     t1.run(); 

     return props; 
    } 

    @Override 
    public void propertyChange(PropertyChangeEvent arg0) { 
     if (arg0.getSource() instanceof RunProfilesJobThread){ 
     RunProfilesJobThread thread = (RunProfilesJobThread)arg0.getSource(); 
     props = thread.getProps(); 

     } 
    } 
    } 



public class RunProfilesJobThread extends Thread { 

private ProfileProposal[] props; 
private Display display; 
private String query; 

public RunProfilesJobThread(String query, Display display){ 
    this.query = query; 
} 

@Override 
public void run() { 
    if (!(query.equals(""))){ 
    GetProfilesJob job = new GetProfilesJob("profiles", query); 
    job.schedule(); 

    try { 
    job.join(); 
    } catch (InterruptedException e) { 
    e.printStackTrace(); 
    } 

    GetProfilesJobInfoThread thread = new GetProfilesJobInfoThread(job.getResults()); 

    try { 
    thread.join(); 
    } catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 


    props = thread.getProps(); 
    } 
} 

public ProfileProposal[] getProps(){ 
    return props; 
} 
} 

public class GetProfilesJobInfoThread extends Thread { 

    private ArrayList<String> names; 
    private ProfileProposal[] props; 

    public GetProfilesJobInfoThread(ArrayList<String> names){ 
     this.names = names; 
    } 

    @Override 
    public void run() { 
     if (names != null){ 
     props = new ProfileProposal[names.size()]; 
     for (int i = 0; i < props.length - 1; i++){ 
     ProfileProposal temp = new ProfileProposal(names.get(i), names.get(i)); 
     props[i] = temp; 
     } 
     } 
    } 

    public ProfileProposal[] getProps(){ 
     return props; 
    } 
    } 

回答

0

好吧,我来试试......

我还没有尝试运行它,但它应该工作或多或少。至少这是一个好的开始。如果你有任何问题随时问。

public class ProfilesProposalProvider implements IContentProposalProvider { 
    private List<IContentProposal> proposals; 
    private String proposalQuery; 
    private Thread retrievalThread; 

    public void setProposals(List<IContentProposal> proposals, String query) { 
     synchronized(this) { 
      this.proposals = proposals; 
      this.proposalQuery = query; 
     } 
    } 

    public IContentProposal[] getProposals(String contents, int position) { 
     // Synchronize incoming thread and retrieval thread, so that the proposal list 
     // is not replaced while we're processing it. 
     synchronized(this) { 
      /** 
      * Get proposals if query is longer than one char, or if the current list of proposals does with a different 
      * prefix than the new query, and only if the current retrieval thread is finished. 
      */ 
      if (retrievalThread == null && contents.length() > 1 && (proposals == null || !contents.startsWith(proposalQuery))) { 
       getProposals(contents); 
      } 

      /** 
      * Select valid proposals from retrieved list. 
      */ 
      if (proposals != null) { 
       List<IContentProposal> validProposals = new ArrayList<IContentProposal>(); 
       for (IContentProposal prop : proposals) { 
        if(prop == null) { 
         continue; 
        } 
        String propVal = prop.getContent(); 
        if (isProposalValid(propVal, contents)) { 
         validProposals.add(prop); 
        } 
       } 
       return validProposals.toArray(new IContentProposal[ validProposals.size() ]); 
      } 
     } 

     return new IContentProposal[0]; 
    } 

    protected void getProposals(final String query) { 
     retrievalThread = new Thread() { 
      @Override 
      public void run() { 
       GetProfilesJob job = new GetProfilesJob("profiles", query); 
       job.schedule(); 

       try { 
        job.join(); 

        ArrayList<String> names = job.getResults(); 
        if (names != null){ 
         List<IContentProposal> props = new ArrayList<IContentProposal>(); 
         for (String name : names) { 
          props.add(new ProfileProposal(name, name)); 
         } 
         setProposals(props, query); 
        } 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       retrievalThread = null; 
      } 
     }; 
     retrievalThread.start(); 
    } 

    protected boolean isProposalValid(String proposalValue, String contents) { 
     return (proposalValue.length() >= contents.length() && proposalValue.substring(0, contents.length()).equalsIgnoreCase(contents)); 
    } 
}