Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[e4-dev] Feedback from a frustrated user on the @(Can)Execute API

Dear e4 Developers,

I hope this is the right venue for this (as opposed to the Eclipse 4
forum or Bugzilla).

I just like to share a very frustrating experience I had trying to
accomplish a seemingly simple task: Implementing a check-type menu item
whose value is synchronized with a preference. For simplicity, I choose
a Direct Menu Item with the following "handler":

  class MyHandler {

    @PostConstruct
    void init(MMenuItem item, @Preference(MY_PREF) boolean selected) {
      item.setSelected(selected);
    }

    @Execute
    void exec(MMenuItem item, @Preference IEclipsePreferences prefs) {
      prefs.putBoolean(MY_PREF, item.isSelected());
    }
  }

The above looks downright *elegant*, with the @Preference annotation and
all. Unfortunately, it doesn't work; the @PostConstruct method cannot be
called since the context does not *yet* contain the MMenuItem for my
handler.

One StackOverflow question [1] later, I've converted the above to a
"solution" using @CanExecute:

  class MyHandler {

    @CanExecute
    void can(MMenuItem item, @Preference(MY_PREF) boolean selected) {
      item.setSelected(selected);
      return true;
    }

    @Execute
    void exec(MMenuItem item, @Preference IEclipsePreferences prefs) {
      prefs.putBoolean(MY_PREF, item.isSelected());
    }
  }

Using @CanExecute for this seems like a hack, as I don't really
determine the handler's executability; I merely want to synchronize the
MMenuItem with the preference and, unlike in @PostConstruct, now the
context contains my handler's associated MMenuItem.

Unfortunately, the above still doesn't work -- and it's not obvious (to
me, at least) why!

The problem with the second "solution" is that the menu item's selection
state is seemingly "stuck" at the preference's initial value. The root
cause is that the @CanExecute is executed twice: First when the menu is
created. Then after the user has clicked on the item, at which point in
time the selection state has already changed -- and gets reset in
@CanExecute.

My final solution looks hence like this:

  class MyHandler {

    boolean prefSynced = false;

    @CanExecute
    void can(MMenuItem item, @Preference(MY_PREF) boolean selected) {
      if (!prefSynced) {
        item.setSelected(selected);
        prefSynced = true;
      }
      return true;
    }

    @Execute
    void exec(MMenuItem item, @Preference IEclipsePreferences prefs) {
      prefs.putBoolean(MY_PREF, item.isSelected());
    }
  }

Granted, that's still not a lot of code, but how to get there was far
from obvious.

I hope this (lengthy) story helps you to further improve the Eclipse 4
API; despite episodes like the above, it has generally been a pleasant
experience.

Best wishes,

Andreas

[1] <stackoverflow.com/questions/42575661/>

-- 
Codetrails GmbH
The knowledge transfer company

Robert-Bosch-Str. 7, 64293 Darmstadt
Phone: +49-6151-276-7092
Mobile: +49-170-811-3791
http://www.codetrails.com/

Managing Director: Dr. Marcel Bruch
Handelsregister: Darmstadt HRB 91940

Attachment: signature.asc
Description: OpenPGP digital signature


Back to the top