Where should ISaveHandler be registered? [message #903559] |
Fri, 24 August 2012 06:42  |
Eclipse User |
|
|
|
I am working on a e4-based RCP application and I am not very happy with the default dialog for saving parts.
I understand that I have to put a custom ISaveHandler (and/or IWindowCloseHandler) in the context of the MWindow. Lars Vogel gave an example where he registered a IWindowCloseHandler from within a handler method (annotated with @Execute), see [1].
The questions is where or how should I trigger that handler so that the IWindowCloseHandler get registered automatically when the application starts up?
Other things I tried is set the IWindowCloseHandler from a life cycle handler (@PostContextCreate) and from an Addon that listens for new windows being created. Form what I can say both seems to happen too soon, i.e. the IWindowCloseHandler seems to get overwritten later by the framework.
[1] (I am not allowed to link to H T T P : //) www.vogella.com/articles/EclipseRCP/article.html#context_who
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Re: Where should ISaveHandler be registered? [message #1060965 is a reply to message #1060947] |
Wed, 29 May 2013 06:41   |
Eclipse User |
|
|
|
The addon context only holds the MApplication instance! You could in
there traverse the windows but the problem is that at this point the
IEclipseContext has not been created.
The strategy to use is that your addon registers itself as a listener on
the event-bus to detect when the IEclipseContext has been set and the
push in this context the respective handler.
Tom
On 29.05.13 11:27, Uti Devel wrote:
> Hi,
>
> i'm fairly new to RCP4 so i'm still trying to figure out how to connect
> all the odds and ends. If i take the code from above, what to do with
> it? I tried to register the QuitProcessor as an addon so it gets loaded
> on startup. Now a get the following exception:
>
> !ENTRY org.eclipse.e4.ui.workbench 4 0 2013-05-29 11:18:48.886
> !MESSAGE Unable to create class
> 'com.test.application.addons.QuitProcessor' from bundle '68'
> !STACK 0
> org.eclipse.e4.core.di.InjectionException: Could not find satisfiable
> constructor in com.test.application.addons.QuitProcessor
> at
> org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:330)
>
> at
> org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:255)
> at
> org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:185)
>
> at
> org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.createFromBundle(ReflectionContributionFactory.java:105)
>
> at
> org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.doCreate(ReflectionContributionFactory.java:71)
>
> at
> org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.create(ReflectionContributionFactory.java:49)
>
> at
> org.eclipse.e4.ui.internal.workbench.swt.E4Application.createE4Workbench(E4Application.java:258)
>
> at
> org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:132)
>
> at
> org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
>
> at
> org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
>
> at
> org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
>
> at
> org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
>
> at
> org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
>
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>
> at java.lang.reflect.Method.invoke(Method.java:601)
> at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
> at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
> at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
> at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
>
> I think the model is not created by now, so the window can not be found.
> How to delay the creation of the Processor?
>
> Thank You
>
> René Brandstetter wrote on Wed, 31 October 2012 17:29
>> Hi Markus,
>>
>> it's still a hack put with this processor you should be able to
>> replace the default IWindowCloseHandler from WBWRenderer with your own
>> impl.
>>
>>
>> package com.test.application.addons;
>>
>> import javax.inject.Inject;
>> import javax.inject.Named;
>>
>> import org.eclipse.e4.core.contexts.IEclipseContext;
>> import org.eclipse.e4.core.contexts.RunAndTrack;
>> import org.eclipse.e4.core.di.annotations.Execute;
>> import org.eclipse.e4.core.services.events.IEventBroker;
>> import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
>> import org.eclipse.e4.ui.workbench.UIEvents;
>> import org.eclipse.e4.ui.workbench.modeling.IWindowCloseHandler;
>> import org.osgi.service.event.Event;
>> import org.osgi.service.event.EventHandler;
>>
>> @SuppressWarnings("restriction")
>> public class QuitProcessor {
>> private final MWindow window;
>> private final IEventBroker eventBroker;
>> @Inject
>> public
>> QuitProcessor(@Named("at.renbrand.sentinel.mainWindow")MWindow window,
>> IEventBroker eventBroker){
>> this.window = window;
>> this.eventBroker = eventBroker;
>> }
>> @Execute
>> void installIntoContext(){
>> eventBroker.subscribe(UIEvents.Context.TOPIC_CONTEXT, new
>> EventHandler(){
>>
>> @Override
>> public void handleEvent(Event event) {
>> if( UIEvents.isSET(event) ){
>> if( window.equals( event.getProperty("ChangedElement") ) &&
>> window.getContext() != null ){
>> // use RunAndTrack to get notified after the
>> IWindowCloseHanlder was changed in the IEclipseContext
>> window.getContext().runAndTrack(new RunAndTrack(){
>> private final IWindowCloseHandler quitHandler = new
>> QuitHandler();
>>
>> @Override
>> public boolean changed(IEclipseContext context) {
>> Object value =
>> context.get(IWindowCloseHandler.class); // access the context value
>> to be reevaluated on every future change of the value
>> if(!quitHandler.equals(value)){ // prevents endless loop
>> context.set(IWindowCloseHandler.class, quitHandler);
>> }
>> return true; // ture keeps tracking and the
>> quitHandler as the only opportunity
>> }
>> });
>> }
>> }
>> }
>> });
>> }
>> }
>
>
|
|
|
|
|
Re: Where should ISaveHandler be registered? [message #1061421 is a reply to message #1061166] |
Fri, 31 May 2013 10:30  |
Eclipse User |
|
|
|
Hi Dennis,
as I wrote it's a "Hack" because as far as I can remember there was a problem with specifing the IWindowCloseHandler after the application has already been started and so that's the reason for the event registration stuff.
During the startup of the application the IWindowCloseHandler will be hardcoded overwritten by some unaccessible (internal private) platform code. So I used the functionality of the RunAndTrack method to set the custom QuitHandler again as soon as the IWindowCloseHandler becomes overwritten by the platform code.
If you take a look at the JavaDoc of the RunAndTrack class you will see that the changed() method is only called if a variable which is accessed during the changed() method changes again. This means that the changed() method in this example will only be triggered again if the IWindowCloseHandler variable in the context changes. So it's not a change of the handler every time you change something in the context.
I hope you understand the RunAndTrack thing I wanted to explain. Sorry, my english isn't that good so if you have any further questions take a look at Lars Blog http://www.vogella.com/articles/EclipseRCP/article.html#extentcontext_turnandtrack . But be careful the last paragraph of the chapter isn't correct (I've already told him) the RunAndTrack isn't stopped if you do not access any values it is stopped if the changed() method return false and goes on tracking if it returns true.
René
|
|
|
Powered by
FUDForum. Page generated in 0.32379 seconds