0

Eclipse RCP E4 application.

The Send Proposal button Send Proposal Button is enabled when the user selects any ready-to-send package Package ready. For other options Package -GreenDot - RedDot, Send Proposal Button is disabled.

App Scenarios

This is achieved with the following code (based on question):

Navigator Part (View):

    Tree t = (Tree) viewer.getControl();
    t.addSelectionListener(new SelectionAdapter() {
        @Override
        public void widgetSelected(SelectionEvent e) {
            IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
            selectionService.setSelection(viewer.getStructuredSelection());
            if (selection.getFirstElement() instanceof Package) {
                broker.post(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, UIEvents.ALL_ELEMENT_ID);
            }
        }
    });

    //To update viewer after the Send Proposal Button is pressed
    @Inject
    @Optional
    public void sentProposal(@UIEventTopic(MundiaurumEventConstants.PROPOSAL_SENT) Package env) {
        viewer.refresh();
    }

ModelServiceImpl:

@Override
public boolean sendProposal(Package pack) {
    //model = list of packages

    model.remove(pack);

    //EventBroker to update Viewer after the Send Proposal Button is pressed
    broker.post(MundiaurumEventConstants.PROPOSAL_SENT, pack);

    //...
}

The handler to execute the shipment:

public class SendProposalHandler {
    @Execute
    public void execute(Shell shell, IEnviosService model,
        @Named(IServiceConstants.ACTIVE_SELECTION) IStructuredSelection selection, EModelService modelService,
        MApplication application, ESelectionService selectionService) {

        Package pack = (Package) selection.getFirstElement();
        model.sendProposal(pack);

        System.out.println("Selection service: " + selection.getFirstElement().getClass().getName());
        System.out.println("Package ID: " + ((Package) selection.getFirstElement()).getEnvioId());
        //This is to try to set the selection on the Navigator Part
        MPart navigatorPart = (MPart) modelService.find("com.mundiaurum.part.navigator", application);
        selectionService.setSelection(navigatorPart);
    }

    @CanExecute
    public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) IStructuredSelection selection,
        @Named(IServiceConstants.ACTIVE_PART) MPart part) {
        if (selection == null)
            return false;
        if (part == null)
            return false;
        if (selection.getFirstElement() instanceof Package) {
            Package pack = (Package) selection.getFirstElement();
            return pack.isReadyToSendProposal();
        }
        return false;
    }

}

The button is enabled/disabled smooth when the user changes the selection by clicking on any part of the application.

When the user click on Send Proposal button, the package is removed from the Navigator View, also the package is removed from the model, but the button is still enabled. (next picture shows scenario after Send Prosal Button is pressed on Package 12).

enter image description here

The issue is that the StructuredSelection is still keeping a reference of the package previous sent (and removed from model), and hence when @canExecute is evaluated the method returns true.

I tried to set the StrucuturedSelction to the Navigator Part, to null, etc...

But since the button is enabled if click on it immediately the following error is thrown:

org.eclipse.core.commands.ExecutionException: com.myapp.handlers.SendProposalHandler handler is missing @Execute
    at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:160)
    at org.eclipse.core.commands.Command.executeWithChecks(Command.java:488)
    at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:487)
    at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:213)
    at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.executeItem(HandledContributionItem.java:438)
    at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.handleWidgetSelection(AbstractContributionItem.java:449)
    at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.lambda$2(AbstractContributionItem.java:475)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
    at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5879)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1427)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:5121)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4599)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1157)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1046)
    at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155)
    at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:168)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:654)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1462)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1435)
Caused by: org.eclipse.core.commands.NotHandledException: org.eclipse.e4.core.commands.internal.HandlerServiceHandler
    at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:161)
    ... 29 more

How can I modify the StructuredSelection in order to disable the button when the selected element is deleted from the model?

J Robes
  • 467
  • 1
  • 6
  • 19
  • Note: TreeViewer has a addSelectionChangedListener, there should be no need to mess around with Tree addSelectionListener like that. – greg-449 Oct 22 '21 at 10:53
  • This is hard to follow from the various bits of code. Your handler uses `IServiceConstants.ACTIVE_SELECTION` - so how are you connecting your viewer to `ESelectionService` to make that work? How are you updating the view when you remove items from the model? – greg-449 Oct 22 '21 at 11:04
  • I have not connection between viewer and ESelectionService. I dont know how to impelment it. To update de view when the items are removed is done by meas of the EventBroker (I have edited que question to show the event broket at the viewer and at the modelService class) – J Robes Oct 22 '21 at 12:08
  • If you aren't using ESelectionService I don't see how you are getting IServiceConstants.ACTIVE_SELECTION to work at all. You use the selection service to set the active selection for the MPart (assuming this is really just e4 not compatability mode using ViewPart) – greg-449 Oct 22 '21 at 13:20
  • Also is the view handling the `MundiaurumEventConstants.PROPOSAL_SENT` event and updating the viewer? – greg-449 Oct 22 '21 at 13:23
  • IServiceConstants.ACTIVE_SELECTION is injected into SendProposal handler at both @execute and @canExecuted methods. I have tried to use the seleciton service as follows: `MPart navigatorPart = (MPart) modelService.find("com.mundiaurum.part.navigator", application); selectionService.setSelection(navigatorPart);` but had not effect. I have edited the question to include how it is handled the `MundiaurumEventConstants.PROPOSAL_SENT` at both viewer and model. – J Robes Oct 22 '21 at 13:59
  • That is not how the selection service works, you must call setSelection with the structured selection from the viewer every time the selection changes. You would do that in the method specified by viewer addSelectionChangedListener – greg-449 Oct 22 '21 at 14:31
  • I have modified my SelectionChangedListener to include the two followinglines in the Viewer Part and works fine. Thanks!: `selectionService.setSelection(viewer.getStructuredSelection()); broker.post(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, UIEvents.ALL_ELEMENT_ID);` – J Robes Oct 22 '21 at 16:35

0 Answers0