Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Send Events directly after application construction
Send Events directly after application construction [message #1006453] Thu, 31 January 2013 11:35 Go to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
Hi,
I want to restore the old application state at startup. I have a file with all the information, but when class A reads it (in a @PostConstruct method), I can't send it to class B since the eventBroker are not yet initialized.

How can I trigger a method to run directly after all classes have been initialized?

thanks Smile
Re: Send Events directly after application construction [message #1007054 is a reply to message #1006453] Mon, 04 February 2013 09:24 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
Doe noone have a solution? It should basically be as in eclipse: I have a Treeviewer with items in it and a partstack with some viewes displaying the items (either txt-files, exel-files or just a bunch of buttons and labels). Right now I save the TreeViewers items and the items they are pointing to with serilizartion. Also my workspace gets saved by eclipse so that the view order, size, windowsize, etc is beeing restored.

So right now, if I start my application, I have to connect the views that are beeing restored to the items I save by serilization. Is there I better way to save the complete workspace with all opened views, TreeViewer items and so on and restore it after reopening my application? I should be just like eclipse Smile
(the only things I found were a couple of other fileformats, but nothing like this)
Re: Send Events directly after application construction [message #1007130 is a reply to message #1007054] Mon, 04 February 2013 15:00 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph KeimelFriend
Messages: 482
Registered: December 2010
Location: Germany
Senior Member
Hi Aljoscha

I like to use the Equinox Preferences to save UI state. In my part contribution class I inject the preference node and maybe some preferences to use for the logic. DI cares about creating a node for my part:
@Inject @Preference private IEclipsePreferences prefNode;
@Inject @Optional @Preference(value=PREF_SHOW_INAKTIV)
private Boolean showInactiv = null;

If you need to do a refresh in case a preference changes, you can let DI call a function instead of using a member variable:
@Inject
void inactivPrefChanged(@Optional @Preference(value=PREF_SHOW_INAKTIV) Boolean showInactiv) {
	... do the refresh ...;
}

When something changes, I just set the preference and let DI care about the values.
final Button showInactivBtn = new Button(control.getComposite(), SWT.CHECK);
showInactivBtn .setText("Show inactive Elements");
showInactivBtn .setSelection(showInaktiv);
showInactivBtn .addSelectionListener(new SelectionAdapter() {
	@Override
	public void widgetSelected(SelectionEvent e) {
		prefNode.putBoolean(PREF_SHOW_INAKTIV, showInactivBtn.getSelection());
	}
});

When the part gets dstroyed, I save the UI state on @PersistState. I.e. I save the column order and the column width of a JFace Viewer like this:
@PersistState
private void persistState() {
	// Save the order of the columns
	int[] columnOrder = viewer.getGrid().getColumnOrder();
	String columnOrderString = Joiner.on(',').join(ArrayUtils.toObject(columnOrder));
	prefNode.put(PREF_GRID_ORDER, columnOrderString);
	
	// Save the width of every column using the EMF feature name as a key
	for (GridColumn col : viewer.getGrid().getColumns()) {
		EStructuralFeature feature = (EStructuralFeature) col.getData(DATA_COLUMN_FEATURE);
		prefNode.putInt(feature.getName() + PREF_COLUMN_WIDTH_SUFFIX, col.getWidth());
	}
	
	// Cause Equinox the write the preferences to disc
	try {
		prefNode.flush();
	} catch (BackingStoreException e) {
		logger.error("Error while saving the preferences", e); //$NON-NLS-1$
	}
}


[Edited after the Answer from Sopot below:]
An alternative to this approach could be to put your UI state into the persistedState of your MPart and let E4 save it in the application model for you. I haven't tried this approach, but it could look something like this:
@PostConstruct
void postConstruct(MPart part) {
	String myStateValue = part.getPersistedState().get(MY_STATE_KEY);
}

@PersistState
void persistState(MPart part) {
	part.getPersistedState ().put(MY_STATE_KEY, myStateValue);
}


Hope this helps!

Greetings
Christoph

[Updated on: Thu, 07 February 2013 08:22]

Report message to a moderator

Re: Send Events directly after application construction [message #1007287 is a reply to message #1007130] Tue, 05 February 2013 11:34 Go to previous messageGo to next message
Eclipse UserFriend
I haven't read the whole thread in detail but it looks like MApplicationElement#getPersistedState is relevant here. Basically every model element (addon, MApplication, MPart etc.) extends MAE and it inherits this map like structure which is persisted across restarts. I'm sure Lars tutorials have something more detailed.
Re: Send Events directly after application construction [message #1007361 is a reply to message #1007287] Tue, 05 February 2013 15:49 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph KeimelFriend
Messages: 482
Registered: December 2010
Location: Germany
Senior Member
@Sopot: Thanks, that would probably be a better choice in this case Smile
Re: Send Events directly after application construction [message #1007613 is a reply to message #1006453] Wed, 06 February 2013 17:54 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
Thank you for the answer, but I can't find any tutorial or describtion if I look for MApplicationElement, getPersistedState() or sth similar. Did you have a certain tutorial in mind? Or what is the gerneral keyword I could look for?

Also: would this approach cover all my "problems"?
Btw: hope this was clear or it doesn't matter: I want to do a standalone application, not a Plugin or anything like this
Re: Send Events directly after application construction [message #1007700 is a reply to message #1007613] Thu, 07 February 2013 08:08 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph KeimelFriend
Messages: 482
Registered: December 2010
Location: Germany
Senior Member
Hi Aljoscha,

try this great tutorial by Lars Vogel to get started creating standalone applications:
http://www.vogella.com/articles/EclipseRCP/article.html

Greetings
Christoph

Aljoscha Steffens wrote on Wed, 06 February 2013 18:54
Thank you for the answer, but I can't find any tutorial or describtion if I look for MApplicationElement, getPersistedState() or sth similar. Did you have a certain tutorial in mind? Or what is the gerneral keyword I could look for?

Also: would this approach cover all my "problems"?
Btw: hope this was clear or it doesn't matter: I want to do a standalone application, not a Plugin or anything like this
Re: Send Events directly after application construction [message #1008239 is a reply to message #1007700] Mon, 11 February 2013 17:04 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
I looked already in this tutorial, but couldn't find anything except for 7.2 Persisted State. This way I can display the text files that were restored properly ( yeah Smile ), but I dont't know how this would help me with loading all my classes.
An annotation like @AfterCompleteApplicationConstruction would help Razz





Also I have another issue: When I double-click on an item in my treeviewer it should be displayed. If its already opened in a partstack this part should get active. This is the corresponding method:

	private boolean itemIsOpen(UUID iD, MPartStack stack) {
		Iterator<MStackElement> iter = stack.getChildren().iterator();
		while (iter.hasNext()) {
			
			Object obj = iter.next();
                        System.out.println(obj.getclass());
			if (obj instanceof MInputPart) {
				MInputPart part = (MInputPart) obj;
				if (part.getObject() instanceof MyItemEditor) {

					MyItemEditor editor = (MyItemEditor) part.getObject();
					if (editor.getDisplayedItemId() == iD) {
						partService.showPart(part, PartState.ACTIVATE);
						return true;
					}
				}
			}
		}

		return false;
	}




So there are two problems:

1. The stack grows. When I open a couple of files, say 3, then close the application, restart it and open another file, the stack has a size of 4.

2. The objects in the stack are from type class org.eclipse.e4.ui.model.application.ui.basic.impl.InputPartImpl. Not from MyItemEditor. So the second if-statement always retruns false.


Re: Send Events directly after application construction [message #1008246 is a reply to message #1007700] Mon, 11 February 2013 17:46 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
I looked already in this tutorial, but couldn't find anything except for 7.2 Persisted State. This way I can display the text files that were restored properly ( yeah Smile ), but I dont't know how this would help me with loading all my classes.
An annotation like @AfterCompleteApplicationConstruction would help Razz





Also I have another issue: When I double-click on an item in my treeviewer it should be displayed. If its already opened in a partstack this part should get active. This is the corresponding method:

	private boolean itemIsOpen(UUID iD, MPartStack stack) {
		Iterator<MStackElement> iter = stack.getChildren().iterator();
		while (iter.hasNext()) {
			
			Object obj = iter.next();
                        System.out.println(obj.getclass());
			if (obj instanceof MInputPart) {
				MInputPart part = (MInputPart) obj;
				if (part.getObject() instanceof MyItemEditor) {

					MyItemEditor editor = (MyItemEditor) part.getObject();
					if (editor.getDisplayedItemId() == iD) {
						partService.showPart(part, PartState.ACTIVATE);
						return true;
					}
				}
			}
		}

		return false;
	}




So there are two problems:

1. The stack grows. When I open a couple of files, say 3, then close the application, restart it and open another file, the stack has a size of 4.

2. The objects in the stack are from type class org.eclipse.e4.ui.model.application.ui.basic.impl.InputPartImpl. Not from MyItemEditor. So the second if-statement always retruns false.


Re: Send Events directly after application construction [message #1010978 is a reply to message #1008246] Mon, 18 February 2013 15:46 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
No ideas?
Re: Send Events directly after application construction [message #1011351 is a reply to message #1010978] Tue, 19 February 2013 11:35 Go to previous messageGo to next message
Eclipse UserFriend
Aljoscha -- take a look at the UIEvents.UILifecycle.APP_STARTUP_COMPLETE event.

Brian.
Re: Send Events directly after application construction [message #1011354 is a reply to message #1011351] Tue, 19 February 2013 11:39 Go to previous messageGo to next message
Eclipse UserFriend
And here's the story behind it. https://bugs.eclipse.org/bugs/show_bug.cgi?id=376821
Re: Send Events directly after application construction [message #1012089 is a reply to message #1011354] Wed, 20 February 2013 21:32 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
That sounds perfect, thanks!
But.. APP_STARTUP_COMPLETE cannot be resolved or is not a field. I searched for over one hour now, but can't find any solution. Do I have to download sth from http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?id=958dd70aea1be8b756e9adb06f4f91ca74115af8 ? Or do I have to add this changes manually somehow?
Re: Send Events directly after application construction [message #1012094 is a reply to message #1012089] Wed, 20 February 2013 21:40 Go to previous messageGo to next message
Eclipse UserFriend
It only appeared in 4.3; it's not in 4.2.2.

For 4.2.x, you can listen for the first TOPIC_WIDGET set on a MWindow -- that's roughly equivalent.

Brian.
Re: Send Events directly after application construction [message #1013939 is a reply to message #1012094] Sun, 24 February 2013 19:28 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
Thanks! It works really fine now except for one thing.
How can I access the red circled tabs when the application starts?
http://www.imgbox.de/users/public/images/iMgJ7DDrSF.jpg
I tried it this way:
MPartStack stack = (MPartStack) modelService.find(
					"test.partstack.editors", app);
			
			for (MStackElement element : stack.getChildren()) {
				
				if (element instanceof MInputPart) {
					MInputPart part = (MInputPart) element;
					if (part.getObject() instanceof MyEditor) {

                                           //do sth


					}
				}
			}


but this just gets the tab that is activated. If I click on each tab after the application started it works. But I have to "load" them once manually. (I hope you know what I mean)


[Updated on: Sun, 24 February 2013 19:29]

Report message to a moderator

Re: Send Events directly after application construction [message #1013941 is a reply to message #1013939] Sun, 24 February 2013 19:35 Go to previous messageGo to next message
Eclipse UserFriend
The contributed objects (the getObject()) are only instantiated when the part itself is rendered -- usually by being brought to the top. But you should be able to force the rendering of an element with EPartService#showPart(part, PartState.CREATE).

Brian.
Re: Send Events directly after application construction [message #1015684 is a reply to message #1006453] Fri, 01 March 2013 17:22 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
Thank you!!
It works really fine now. I'm not really satisfied with the TOPIC_WIDGET event (it gets called a couple of times during startup) but I'll just change to eclipse 4.3 in a couple of weeks.
Re: Send Events directly after application construction [message #1015691 is a reply to message #1006453] Fri, 01 March 2013 18:20 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member


Hmm acutally it's again not working properly. When I close tabs seperatly (that means I don't close the whole application but only one tab), and then restart the application the tabs are beeing recreated. I didn't find anything except the hidePart method of EPartService. Is this the correct way?
And if it is: how can I distinguish if a part gets closed seperatly or the whole application beeing closed? (If the part gets closed speratly I would call the hidePart method, if the application gets closed I wouldn't)
Re: Send Events directly after application construction [message #1017261 is a reply to message #1006453] Mon, 11 March 2013 11:12 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
I did again some search but couldn't find anything usefull :/
But it's actually not that fancy:
I have a couple of tabs open, say A, B, C. Then I colse tab A seperatly. After taht I close the whole application. If I restart it, I want tab B and C to be opened again but not A.

So how can I remove a part/destroy it? Is EPartService.hidePart(..) the appropriate method? And how can I distinguish between clonsing the whole application and closing a seperate tab?


Re: Send Events directly after application construction [message #1017264 is a reply to message #1017261] Mon, 11 March 2013 11:24 Go to previous messageGo to next message
Eclipse UserFriend
Aljoscha, I haven't really understood what you're trying to accomplish, and why the normal E4 workbench save and restore mechanisms are insufficient? But rather of having your part contribution objects attempt to talk to each other, have them talk to a central service instead -- separating your business logic and your presentation logic.

Brian,
Re: Send Events directly after application construction [message #1017460 is a reply to message #1017264] Mon, 11 March 2013 21:45 Go to previous messageGo to next message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
Well I don't know whether it's insufficient or whether I'm just not able to use it correclty. Probably latter Razz
So again whats happening:
I have tab A, B and C open. I close tab A. Then I close the application (with B and C still open). Then I restart the application. Now you would assume that only part B and C are beeing reopened. But also part A gets reopened. That is the problem.



So this is what I do:

1.
I close the application. The part has a certain item which is displayed. If the part gets destroyed, it saves the ID of this item.
	@PreDestroy
	private void saveContent(){
		part.getPersistedState().put("ItemId", displayedItemId.toString());
		
	}





2.
Now I restart the application. And the part is beeing recreated and looks if there is a saved id:

     //constructor
	@Inject
	public MyPart(MPart part){
		
		this.part = part;
		if(part.getPersistedState().get("ItemId") != null){
			displayedItemId = part.getPersistedState().get("ItemId");
		}
		
		
	}


3. After the application has started (this is where I needed your UIEvents.UILifecycle.APP_STARTUP_COMPLETE event), it looks which parts are opened and calls an "update" method.


			for(MPart part : partService.getParts()){			
				if(part instanceof MInputPart){
					partService.showPart(part, PartState.CREATE);
					MInputPart inputPart = (MInputPart) part;
					if (inputPart.getObject() instanceof MyPart) {
						MyPart myPart =(MyPart) inputPart.getObject();
						myPart.recallEditorContent();
					}	
				}
			}


4. This "update" method takes the Id (if there is one) and gets the required information so that the part can display the item properly.


What do I do wrong?


I don't really know what you mean with contribution objects talking to each other. Can you explain it a little more?
Thank you very much Smile

Re: Send Events directly after application construction [message #1019324 is a reply to message #1017460] Fri, 15 March 2013 12:53 Go to previous message
Aljoscha Steffens is currently offline Aljoscha SteffensFriend
Messages: 302
Registered: November 2012
Senior Member
Maybe it's better to start at that point again: http://www.eclipse.org/forums/index.php/mv/msg/452376/1013939/#msg_1013939
All the tabs are loaded by Eclipse, but the contribution objects are not instanciated so they don't really exist. Only if I click on the tabs, they get instantiated.
How can I instanciate them? ( EPartService#showPart(part, PartState.CREATE) does not really work, because also the tabs which were closed seperatly are beeing recreated )
Previous Topic:subversive - Unable to read repository under Eclipse 4.2.2
Next Topic:WorkbenchWindowAdvisor.postWindowCreate no longer is called in E4
Goto Forum:
  


Current Time: Thu Mar 28 16:25:35 GMT 2024

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

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

Back to the top