Skip to main content



      Home
Home » Eclipse Projects » Eclipse 4 » How to forestall the window closing(Life cycle)
How to forestall the window closing [message #922580] Tue, 25 September 2012 02:17 Go to next message
Eclipse UserFriend
I need (I think not only I am) to handle a moment when the main window (or application) can be closed and to cancel this attempt if it is necessary. In eclipse 3.x it was the method

boolean preWindowShellClose()

in WorkbenchWindowAdvisor class. It was enough convenient.

For parts there are URI classes with life cycle methods with annotations such as @PostConstruct. I hoped that similar classes should be for application and windows too. But it is not provided for.

Some articles recommends to use IWindowCloseHandler added to window context. But it is ununderstandable when it is possible to add this interface. In every case when the application starts, the window context is equal to null.

In result I have added this interface in the @PostConstruct method of URI class of one of parts. But I think it is not competent way.

Do you know the correct solution for such cases?
Re: How to forestall the window closing [message #922673 is a reply to message #922580] Tue, 25 September 2012 04:17 Go to previous messageGo to next message
Eclipse UserFriend
In an addon, you can listen for a window creation event through the IEventBroker and after the window is created, put the handler in it's context.
Re: How to forestall the window closing [message #922760 is a reply to message #922673] Tue, 25 September 2012 05:55 Go to previous messageGo to next message
Eclipse UserFriend
Sopot Cela wrote on Tue, 25 September 2012 04:17
In an addon, you can listen for a window creation event through the IEventBroker and after the window is created, put the handler in it's context.


Thank you for your answer. But would you show example of code which I should to put into the class of such addon?
Re: How to forestall the window closing [message #922841 is a reply to message #922760] Tue, 25 September 2012 07:44 Go to previous messageGo to next message
Eclipse UserFriend
Since context lookups go up the parent chain, you can put your IWindowCloseHandler in the application's context at @PostContextCreate.

Brian.
Re: How to forestall the window closing [message #922846 is a reply to message #922841] Tue, 25 September 2012 07:47 Go to previous messageGo to next message
Eclipse UserFriend
I think it will be overriden by the window renderer and the lookup will stop in the window level with the default handler. It's a guess though as I haven't tried this myself.
Re: How to forestall the window closing [message #922856 is a reply to message #922846] Tue, 25 September 2012 07:58 Go to previous messageGo to next message
Eclipse UserFriend
Correct we are pushing the closeHandler in the WBWRenderer:

> private void setCloseHandler(MWindow window) {
> IEclipseContext context = window.getContext();
> // no direct model parent, must be a detached window
> if (window.getParent() == null) {
> context.set(IWindowCloseHandler.class.getName(),
> new IWindowCloseHandler() {
> public boolean close(MWindow window) {
> return closeDetachedWindow(window);
> }
> });
> } else {
> context.set(IWindowCloseHandler.class.getName(),
> new IWindowCloseHandler() {
> public boolean close(MWindow window) {
> EPartService partService = (EPartService) window
> .getContext().get(
> EPartService.class.getName());
> return partService.saveAll(true);
> }
> });
> }
> }



Tom

Am 25.09.12 13:47, schrieb Sopot Cela:
> I think it will be overriden by the window renderer and the lookup will
> stop in the window level with the default handler. It's a guess though
> as I haven't tried this myself.
Re: How to forestall the window closing [message #922894 is a reply to message #922841] Tue, 25 September 2012 08:38 Go to previous messageGo to next message
Eclipse UserFriend
No Message Body

[Updated on: Tue, 25 September 2012 08:39] by Moderator

Re: How to forestall the window closing [message #922951 is a reply to message #922580] Tue, 25 September 2012 09:36 Go to previous messageGo to next message
Eclipse UserFriend
Hi Guys

I spent some time with this today and as far as I can see now, it's not easy to set up your own IWindowCloseHandler.

The problem is that, in WBWRenderer the IEclipseContext is added to the element before the the default IWindowCloseHandler is set. That means, that listening to the Context-SET-Event doesn't work, since the IWindowCloseHandler will be overwritten.

(The same thing is true for the Widget-SET-event, so that doesn't work either.)

Does anyone have any suggestions, or should I open a bug for this?

Greetings
Christoph

[Updated on: Tue, 25 September 2012 09:51] by Moderator

Re: How to forestall the window closing [message #922955 is a reply to message #922951] Tue, 25 September 2012 09:39 Go to previous messageGo to next message
Eclipse UserFriend
How about listening on a window being added to the application and put your handler at that moment? This should override the default.
Re: How to forestall the window closing [message #922960 is a reply to message #922951] Tue, 25 September 2012 09:43 Go to previous messageGo to next message
Eclipse UserFriend
Hello again

This workaround will probably work for most cases. This Addon will listen to the creation of a part and overwrite its Parent-Windows IWindowCloseHandler.

It isn't ideal, since it implies that:
1) A Part will be created
2) The Part is created after the Window

public class WindowCloseHandlerAddon {
	private static final Logger logger = LoggerFactory.getLogger(WindowCloseHandlerAddon.class);
	@Inject private IEventBroker eventBroker;
	
	private EventHandler handler = new EventHandler() {
		@Override
		public void handleEvent(Event event) {
			if (!UIEvents.isSET(event))
				return;
			Object origin = event.getProperty(UIEvents.EventTags.ELEMENT);
			if (!(origin instanceof MPart))
				return;
			MPart contextPart = (MPart) origin;
			MWindow contextWindow = contextPart.getContext().get(MWindow.class);
			IEclipseContext eclipseContext = contextWindow.getContext();

			logger.info("Placing IWindowCloseHandler in window {}", contextWindow.getElementId()); //$NON-NLS-1$
			eclipseContext.set(IWindowCloseHandler.class, new IWindowCloseHandler() {
				@Override
				public boolean close(MWindow windowParam) {
					logger.info("My IWindowCloseHandler was called for window: {}", windowParam.getElementId()); //$NON-NLS-1$
					return true;
				}
			});
			eventBroker.unsubscribe(this);
		}
	};
	
	@PostConstruct
	public void init() {
		//String topic = UIEvents.Context.TOPIC_CONTEXT;
		String topic = UIEvents.UIElement.TOPIC_WIDGET;
		eventBroker.subscribe(topic, handler);
	}
}


Hope this helps.
Christoph

[Updated on: Tue, 25 September 2012 09:52] by Moderator

Re: How to forestall the window closing [message #922969 is a reply to message #922955] Tue, 25 September 2012 09:50 Go to previous messageGo to next message
Eclipse UserFriend
Sopot Cela wrote on Tue, 25 September 2012 15:39
How about listening on a window being added to the application and put your handler at that moment? This should override the default.


Hi Sopot

I don't think there is an event for that. Listening to all ADD-Events only gets triggerd when a tag is added to an ApplicationElement.
eventBroker.subscribe("org/eclipse/e4/ui/*", new EventHandler() {
	@Override
	public void handleEvent(Event event) {
		if (!UIEvents.isADD(event))
			return;
		logger.info("Event: {}, Origin: {}", event, event.getProperty(UIEvents.EventTags.ELEMENT)); //$NON-NLS-1$
	}
});

Or am I missing something?

Greetings
Christoph
Re: How to forestall the window closing [message #922990 is a reply to message #922969] Tue, 25 September 2012 10:19 Go to previous messageGo to next message
Eclipse UserFriend
Then we can fall back to the activation of the window.

@Inject
	@Optional
	public void test(@UIEventTopic(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT) Event o ){
		
		if (o!=null) {
			Object mui = o.getProperty(UIEvents.EventTags.ELEMENT);
			if ((mui instanceof MApplication))
					
			{
			MWindow win = (MWindow) o.getProperty(UIEvents.EventTags.NEW_VALUE);
			System.err.println(win);
			}
			
		}
		
	}
Re: How to forestall the window closing [message #923022 is a reply to message #922990] Tue, 25 September 2012 10:44 Go to previous messageGo to next message
Eclipse UserFriend
Hi Sopot

Listening to the SET of the selectedElement-Attribute might not work, if it has already been set in the model (either in the *.e4xmi or the persisted workbench.xml), since in this case application.setSelectedElement(window) does not need to be called. I'm not sure though ... at least it will depend on the internal implementation.

Greetings
Christoph
Re: How to forestall the window closing [message #923091 is a reply to message #923022] Tue, 25 September 2012 11:40 Go to previous messageGo to next message
Eclipse UserFriend
My current (also not very beautiful) solution:

public class LifeCycleManager {
	private ISaveHandler saveHandler;
	private IWindowCloseHandler windowCloseHandler;

	private final HashSet<MWindow> processed = new HashSet<MWindow>();

	private final EventHandler windowHandler = new EventHandler() {
		@Override
		public void handleEvent(Event event) {
			if (!UIEvents.isSET(event))
				return;

			Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
			if (!(element instanceof MWindow))
				return;

			MWindow window = (MWindow) element;
			if (!processed.add(window))
				return;

			IEclipseContext context = window.getContext();
			context.set(ISaveHandler.class, saveHandler);
			context.set(IWindowCloseHandler.class, windowCloseHandler);
		}
	};

	@PostContextCreate
	public void startup(IEclipseContext context, IEventBroker eventBroker) {
		saveHandler = ContextInjectionFactory.make(PartSaveHandler.class, context);
		windowCloseHandler = ContextInjectionFactory.make(WindowCloseHandler.class, context);

		eventBroker.subscribe(UIEvents.Window.TOPIC_X, windowHandler);
	}
}

plugin.xml:
         <property
               name="lifeCycleURI"
               value="bundleclass://com.example.editor/com.example.editor.handlers.LifeCycleManager">
         </property>

Relies on the Window's X position being set at some point after it has been created. See also my other thread about where to register an ISaveHandler..
Re: How to forestall the window closing [message #923389 is a reply to message #923091] Tue, 25 September 2012 17:50 Go to previous messageGo to next message
Eclipse UserFriend
Do we already have a bug for that?

Tom

Am 25.09.12 17:40, schrieb Markus Wiederkehr:
> My current (also not very beautiful) solution:
>
>
> public class LifeCycleManager {
> private ISaveHandler saveHandler;
> private IWindowCloseHandler windowCloseHandler;
>
> private final HashSet<MWindow> processed = new HashSet<MWindow>();
>
> private final EventHandler windowHandler = new EventHandler() {
> @Override
> public void handleEvent(Event event) {
> if (!UIEvents.isSET(event))
> return;
>
> Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
> if (!(element instanceof MWindow))
> return;
>
> MWindow window = (MWindow) element;
> if (!processed.add(window))
> return;
>
> IEclipseContext context = window.getContext();
> context.set(ISaveHandler.class, saveHandler);
> context.set(IWindowCloseHandler.class, windowCloseHandler);
> }
> };
>
> @PostContextCreate
> public void startup(IEclipseContext context, IEventBroker
> eventBroker) {
> saveHandler =
> ContextInjectionFactory.make(PartSaveHandler.class, context);
> windowCloseHandler =
> ContextInjectionFactory.make(WindowCloseHandler.class, context);
>
> eventBroker.subscribe(UIEvents.Window.TOPIC_X, windowHandler);
> }
> }
> plugin.xml:
>
> <property
> name="lifeCycleURI"
>
> value="bundleclass://com.example.editor/com.example.editor.handlers.LifeCycleManager">
>
> </property>
> Relies on the Window's X position being set at some point after it has
> been created. See also my other thread about where to register an
> ISaveHandler..
Re: How to forestall the window closing [message #923682 is a reply to message #923389] Wed, 26 September 2012 01:24 Go to previous messageGo to next message
Eclipse UserFriend
Thanks for your replies with solutions of this problem. But why is it a problem? Why is it so complex?

I think It must be provided appropriate URI classes for application (or workbench) and for windows similar to URI class for Parts. These classes must support all theirs possible lifecycle events by using appropriate annotations such as:
@PostContextCreate
@Focus
@FocusLost
@CanClose (with boolean result)
@PreDestroy
... ets.

Incidentally, I think for Part classes should be feasible also and methods with @CanClose (boolean) and @FocusLost too.

These are not specific events which can be required very seldom. It is required for most applications and implementation of such events should be laconic.
Am I not right?

[Updated on: Wed, 26 September 2012 02:53] by Moderator

Re: How to forestall the window closing [message #923765 is a reply to message #923682] Wed, 26 September 2012 03:11 Go to previous messageGo to next message
Eclipse UserFriend
Am 26.09.12 07:24, schrieb ALGROM Mising name:
> Thanks for your replies with solutions of this problem. But why is it a
> problem? Why is it so complex?
>
> I think It must be provided appropriate URI classes for application (or
> workbench) and for windows similar to URI class for Parts. These classes
> must support all theirs possible lifecycle events by using appropriate
> annotations such as:

I see where you are going to - you want to install a lifecycle handler
for windows (and most likely perspectives as well).

I need to think about this a bit, but it would certainly make things
easier, than listening to the eventbroker and/or installing stuff into
the context.

File a feature request and post the bug-id here.

> @PostContextCreate
> @Focus
> @FocusLost
> @PreClose (with boolean result)
> @PreDestroy
> ... ets.
>
> Incidentally, I think for Part classes should be feasible also and
> methods with @PreClose (boolean) and @FocusLost too.
>

File a feature request and post the bug-id here. - I see those 2 making
sense for part.

Tom
Re: How to forestall the window closing [message #923866 is a reply to message #923765] Wed, 26 September 2012 05:02 Go to previous message
Eclipse UserFriend
Thanks.

I mean that 99% necessities should be provided via the Application.e4xmi. It is possible!

Gennady

[Updated on: Wed, 26 September 2012 05:02] by Moderator

Previous Topic:Calling getObject On A Populated Part Returns null
Next Topic:Removing Some menu items programatically
Goto Forum:
  


Current Time: Tue Jul 01 18:57:00 EDT 2025

Powered by FUDForum. Page generated in 0.11845 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top