How to notify ActionGuards

Hello,

I’ve been running with some custom buttons in my CDockables, and this is working nicely.

I’ve added support for making some buttons invisible depending on some [app internal] state of the CDockable.
(I override and use the ActionGuard’s react() method to do this)

This works, but it only updates the buttons when a user changes the state - e.g. minimize etc.

Is there a way to programatically notify the dockable so that it calls all registered ActionGuards’ react()?

Thanks!
midiman

No, but actions can appear/disappear at any time through the DockActionSource your ActionGuard returns (so you still need the ActionGuard). The typical solution would be

  • either to give your application/CDockable access to the DockActionSource such that they can add or remove actions when necessary.
  • or to implement a custom DockActionSource that adds or removes DockActions when necessary. For example the DockActionSource could add some listeners to your application and react if one of them is triggered. Just don’t forget to remove the listeners when the source is no longer used, otherwise you have a memory leak.

To make life easier: you can use the same DockAction and the same DockActionSource for more than one Dockable. It would be perfectly legal for your ActionGuard to return always the same object.

Both solutions are used by the framework itself, but the second solution is used more often.

Hi,

Many thanks for your reply.

Re your suggestions - I have the controls adding/removing/working fine - I just need a way to tell the dockable (the title bar controls and associated ActionGuards, in particular) when something has changed in the app, rather than by a user pressing a button.
Kind of like a revalidate() call for swing.

When I press, say, the minimize button on the dockable, react() is called and the relevant button(s) are shown/not shown. Just need that behaviour, but without the minimize or button press.
Could I use a blank action, maybe? Would this call react()? How would I do that?

Thanks!
midiman

And you need to tell the framework about the change through an event to the DockActionSourceListener(s) that are added to your DockActionSource.

There is absolutely no way to force a call to react - a call to react is reserved to the event where the hierarchy (a.k.a location) of a Dockable changes. And probably even that might be removed in a future release.

Try something like this:

  private DefaultDockActionSource source = new DefaultDockActionSource();

  public DockActionSource getMySource(){
    return source;
  }

  public void onEvent(){
    if( ... ){
      source.add( action );
    }
    else{
      source.remove( action );
    }
  }
}

...

class MyActionGuard implements DockActionGuard{
  public boolean react( Dockable dockable ){
    return dockable instanceof MyDockable;
  }

  public DockActionSource getSource( Dockable dockable ){
    return ((MyDockable)dockable).getMySource();
  }
}```