|
|
|
|
Re: Where should ISaveHandler be registered? [message #908449 is a reply to message #908426] |
Wed, 05 September 2012 12:07 |
Eclipse User |
|
|
|
If the processor is a "too early" approach you can also use IEventBroker and listen for the initial creation or activation of the window and populate the IEC at this point. You can use IEB.subscribe and supply the topic. Check out the UIEvents class which has all sorts of event topics to hook your code to a specific life cycle event (UILifeCycle) and specific event type (UIEventsType).
|
|
|
Re: Where should ISaveHandler be registered? [message #908487 is a reply to message #908426] |
Wed, 05 September 2012 13:21 |
|
You're right, it would be null at that point...
(IMO) I feel as though that is a bug, but I am not sure how everyone else will feel about this. Please file a bug report detailing what you are experiencing (just what you already posted). I already have a patch in the works and we will see if it is picked up. (it should be) If it is picked up, I wouldn't expect it to be in the SR1.
To get around this for now, treat this as an addon and use @ProcessAdditions.
The one issue we might run into is how the model handles setting the context. The main issue is that the MApplication does not have its context set at that point. So there might be some issues with setting the MApplication context and then adding certain features with processors.
I'll take a look, but please file the bug report and post it here. We'll see what happens.
JD
|
|
|
|
|
|
|
Re: Where should ISaveHandler be registered? [message #909203 is a reply to message #909167] |
Thu, 06 September 2012 18:21 |
|
No you should not file a bug report. As Tom eluded to (and I didn't think of), when a workbench model element receives a context, it is not a context for life. Not every workbench model element will receive a unique context, but for those that do, the context remains valid only as long as it is rendered and its heirarchy does not change.
For now the method Sopot suggested using the event broker is the approach you should use. Something like this:
public class YourProcessor {
@Inject
private IEventBroker eventBroker;
private EventHandler addHandler = new EventHandler() {
@Override
public void handleEvent(Event event) {
if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MWindow))
return;
if (!UIEvents.isCREATE(event))
return;
// do something
}
};
@Execute
protected void init() {
eventBroker.subscribe(UIEvents.Window.TOPIC_ALL, addHandler);
//eventBroker.subscribe(UIEvents.TrimmedWindow.TOPIC_ALL, addHandler);
}
}
|
|
|
|
Re: Where should ISaveHandler be registered? [message #966231 is a reply to message #922724] |
Wed, 31 October 2012 21:29 |
René Brandstetter Messages: 17 Registered: July 2012 |
Junior Member |
|
|
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
}
});
}
}
}
});
}
}
[Updated on: Thu, 01 November 2012 10:14] Report message to a moderator
|
|
|
|
Re: Where should ISaveHandler be registered? [message #1060965 is a reply to message #1060947] |
Wed, 29 May 2013 10:41 |
Thomas Schindl Messages: 6651 Registered: July 2009 |
Senior Member |
|
|
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
>> }
>> });
>> }
>> }
>> }
>> });
>> }
>> }
>
>
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.05839 seconds