what is the standard way in eclipse to notify a view that an elment was added. In my cases i have one view in which items are created (tree viewer). Once that is done all other interrested parties shall be informed.
In another case all interrested views shall be informed if the data in an editor was changed. Should this be the save of an completly new object than this new item shall be added to a view.
What is the best way to do this without implmenting my own listener mechanism?
In your viewer's content provider there is a method:
public void inputChanged(Viewer viewer, Object oldInput, Object newInput);
According to the documentation:
Notifies this content provider that the given viewer's input has been
switched to a different element.
A typical use for this method is registering the content provider as a
listener to changes on the new input (using model-specific means), and
deregistering the viewer from the old input. In response to these
change notifications, the content provider should update the viewer
(see the add, remove, update and refresh methods on the viewers).
You can use this method to notify other classes that your input has changed. (i.e. - an element was added .. )
Related
I have an eclipse plugin which has multiple classes which make some UI contributions.
The contribution is done through the deprecated org.eclipse.ui.actionSets and the classes implement the IWorkbenchWindowActionDelegate which require an implementation of the selectionChanged(IAction action, ISelection selection).
The selectionChanged method is triggered on any selection change (another file opened, another item selected in Project Explorer, some text is selected in the editor(this one triggers several calls of the method)).
Is there a filtering or something which I can do to limit the selectionChanged observed objects. For example, for class A, trigger the selectionChanged only if the opened file in editor changes)?
No, there is no way to filter that.
Selections coming from text editors with be instances of ITextSelection, other selections will usually be instances of IStructuredSelection so you can check for those instances to do simple filtering in your code.
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.
In my application I have a menu which open a SelectionDialog, this dialog is used to choose an object.
When this object is selected I have to display it in the view.
What is the best way to update my view?
Currently, I call myview.update(object) after the dialog is closed (in the handler of the menu). But I think this solution is not well design.
I have read about update my model and notify my view but my model does not change (no data are changed, I only display different Data ).
Does anyone has some ideas for a well design solution ?
Define model listener ( dataPopulated(Event e))
Make your view implement model listener and register it with the Model.
Define a Model class that can contain the objects that you want to populate in the view
When Model.setInput(Object input) is invoked fire dataPopulated() event on all registered model listeners.
Above steps works properly when you have view activated. You need to consider cases like when if view is deactivated or not visible ( make sure you refresh view is visible else you will have unnecessary overhead of refreshing view though it is notvisible)
Try adding a selection listener in the view and register this selection in the dialog.
In the listener action, add the code to show the selected object.
I have a file dialogue opening from the menu where a user can select a file. The FileDialog is called from the menu command's handler class in execute().
Based on the file the user selected, I would like to update a view, for which (I believe) I'd need the same Composite element that's passed to the view in createPartControl().
Is it possible to get access to it from the command handler, or would it be better to trigger the view updating via something like ISourceProviderListener or PropertyChangeListener?
Thank you.
Yes, it's possible:
IViewPart part = HandlerUtil.getActiveWorkbenchWindow(executionEvent).getActivePage()
.findView(viewId);
It would be better to first update the data that your view is displaying (the model in MVC) and the change in data should trigger view refresh. It's hard to say which listener is better without knowing all the details.
I have a plugin which contains class A that brings up a view defined in class B via the following line of code:
(VideoLogView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView("Videolog.VideoLogView");
What I need to do in the createPartControl() method of the view (class B object) is access a method in the class A object.
How can this be done?
Thanks.
Look like you are facing the classic issue of "how do I pass arguments to my view" ?
This thread illustrates it best:
I was facing the same problem at the beggining of my RCP project. I was getting weird about the fact that there was no way to pass an argument to a view as the viewed model.
Why? Because (emphasis mine):
You are on an opened, pluggable platform.
You contribute to existing developments, others should be able to contribute to yours.
Therefore you will not "pass" arguments to a view, this would lock the whole thing into a non-opened design.
Instead, your view will ask the platform (or will listen to the platform) to determine which information to manage.
Other views (from other plugins that don't yet exist) might also want to manage the same information on the same event.
What you should do then is to ask the workbench for the current selection. I guess your view is opening on a double click action or simple selection so the object you want to manage in your view will be currently selected.
This is how you could retrieve the workbench selection from your view :
ISelection s = this.getSite().getWorkbenchWindow().getSelectionService().getSelection();
where "this" is a ViewPart.
Then you have to make your initial view (the one initiating the view creation from a given event like DoubleClick) a selection provider. A JFace viewer is a selection provider, so you can use it if you're using jface, or you can implement the ISelectionProvider interface when you're using custom SWT controls (that was my case).
The article "Eclipse Workbench: Using the Selection Service" can also give you some pointers.