Programmatically showing a View from an Eclipse Plug-in - eclipse

I have a plug-in to an Eclipse RCP application that has a view. After an event occurs in the RCP application, the plug-in is instantiated, its methods are called to populate the plug-in's model, but I cannot find how to make the view appear without going to the "Show View..." menu.
I would think that there would be something in the workbench singleton that could handle this, but I have not found out how anywhere.

You are probably looking for this:
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView("viewId");

If called from handler of a command
HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().showView(viewId);
would be better, as I know.

I found the need to bring the view to the front after it had been opened and pushed to the background. The activate method does the trick.
PlatformUI.getWorkbench()
.getActiveWorkbenchWindow()
.getActivePage()
.activate(workbenchPartToActivate);
NOTE: The workbenchPartToActivate is an instance of IWorkbenchPart.

In e4, the EPartService is responsible for opening Parts. This can also be used to open e3 ViewParts. Instantiate the following class through your IEclipseContext, call the openPart-Method, and you should see the Eclipse internal browser view.
public class Opener {
#Inject
EPartService partService;
public void openPart() {
MPart part = partService.createPart("org.eclipse.ui.browser.view");
part.setLabel("Browser");
partService.showPart(part, PartState.ACTIVATE);
}
}
Here you can find an example of how this works together with your Application.e4xmi.

Related

How to get/inject EPartService outside part or in LifeCycle Manager or How to control life cycle of e4 RCP app in true sense?

My application consists of many parts and they are defined in application's e4xmi file. I want to hide and show them dynamically. I am using EpartService to do so in handlers, where I can inject it.
But I also want to control the show/hide of parts with something like life cycle manager, where I can not inject EPartService. Is there any way to achieve and fully control RCP application's life cycle?
There seems the exact same question here and void of solution:
https://www.eclipse.org/forums/index.php/t/595958/
I want to implement 'remember me like feature' where part having sign in screen is shown instead of other parts. Also after log out same sign-in part is to be shown. So I need to control life cycle of RCP app. But I cant inject EPartService before anything in Application's e4xmi is initiated.
If you are creating a class from something which is injected (such as the LifeCycle class) you can create your class with injection using ContextInjectionFactory:
#Inject
IEclipseContext context;
MyClass myClass = ContextInjectionFactory.make(MyClass.class, context);
Or if you just pass an IEclipseContext to the class you can get the part service using:
EPartService partService = context.get(EPartService.class);
Note: There is a separate instance of the part service for each part. Depending on what you are doing you may need to make sure you have the service for the active part.
If you are not locked in to using SWT, you could use the e(fx)clipse e4 renderer for JavaFX instead.
e(fx)clipse has more possibilities to control the lifecycle of the application. For example you can return a Boolean from #PostContextCreate to signal whether you want to continue the startup or not. You will not be able to use EPartService here though, but you can roll your own login dialog using dependency injection as greg-449 has described it in his answer.
public class StartupHook {
#PostContextCreate
public Boolean startUp(IEclipseContext context) {
// show your login dialog
LoginManager loginManager = ContextInjectionFactory.make(LoginManager.class, context);
if(!loginManager.askUserToLogin()) {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
}
(You can also restart the application. Form
more details see http://tomsondev.bestsolution.at/2014/11/03/efxclipse-1-1-new-features-api-to-restart-your-e4-app-on-startup/).

Refresh Eclipse 4 RCP view on wizard perform finish

Rookie question that I'm not having much luck with. In my e4 RCP application, I have a couple of instances where I create an object in a wizard that should then appear in one of my views.
The desired behavior is similar to how the eclipse Package Explorer View updates after a new project is created.
I was thinking I could just grab the view from the partService and run my own update method:
MPart ingredientsView = partService.showPart("com.personal.recipes.part.ingredientsview", PartState.ACTIVATE);
IngredientsView iv = (IngredientsView) ingredientsView.getObject();
iv.updateView();
While this works in other places, when called from a wizard 'partService' is null and the app NPE's out.
So what is the proscribed method of forcing e4 views to update after modifying their contents?
EDIT:
I tried to use the ContextInjectionFactory like #greg-449 showed in his answer, but I'm uncertain where to place it in my code, or how to define the context. I'm launching the wizard from a toolbar button, and placed the following code in my handler:
#Execute
public void execute(Shell shell) {
IEclipseContext context = EclipseContextFactory.create();
IWizard ingredientWizard = ContextInjectionFactory.make(IngredientWizard.class, context);
WizardDialog wizardDialog = new WizardDialog(shell, ingredientWizard);
wizardDialog.open();
}
However, when I tried to get the part service with #Inject EPartService partService; I got an InjectionException saying no error was found.
Once injection is available, using the EventBroker looks like the way to go.
enter code hereThe best way to update a view is to use a model for the content of the view. Your wizard seems to allow editing or creating ingredients. When you perform the finish of your wizard you are probably modifying some ingredient data. The ingredient model should be informed of these changes. If the view uses a content provider that observes this model is will update automatically when the model sees the update (this is the observer pattern).
How this works depends on the nature of your data. You could use the PropertyChange-Support in Java.
To do so let the content provider implement the org.eclipse.jface.util.IPropertyChangeListener interface and fire property change events when the data is changed.
UPDATE
My ContentProvider implements the property change interface. Whenever a property change event is received the viewer is refreshed(asynchronously). All my persistence operations are handled by data managers similar to Fowler's the table data gateway pattern but sometimes for more than one table. The data manager fires the property change event. This way the UI (wizard) does not need to know about persistence
Injection is only done on objects that the application model knows about. So it is not done on Wizards or Dialogs unless you do it 'manually' using ContextInjectionFactory when you create the dialog:
IWizard wizard = ContextInjectionFactory.make(YourWizardClass.class, eclipseContext);
WizardDialog dialog = new WizardDialog(shell, wizard);
This will do injection on your wizard class giving you access to the EPartService.
You could also use the 'event broker' (IEventBroker) to broadcast an event to anything that is interested rather than finding your specific view.

Eclipse RCP 4.x show view

I'm working for a short time on the libraries of eclipse 4.x someone could tell me how can I open a view through from the context menu? Thank you in advance.
To show a part anywhere you should define a command in the application model and a handler for the command. To show a part in the handler use:
#Execute
public void execute(EPartService partService)
{
MPart mpart = partService.showPart(part id, PartState.ACTIVATE);
}
In the application Part definition for your part add a Popup Menu to the Menus section. In the popup menu define a HandledMenuItem for your command.
To register the popup menu as the context menu for a control (tree, table etc) use:
#Inject
private EMenuService;
...
menuService.registerContextMenu(control, menu id);

Eclipse 4.2(juno) did not call saveState method of ViewPart when workspace is closing

I have a eclipse-plugin that have two perspectives. There is a view which extends ViewPart in one of the two perspectives. In this view, I overrided saveState method of ViewPart to save my data.
First, I open the prespective that has this view. Then i add some data in the view which should be save in saveState.
Next, I navigate to the other perspective that does not have this view.
Finally, I close the eclipse's workspace.
In eclipse 4.2(juno), saveState method of the view do not have been called. My data lost.
In eclipse 3.6(Helios), saveState method of the view have been called. My date has been persisted.
Does anyone know the reason? How can I insure that the saveState will be called when closing the workspace on all version of eclipse?
Eclipse e4 has no ApplicationWorkbenchAdvisor class and the application model has no property to set this,totally different with Eclipse 3.x.
You can get more from the wiki and vogella tutorial blog.
With joy, this problem persists into 4.4.2.
At its base, the issue is the compatibility layer WorkbenchPart.getViewReferences() only searches the currently active perspective. This behavior is different than the 3.x. The relevant code from the 4.4.2 Eclipse WorkbenchPart is here (notice the call to getCurrentPerspective()).
public IViewReference[] getViewReferences() {
MPerspective perspective = getCurrentPerspective();
if (perspective != null) {
List<MPlaceholder> placeholders = modelService.findElements(window, null,
MPlaceholder.class, null, EModelService.PRESENTATION);
List<IViewReference> visibleReferences = new ArrayList<IViewReference>();
for (ViewReference reference : viewReferences) {
for (MPlaceholder placeholder : placeholders) {
if (reference.getModel() == placeholder.getRef()
&& placeholder.isToBeRendered()) {
// only rendered placeholders are valid view references
visibleReferences.add(reference);
}
}
}
return visibleReferences.toArray(new IViewReference[visibleReferences.size()]);
}
return new IViewReference[0];
}
Therefore, if one has a view open and then changes to a perspective where that view is not shown, the saveState() method will not be called.
We have added an OSGI event listener for the UIEvents.UILifeCycle.appShutdownStarted and made a call to the saveState(). However, it is necessary to obtain the IMemento manually, since it is not present. Example code is in the org.eclipse.ui.internal.ViewReference (http://grepcode.com/file/repository.grepcode.com/java/eclipse.org/4.2.2/org.eclipse.ui/workbench/3.104.0/org/eclipse/ui/internal/ViewReference.java#ViewReference).
One could also add a part close listener with the IPartListener class to potentially persist settings if the user closes the view rather than application shutting down.
We have not found an OSGI event for the part being closed, but there may be one.
This discussion (Eclipse call ViewPart saveState on View close) suggested using IDialogSettings rather the IMemento. This discussion also proposed perhaps adding something into the dispose() method, but it is unclear how many resources are necessarily still available at the point of the dispose() being called.

Refreshing the workbench

HI,
I am facing some problem.. I want to hide the menu when eclipse workbench starts.
But the problem is menu is not hiding when the eclipse workbench starts. It is hiding only
when some refresh is happened. for example: when I change the default perspective to some other perspective, I am getting the desired out put. That means menu is hiding.
But when the eclipse workbench is loaded it is not hiding the menu. Below is my code.
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
try {
IWorkbenchWindow window = Workbench.getInstance().getActiveWorkbenchWindow()
if(window instanceof WorkbenchWindow) {
MenuManager menuManager = ((WorkbenchWindow)window).getMenuManager();
IContributionItem[] items = menuManager.getItems();
for(IContributionItem item:items){
System.out.println("item.getId()::: "+item.getId());
menuManager.remove("org.eclipse.ui.run");
menuManager.remove("help");
menuManager.remove("project");
}
}
}`
}
};
Given that you are looking to hide some features, I don't think that this is the best approach. (Not I am using the term feature here in the colloquial way, not as an Eclipse feature.
I would recommend one of two avenues:
Perspectives: See the extension point org.eclipse.ui.perspectives. This allows you to create a new perspective like the debug perspective or the Java perspective. Using a perspective, you can select exactly what menu items and views are shown and which ones are hidden.
Capabilities (aka activites): See the extension point org.eclipse.ui.activities. This allows you to have some fairly fine-grained control over what features are available in the workspace. See more info here: http://wiki.eclipse.org/Galileo_Capabilities
Put Your code in org.eclipse.ui.startup extention point. Make a Startup class after implementing the interface IStartup. For Details follow this link:-
Eclipse plugin : disable/enable dynamically an action from main menubar