I wanted to do something with a closure where my action listener didn’t have to know what events to use… e.g. normally, you’d tell the implemented ActionListener that if (event.name) == “bob” or whatever then perform an action
in this case, we’re going to use a simple ActionListener that doesn’t care about the event, just does whatever we tell it.
In this case, I want my swing ActionListener on a button to printout information to the console. Normally, I’d just tell the ActionListener System.out.println(“text”). We’re going to do something a little different.
We’re going to declare an ActionListener that has no idea what it’s doing until we tell it in the main code and not anywhere else. Basically, our implementation is “blind” in a way. It doesn’t care what it gets as long as we have told it what to do.
We’ll start with GButton extending JButton
import javax.swing.JButton
public class GButton extends JButton {
/**
* Construct a new ‘anonymous’ action
* and register it with the button.
*/
public void addActionListener(Closure code) {
addActionListener(new GAction(code));
}
as you can see, we’ve overloaded addActionListener so it takes a Closure, that then places an AbstractAction into the Button.
The GAction implements ActionListener
import javax.swing.AbstractAction;
import java.awt.event.ActionEvent;
import groovy.lang.Closure;
public class GAction extends AbstractAction {
Closure code;
GAction(Closure c) { code= c; }
public void actionPerformed(ActionEvent e) { code(); }
}
This is a little confusing, but not really. What we’ve done is overload the constructor to take a closure that we’re going to set locally. When the actionPerformed is called it will simply run the closure code. Make sense? Instead of hardcoding our action in another class, we’ve given a virtual call, more or less.
import javax.swing.JFrame; import javax.swing.JButton;
def f = new JFrame();
def b = new GButton();
b.setText(“press me”);
b.addActionListener{ println ‘hello world’ } // <– cool!
f.getContentPane().add(b);
f.pack()
f.show()
f.setVisible(true);
Here, as you can see, we’ve put this into action.
When the actionListener is called by the button, it will printout hello world to hte console. You could do anything… like have it call another class, or whatever. Doesn’t matter… just another example of how Groovy is awesome
One Reply to “kind of MetaClass-y”