A RCP E4 application includes a TreeViewer to manage the visivility/selection of a collection of “Packages”. The part is named as Package Navigator.
When one Package is ready to be send, the TreeViewer icon shows and the button to start the shipment should be enabled.
When the package is not ready, the icon is and the button (handler) to ship should be disabled.
The code to implement such behavior is:
private TreeViewer viewer;
@PostConstruct
public void createComposite(Composite parent, IEnviosService theModel) {
...
Tree t = (Tree) viewer.getControl();
t.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
boolean check = false;
System.out.print("Selection listener ....");
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
if (selection.getFirstElement() instanceof Package) {
check = ((Package)selection.getFirstElement()).isReadyToShip();
System.out.print("IT'S A PACKAGE....");
// evaluate all @CanExecute methods
broker.post(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, check);
}
System.out.print("\n");
}
});
}
The handler to execute the shipment is
public class ShipmentHandler {
@Execute
public void execute(Shell shell) {
//TODO
}
@Inject
@Optional
@CanExecute
public boolean canExecute(@UIEventTopic(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC) boolean checkPackageReady) {
System.out.println("Inside canExecute method... " + checkPackageReady);
if (checkPackageReady)
return true;
return false;
}
}
But the button never is disabled, even whe the @canExecute method returns false, for example, after click on Packages 88 , 89 and 110 and 112 shows the following console output whith the button always enabled:
Selection listener PACKAGE: 88...true
Inside canExecute method... true
Selection listener PACKAGE: 89...false
Inside canExecute method... false
Selection listener PACKAGE: 110...false
Inside canExecute method... false
Selection listener PACKAGE: 112...true
Inside canExecute method... true
I don't think you can mix @CanExecute
and @UIEventTopic
like that. In any case UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC
is a rather special topic which isn't intended to be handled like this.
The argument to the broker.post(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC
is supposed to be an element id, UIEvents.ALL_ELEMENT_ID
or a org.eclipse.e4.ui.workbench.Selector
, nothing else. The argument selects which handlers are updated.
So you can't pass the 'checkPackageReady' value directly to the handler, you will have to use some other mechanism - such as a model object that the view and the handler can both inject.
You could also use the ESelectionService
to set the current selection for the part, you can then access this information in the handler:
View part:
@Inject
ESelectionService selectionService;
...
public void widgetSelected(SelectionEvent e)
{
selectionService.setSelection(viewer.getStructuredSelection());
broker.post(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, ... selector);
}
Can execute:
@CanExecute
public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) IStructuredSelection selection, @Named(IServiceConstants.ACTIVE_PART) MPart part)
{
// TODO check part is your part
// TODO check the selection
}