Eclipse plugin 在插件启动期间,执行UI相关操作的正确方法是什么

Eclipse plugin 在插件启动期间,执行UI相关操作的正确方法是什么,eclipse-plugin,eclipse-rcp,Eclipse Plugin,Eclipse Rcp,我需要执行UI操作,如“删除eclipse默认菜单”、“注册IWindowCloseHandler”和“添加IWorkbenchListener”等 所有上述操作都是在pluginstart()方法中完成的 start(BundleContext){ .... Display.getDefault().syncExec(新的Runnable()){ @凌驾 公开募捐{ //禁用/删除eclipse默认菜单项,如编辑、运行等 //寄存器工作台寄存器 最终IWorkbench workbench=P

我需要执行UI操作,如“删除eclipse默认菜单”、“注册IWindowCloseHandler”和“添加IWorkbenchListener”等

所有上述操作都是在plugin
start()
方法中完成的

start(BundleContext){
....
Display.getDefault().syncExec(新的Runnable()){
@凌驾
公开募捐{
//禁用/删除eclipse默认菜单项,如编辑、运行等
//寄存器工作台寄存器
最终IWorkbench workbench=PlatformUI.getWorkbench();
最终IWorkbenchPage activePage=workbench.getActiveWorkbenchWindow().getActivePage();
workbench.getActiveWorkbenchWindow().addPerspectiveListener(pHandler);
workbench.addWorkbenchListener(新的IWorkbenchListener(){
@凌驾
公共布尔值预关闭(IWorkbench工作台,布尔值强制){
activePage.CloseEditor(activePage.getEditorReferences(),true);
返回true;
}
});     
//寄存器关闭处理程序
registerExitHandler();
}
}); 
}
公共类导出器{
公共静态无效registerExitHandler(){
WorkbenchWindow activeWorkbenchWindow=(WorkbenchWindow)平台ui.getWorkbench().getActiveWorkbenchWindow();
if(activeWorkbenchWindow!=null){
MWindow window=activeWorkbenchWindow.getModel();
如果(窗口!=null){
window.getContext().set(IWindowCloseHandler.class,新的IWindowCloseHandler()){
@凌驾
公共布尔关闭(MWindow窗口){
//退出逻辑涉及用户界面;
}
});
}
}
}
} 
有时,对于Display.asynceec()/syncExec()中引用的许多类,我会遇到以下异常:

执行这些操作的正确位置是什么

  • 在org.eclipse.ui.IStartup的earlyStartUp()中,或
  • 在org.osgi.framework.BundleListener的bundleChanged()中或在lifecycle类中
  • 我对以上两种选择表示怀疑!!还有其他合适的选择吗

  • 观察:当我的品牌插件发生更改时,会观察到上述问题,否则加载工作正常

    使用
    IStartup
    方法,但您需要使用
    Display.asyncExec
    延迟代码的运行,直到工作台启动完成:

    public void earlyStartup()
    {
    Display.getDefault().asyncExec(新的Runnable()){
    @凌驾
    公开募捐{
    //在这里执行您的代码
    }
    });
    }
    
    避免这种情况的一种方法是将所有代码放在激活代码的末尾,这样就可以在不加载其他类的情况下快速退出

    最好使用aysnc执行,因为包激活线程将立即返回并进入活动状态,否则包激活线程将被阻塞,直到您的服务结束

    Start(BundleContext context) {
     ....
    // this is my last call in the start() method
    Display.getDefault().syncExec(new Runnable() {
     @Override
     public void run() {
        //UI logic to disable 
        }
      }
    } 
    

    我遵循以下方法来解决上述问题:

  • 菜单enable/disable已经在我的视图的init()中完成,它在我的包启动后被加载
  • 在bundle启动后,正在我的BundleListener中注册诸如“IWindowCloseHandler”和“IWorkbenchListener”等侦听器

    public class StudioBundleListener implements BundleListener {
     @Override
       public void bundleChanged(BundleEvent event) {
       String symbolicName = event.getBundle().getSymbolicName();
       int type = event.getType();
       if(symbolicName.equals(MYPlugin.PLUGIN_ID) && type == BundleEvent.STARTED) {
         //Register your listeners
       }
      }
    }
    

  • 捆绑包激活代码末尾的IStartup和async()仍然会导致类加载问题,如问题部分所述。

    感谢您的回复!我有一个StudioStartup实现IStartup的类,其中实现了earlyStartup()。有几次我在加载类“StudioStartup”时收到“!MESSAGE”,线程“thread[main,6,main]”在等待线程“thread[thread-6,5,main]”完成启动bundlename包时超时(5011ms)。为了避免死锁,线程“thread[main,6,main]”正在继续,但“StudioStartup”可能没有完全初始化。eclipse没有启动。不过,这个问题在很大程度上是断断续续的。
    public class StudioBundleListener implements BundleListener {
     @Override
       public void bundleChanged(BundleEvent event) {
       String symbolicName = event.getBundle().getSymbolicName();
       int type = event.getType();
       if(symbolicName.equals(MYPlugin.PLUGIN_ID) && type == BundleEvent.STARTED) {
         //Register your listeners
       }
      }
    }