Search code examples
javaeclipsebindingkeyrcp

eclipse rcp 4 Dialog add Binding Context


how to add a binding context to a Dialog in Eclipse RCP4.

I have defined multiple Binding Contexts to listen for FKeys. The Parts react to the keys pressed but i have no ideas how to add a binding to a Dialog.

I create my Dialog with

ImportDialog dialog = ContextInjectionFactory.make(ImportDialog.class, context);
dialog.open();

Therefore i have access to every Service, what to do to make it send key events to the Binding Contexts?


Solution

  • In your application.e4xmi define a 'Binding Context' for your dialog, make this a child of the 'In Dialogs' Binding Context.

    Add a new 'BindingTable' with the context id set to your new Binding Context. Add the key bindings you want to use in the dialog to this table.

    In your dialog inject the MApplication:

    @Inject
    private MApplication _app;
    

    do not try to inject other services as you will not get the correct instance of the service.

    Add this method to get the correct Eclipse Context for the dialog:

    IEclipseContext getEclipseContext()
    {
      // Must use active leaf from the Application context to get the correct context for key bindings and contexts in dialogs
    
      return _app.getContext().getActiveLeaf();
    }
    

    Override the dialog getShellListener to return a shell listener because we need to wait for the shell to activate before setting up contexts:

    @Override
    protected ShellListener getShellListener()
    {
      return new ActivateShellListener();
    }
    
    private final class ActivateShellListener extends ShellAdapter
    {
      @Override
      public void shellActivated(final ShellEvent e)
      {
        doShellActivated();
      }
    }
    
    void doShellActivated()
    {
      IEclipseContext context = getEclipseContext();
    
      EContextService contextService = context.get(EContextService.class);
    
      contextService.activateContext(ID_CONTEXT);
    
      EHandlerService handlerService = context.get(EHandlerService.class);
    
      handlerService.activateHandler(ID_COMMAND, handler);
    }
    

    where 'ID_CONTEXT' is the binding context id and 'ID_COMMAND' is a command you want to activate a handler for.

    Override close to clean up:

    @Override
    public boolean close()
    {
      IEclipseContext context = getEclipseContext();
    
      EHandlerService handlerService = context.get(EHandlerService.class);
    
      handlerService.deactivateHandler(ID_COMMAND, handler);
    
      EContextService contextService = context.get(EContextService.class);
    
      contextService.deactivateContext(ID_CONTEXT);
    
      return super.close();
    }