3

How can I implement IWindowCloseHandler in order to display a MessageDialog before closing the application ?

Here is my code :

EDIT

public class LifeCycle {    

 @PostContextCreate
 public void postContextCreate()
  {
    // TODO start up code here

     System.out.println("open");

  }

 @ProcessAdditions
  void processAdditions(MApplication app, EModelService modelService)
  {
     WindowCloseHandler closeHandler=new WindowCloseHandler();
    MWindow window = (MWindow)modelService.find("uploadcenter.source.trimmedwindow.0", app);
    window.getContext().set(IWindowCloseHandler.class, closeHandler);
  }
 private static class WindowCloseHandler implements IWindowCloseHandler{

    @Override
    public boolean close(MWindow window) {
        // TODO Auto-generated method stub
        Shell shell = new Shell();

        if (MessageDialog.openConfirm(shell, "Confirmation",
                "Do you want to exit?")) {
            return true;
        }
        return false;
    } 
 }

}

Ismail

Ismail Sen
  • 571
  • 2
  • 14
  • 27
  • If this is a pure e4 application you can't use PlatformUI. – greg-449 Mar 04 '14 at 16:55
  • Okay @greg-449, I can understand better e4 RCP app now. So , in my latest edit, I'm using `EModelService` and `MApplication` to find the main window of my app and I got my window in `processAddictions()`. The LifeCycle class is in the `plugin.xml`. Now , I just need to pass the window to the `close` method, but I can't, what am I missing to do this last step ? – Ismail Sen Mar 05 '14 at 07:57
  • As I already said you put the `IWindowCloseHandler` in the window context and Eclipse will call the `close` method when it is needed. You must wait until the app startup event fires to put the entry in the context. I have updated the answer to match your code – greg-449 Mar 05 '14 at 08:10
  • I couldn't see yout updates (sorry), I was editing at the same time I guess. I've added new modification too . . . I'm getting `NullPointerException` here : `window.getContext().set(IWindowCloseHandler.class, closeHandler);`. Does my new edits correct ? Why I'm getting `NullPointerException` ? . Sorry again for not seeing your edits – Ismail Sen Mar 05 '14 at 08:22
  • The context is not yet set up when `@ProcessAdditions` is called, you **must** do this in the app startup complete event as I have shown. – greg-449 Mar 05 '14 at 08:25

2 Answers2

6

The IWindowCloseHandler must be registered in the Eclipse context (IEclipseContext) for the MWindow which you want to control.

MWindow window = get the window

window.getContext().set(IWindowCloseHandler.class, handler);

If you want to set this up in the LifeCycle class there is a bit of work to do because the life cycle methods are called too early in the application start up to be able to set the value in the context directly. It is necessary to wait for the app startup complete event:

public class LifeCycle
{
  @ProcessAdditions
  public void processAdditions(IEventBroker eventBroker, MApplication app, EModelService modelService)
  {
     MWindow window =(MWindow)modelService.find("uploadcenter.source.trimmedwindow.0", app);

     eventBroker.subscribe(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE, 
                          new AppStartupCompleteEventHandler(window));
  }


  private static class AppStartupCompleteEventHandler implements EventHandler
  {
    private MWindow theWindow;

    AppStartupCompleteEventHandler(MWindow window)
    {
       theWindow = window;
    }


    @Override
    public void handleEvent(final Event event)
    {
      theWindow.getContext().set(IWindowCloseHandler.class, handler);        
    }
  }
}
greg-449
  • 109,219
  • 232
  • 102
  • 145
  • I want to control the main window. So to get it , i did : `MWindow window= (MWindow) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();`. And now, `LifeCycle` class is a normal class (not anymore in the `plugin.xml`. Now , I can't `getContext` ! . Please, see my edit . – Ismail Sen Mar 04 '14 at 16:39
  • 1
    You `LifeCycle` must still be declared in the plugin.xml as the life cycle class. You can't use PlatformUI, you must find the window using `EModelService`. – greg-449 Mar 04 '14 at 18:08
  • I can't use `IEventBroker` and no import is suggested, same for `EventHandler` – Ismail Sen Mar 05 '14 at 08:34
  • 1
    `IEventBroker` is in the `org.eclipse.e4.core.services` plugin – greg-449 Mar 05 '14 at 08:37
  • `EventHandler` is in `org.eclipse.osgi.services` – greg-449 Mar 05 '14 at 08:38
  • Thank you @greg-449 , it's working now. I'm finally getting the `MessageDialog`. Your indications were very important in both questions I've posted to find the solution. – Ismail Sen Mar 05 '14 at 09:09
1

A variation on @greg-449's answer using dependency injection and annotation. Register this class as an addon in your Application.e4xmi.

public class ExampleWindowCloseAddon implements IWindowCloseHandler
{
    @Inject
    @Optional
    public void startupComplete(@UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) MApplication application,
            EModelService modelService)
    {
        MWindow window = (MWindow) modelService.find("my.window.id", application);
        window.getContext().set(IWindowCloseHandler.class, this);
    }

    @Override
    public boolean close(MWindow window)
    {
        // Your code goes here
        return true;
    }
}
Jon Iles
  • 2,519
  • 1
  • 20
  • 30
  • Tried this, but `window.getContext().set(...)` crashed because `getContext()` returned null. Any ideas what might be the problem? I am using the Eclipse Kepler release 4.3.1. – skowski Nov 12 '14 at 08:24
  • @skowski are you sure your window.id exists. – kdoteu Dec 30 '14 at 13:19