Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Correct way to listen to a part activation/visibility change?
Correct way to listen to a part activation/visibility change? [message #1684004] Wed, 18 March 2015 08:41 Go to next message
Alexander Bunkowski is currently offline Alexander BunkowskiFriend
Messages: 23
Registered: February 2014
Junior Member
Hi,

I need to listen if the part I'm currently in is set to visible.
At the moment I'm using the code below which works, but it seems a bit much and it is always executed twice with completely identical event object.

@Inject
@Optional
private void activate(@UIEventTopic(UIEvents.UILifeCycle.ACTIVATE) Event event) {
	Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
	if (element != null && element instanceof MPart) {
		MPart part = (MPart) element;
		if (part.getElementId().equals(thisPart.getElementId()) && part.getTags().contains("active")) {
			//expensive call here
		}
	}
}


Is there some better way to listen to visibility changes from inside a part?
Re: Correct way to listen to a part activation/visibility change? [message #1689782 is a reply to message #1684004] Tue, 24 March 2015 09:58 Go to previous messageGo to next message
Alexander Bunkowski is currently offline Alexander BunkowskiFriend
Messages: 23
Registered: February 2014
Junior Member
I found a presentation from EclipseCon 2014 Brian de Alwis (not allowed to post links yet you can google it if required)

On Page 14 of his slides he suggests the following not working code:
@Inject
public void raisedToTop(@UIEventTopic(UIEvents.UILifeCycle.BRINGTOTOP) MPart part) {
	if (part == thisPart) {
		// do something
	}
}


It's the same thing I tried, but it does not work.
I guess that's because the MPart inside Event Map has the Key UIEvents.EventTags.ELEMENT (=ChangedElement) and not IEventBroker.DATA (=org.eclipse.e4.data).
Bug or intended?

But at least BRINGTOTOP is better then ACTIVATE because it is only fired once.
Re: Correct way to listen to a part activation/visibility change? [message #1690172 is a reply to message #1689782] Wed, 25 March 2015 14:51 Go to previous messageGo to next message
Alexander Bunkowski is currently offline Alexander BunkowskiFriend
Messages: 23
Registered: February 2014
Junior Member
Ok, my solution for now is just a simplified version of what I initially posted, together with the usage of BRINGTOTOP instead of ACTIVE.

@Inject
@Optional
public void handleBringToTop(@UIEventTopic(UIEvents.UILifeCycle.BRINGTOTOP) Event event) {
	if (thisPart == event.getProperty(UIEvents.EventTags.ELEMENT)) {
		//do something
	}
}


The event is never null and all the other checks I did in my original post are not required.
Re: Correct way to listen to a part activation/visibility change? [message #1696930 is a reply to message #1690172] Fri, 29 May 2015 12:55 Go to previous messageGo to next message
Alexander Bunkowski is currently offline Alexander BunkowskiFriend
Messages: 23
Registered: February 2014
Junior Member
After using this solution for a while I recognized that BRINGTOTOP is not fired when the respective MPart is shown as part of an perspective switch.

BRINGTOTOP is fired:
1. If you open the part (create a new one)
2. If you bring it on top of a part stack by selecting the tab
3. If you switch the perspective and set it as the selected element.

It is not fired if the part comes up as part of an perspective without having focus.


Is there any annotation or topic I can use to react to part becomes visible?
Re: Correct way to listen to a part activation/visibility change? [message #1699991 is a reply to message #1696930] Mon, 29 June 2015 14:33 Go to previous messageGo to next message
Alexander Bunkowski is currently offline Alexander BunkowskiFriend
Messages: 23
Registered: February 2014
Junior Member
Maybe that is the reason is that visibility change of a part is not posted via the IEventBroker?

// FIXME: convert me to e4 events!
private void firePartVisible(MPart part) {
....

See code:
http://git.eclipse.org/c/platform/eclipse.platform.ui.git/tree/bundles/org.eclipse.ui.workbench/Eclipse%20UI/org/eclipse/ui/internal/WorkbenchPage.java#n5286

It's not yet converted to e4 ?
Re: Correct way to listen to a part activation/visibility change? [message #1713195 is a reply to message #1699991] Mon, 02 November 2015 09:13 Go to previous messageGo to next message
Alexander Bunkowski is currently offline Alexander BunkowskiFriend
Messages: 23
Registered: February 2014
Junior Member
I found a way that reliable also works if the perspective if set visible (and all other cases):

				ePartService.addPartListener(new PartListenerAdapter() {
					@Override
					public void partBroughtToTop(MPart part) {
						if (part == targetMPart) {
							//react here
						}
					}
				});
Re: Correct way to listen to a part activation/visibility change? [message #1734860 is a reply to message #1713195] Mon, 13 June 2016 14:40 Go to previous messageGo to next message
py e4 is currently offline py e4Friend
Messages: 4
Registered: June 2016
Junior Member
where would PartListenerAdapter be found ?

Alexander Bunkowski wrote on Mon, 02 November 2015 09:13
I found a way that reliable also works if the perspective if set visible (and all other cases):

				ePartService.addPartListener(new PartListenerAdapter() {
					@Override
					public void partBroughtToTop(MPart part) {
						if (part == targetMPart) {
							//react here
						}
					}
				});

Re: Correct way to listen to a part activation/visibility change? [message #1735464 is a reply to message #1734860] Mon, 20 June 2016 06:38 Go to previous messageGo to next message
Alexander Bunkowski is currently offline Alexander BunkowskiFriend
Messages: 23
Registered: February 2014
Junior Member
Hey py,

sorry, its my own abstract (empty) implementation of IPartListener, to avoid all the empty methods.

So either you use IPartListener directly or create this:

import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.modeling.IPartListener;

public abstract class PartListenerAdapter implements IPartListener {

	@Override
	public void partActivated(MPart part) {
	}

	@Override
	public void partBroughtToTop(MPart part) {
	}

	@Override
	public void partDeactivated(MPart part) {
	}

	@Override
	public void partHidden(MPart part) {
	}

	@Override
	public void partVisible(MPart part) {
	}

}


Good point Smile
Re: Correct way to listen to a part activation/visibility change? [message #1735524 is a reply to message #1735464] Mon, 20 June 2016 15:05 Go to previous messageGo to next message
py e4 is currently offline py e4Friend
Messages: 4
Registered: June 2016
Junior Member
A.
thanks for the prompt answer.
indeed seems to work PARTIALLY when run from @PostConstruct of my part ...

now it's quite puzzling when switching perspective to get 3 calls : activated-desactivated-activated, as shown in log below :
partDeactivated org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl @6a99e02d
partActivated org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl @17495c9e
partDeactivated org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl @17495c9e
partActivated org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl @17495c9e

any (good?) reason for that ?

B.
and it's quite also puzzling to get this exception when run from an AddOn !!??
Caused by: org.eclipse.e4.core.di.InjectionException: java.lang.UnsupportedOperationException: Listeners should only be attached/removed from a window's part service


partService is the same here and there, no ?


C.
unfortunaltely, if the perspective contains another part with the focus, then my part (17495c9e in the above log) doesn't get any "activated" Sad

seems so basic ... Rolling Eyes
has someone a complete successful implementation of such e4 app ?

Re: Correct way to listen to a part activation/visibility change? [message #1735867 is a reply to message #1735524] Thu, 23 June 2016 11:25 Go to previous message
Alexander Bunkowski is currently offline Alexander BunkowskiFriend
Messages: 23
Registered: February 2014
Junior Member
Not sure if I understand your Problem, but ill try to give some hints:

For B it should help to get the EPartService from the part context you want to watch.

MPart yourTargetPart = {somehow get you part here}
EPartService ePartService = yourTargetPart.getContext().get(EPartService.class);
ePartService.addPartListener(new PartListenerAdapter() {
	@Override
	public void partBroughtToTop(MPart part) {
		if (yourTargetPart == targetMPart) {
			//react here
		}
	}
});


If you have problems when switching perspectives you can try to subscribe to the PERSPECTIVE_SET_TOPIC. Idea is to see if you part is visible after a perspective has been switched and then react to it.

private static final String PERSPECTIVE_SET_TOPIC = "org/eclipse/e4/ui/model/ui/ElementContainer/selectedElement/SET";
eventBroker.subscribe(PERSPECTIVE_SET_TOPIC, new EventHandler() {
	@Override
	public void handleEvent(Event event) {
		Object property = event.getProperty(UIEvents.EventTags.ELEMENT);
		if (property != null && property instanceof MPerspectiveStack && partService.isPartVisible(yourTargetPart )) {
			//react here
		}
	}
});

[Updated on: Thu, 23 June 2016 11:34]

Report message to a moderator

Previous Topic:Create new workbench window
Next Topic:Switching binding context based on selection
Goto Forum:
  


Current Time: Fri Sep 22 06:17:09 GMT 2017

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

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