Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    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 06:17 Go to next message
Gennady Gromov is currently offline Gennady GromovFriend
Messages: 24
Registered: May 2011
Junior Member
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 08: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 09:55 Go to previous messageGo to next message
Gennady Gromov is currently offline Gennady GromovFriend
Messages: 24
Registered: May 2011
Junior Member
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 11: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 11: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 11:58 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
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 12:38 Go to previous messageGo to next message
Gennady Gromov is currently offline Gennady GromovFriend
Messages: 24
Registered: May 2011
Junior Member
No Message Body

[Updated on: Tue, 25 September 2012 12:39]

Report message to a moderator

Re: How to forestall the window closing [message #922951 is a reply to message #922580] Tue, 25 September 2012 13:36 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph KeimelFriend
Messages: 482
Registered: December 2010
Location: Germany
Senior Member
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 13:51]

Report message to a moderator

Re: How to forestall the window closing [message #922955 is a reply to message #922951] Tue, 25 September 2012 13: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 13:43 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph KeimelFriend
Messages: 482
Registered: December 2010
Location: Germany
Senior Member
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 13:52]

Report message to a moderator

Re: How to forestall the window closing [message #922969 is a reply to message #922955] Tue, 25 September 2012 13:50 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph KeimelFriend
Messages: 482
Registered: December 2010
Location: Germany
Senior Member
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 14: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 14:44 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph KeimelFriend
Messages: 482
Registered: December 2010
Location: Germany
Senior Member
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 15:40 Go to previous messageGo to next message
Markus Wiederkehr is currently offline Markus WiederkehrFriend
Messages: 17
Registered: August 2012
Junior Member
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 21:50 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
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 05:24 Go to previous messageGo to next message
Gennady Gromov is currently offline Gennady GromovFriend
Messages: 24
Registered: May 2011
Junior Member
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 06:53]

Report message to a moderator

Re: How to forestall the window closing [message #923765 is a reply to message #923682] Wed, 26 September 2012 07:11 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
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 09:02 Go to previous message
Gennady Gromov is currently offline Gennady GromovFriend
Messages: 24
Registered: May 2011
Junior Member
Thanks.

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

Gennady

[Updated on: Wed, 26 September 2012 09:02]

Report message to a moderator

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


Current Time: Thu Apr 18 05:11:22 GMT 2024

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

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

Back to the top