Dynamic Enablement Without Lookup

Normally, dynamic enablement of Actions in the NetBeans Platform is achieved through observing the state of Objects in the Lookup, as described in How to Make the NetBeans Platform Sensitive to Customers.

However, you don't always have a context, e.g, when you have an Action that displays some kind of dialog for logging into something. When the user has been successfully logged in, you want the related Action to be disabled, since there's no point in logging in again. In this case, you could set up a scenario where you have a User object that has a property "loggedIn" or something like that, publish it into the Lookup, and then react when the property changes.

A simpler approach is as follows, read in particular the comments in bold within the code:

import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.AbstractAction;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle.Messages;

@ActionID(
        category = "Edit",
        id = "org.feature.login.LoginAction"
)
@ActionRegistration(
        displayName = "not-used",
        lazy = false
)
@ActionReference(path = "Menu/File", position = 0)
public final class LoginAction extends AbstractAction implements PropertyChangeListener {

    Login login;

    @Messages("CTL_LoginAction=Login")
    public LoginAction() {
        super(Bundle.CTL_LoginAction());
        login = new Login();
        login.addPropertyChangeListener(this);
    }

    @Messages({
        "CTL_LoginFormTitle=Login Form",
        "CTL_LoginFormLabel=Login:"})
    @Override
    public void actionPerformed(ActionEvent e) {
        NotifyDescriptor.InputLine input = new NotifyDescriptor.InputLine(
                Bundle.CTL_LoginFormLabel(),
                Bundle.CTL_LoginFormTitle());
        Object result = DialogDisplayer.getDefault().notify(input);
        if (NotifyDescriptor.YES_OPTION.equals(result)) {
            //If the user's name is 'Tom', disable the Login object,
            //which will fire a property change event,
            //where the Action's enable/disable state
            //will match the Login object,
            //which will disable the related menu item and/or toolbar button:
            if (input.getInputText().equals("Tom")) {
                login.setLoggedIn(false);
            } else {
                login.setLoggedIn(true);
            }
        }
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        setEnabled(login.isLoggedIn());
    }

    private class Login {
        private boolean isLoggedIn = false;
        public static final String PROP_ISLOGGEDIN = "isLoggedIn";
        public boolean isLoggedIn() {
            return isLoggedIn;
        }
        public void setLoggedIn(boolean loggedIn) {
            boolean oldIsLoggedIn = this.isLoggedIn;
            this.isLoggedIn = loggedIn;
            propertyChangeSupport.firePropertyChange(PROP_ISLOGGEDIN, oldIsLoggedIn, loggedIn);
        }
        private transient final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
        public void addPropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.addPropertyChangeListener(listener);
        }
        public void removePropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.removePropertyChangeListener(listener);
        }
    }

}

Comments:

The setEnabled you call from the property change listener should be called from EDT (SwingUtilities.invokeLater...) since it enables or disables the Swing component (button or menu entry) of the action.

Posted by Simon on December 05, 2013 at 07:25 AM PST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« July 2014
SunMonTueWedThuFriSat
  
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today