This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 179814 - DropDownButtonFactory buttons do not honor action enablement
Summary: DropDownButtonFactory buttons do not honor action enablement
Status: RESOLVED WONTFIX
Alias: None
Product: platform
Classification: Unclassified
Component: Window System (show other bugs)
Version: 6.x
Hardware: PC Windows XP
: P3 normal (vote)
Assignee: issues@platform
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-01-23 21:32 UTC by _ tboudreau
Modified: 2012-12-11 16:07 UTC (History)
0 users

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description _ tboudreau 2010-01-23 21:32:19 UTC
Create a JButton using DropDownButtonFactory, in an implementation of Presenter.Toolbar.

Call setAction(this) on the button.

The button tracks the enabled state of the action, but the popup menu and its contents are enabled all the time.  This requires any code that does context aware popup button actions to do extra bookkeeping.  See the code below - the WeakSet of Actions from the popup menu should not be needed.

public class MyAction extends AbstractAction implements ContextAwareAction,
                                                        Presenter.Toolbar,
                                                        LookupListener {
  private final Lookup lkp;
  private Lookup.Result<? extends DataObject> res;
  private Set<Action> popupMenuActions = new WeakSet<Action>();

  public MyAction() {
    this(Utilities.actionsGlobalContext());
  }

  private MyAction(Lookup lkp) {
    this.lkp = lkp;
    Icon icon = ImageUtilities.image2Icon(
            ImageUtilities.loadImage("com/foo/icon.gif"));
    putValue(SMALL_ICON, icon);
    //set the initial enabled state
    setEnabled(false);
  }

  @Override
  public Action createContextAwareInstance(Lookup lkp) {
    return new MyAction(lkp);
  }

  @Override
  public void resultChanged(LookupEvent le) {
    setEnabled(!res.allItems().isEmpty());
  }

  @Override
  public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
    boolean startListening = getPropertyChangeListeners().length == 0;
    super.addPropertyChangeListener(l);
    if (startListening) {
      res = lkp.lookupResult(DataObject.class);
      res.addLookupListener(this);
    }
  }

  @Override
  public synchronized void removePropertyChangeListener(PropertyChangeListener l) {
    super.removePropertyChangeListener(l);
    if (getPropertyChangeListeners().length == 0) {
      res.removeLookupListener(this);
      res = null;
    }
  }

  @Override
  public Component getToolbarPresenter() {
    JPopupMenu menu = new JPopupMenu();
    Action actionOne = new DemoMenuAction("One");
    Action actionTwo = new DemoMenuAction("Two");
    menu.add(new JMenuItem(actionOne));
    menu.add(new JMenuItem(actionTwo));
    popupMenuActions.add(actionOne);
    popupMenuActions.add(actionTwo);
    //add action listeners to the menu items to do what you want
    Icon icon = (Icon) getValue(SMALL_ICON);
    JButton result = DropDownButtonFactory.createDropDownButton(icon, menu);
    result.setAction(this);
    return result;
  }
  
  @Override
  public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);
    for (Action a : popupMenuActions) {
      if (a != null) { //WeakSet iterator can return null
        a.setEnabled(enabled);
      }
    }
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    //if you want to do something when the left side of the popup
    //button is clicked, do it here
  }

  private class DemoMenuAction extends AbstractAction {
    DemoMenuAction(String name) {
      putValue(NAME, name);
      setEnabled (MyAction.this.isEnabled());
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      DataObject ob = res.allInstances().iterator().next();
      DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
              ob.getName()));
    }
  }
}
Comment 1 Stanislav Aubrecht 2012-12-11 16:07:23 UTC
(In reply to comment #0)
> Create a JButton using DropDownButtonFactory, in an implementation of
> Presenter.Toolbar.
> 
> Call setAction(this) on the button.
> 
> The button tracks the enabled state of the action, but the popup menu and its
> contents are enabled all the time.  
But there are use cases where (some) actions in the dropdown menu should be enabled even though the default button is disabled (e.g. NetBeans Debug button).
Feel free to provide a patch and reopen, thanks.