What's the deal with Delegates?
button.addMousePressedListener(this) or something to that effect.
This saves us from the old dilemma: Do I add an inner class that extends MouseAdapter , or do I implement MouseListener with a bunch of empty callback methods? Frankly I see nothing wrong with using an inner class, since I like avoiding exposing the public callback method because it allows it to be called in cases other than event notification. C# poeple, however, seem to want to do the method hiding without the inner class. Sometimes I feel the same way.
I will first address the issue of wanting only a single callback method. Let me start with a simple interface, MouseMotionListener. I first create 2 new interfaces:
public interface MouseMovedListener extends EventListener {
public void mouseMoved(MouseEvent e);
}
public interface MouseDraggedListener extends EventListener {
public void mouseDragged(MouseEvent e);
}
Now we need a class to create an interface between them and the original interface:
Yeah, we could split it up into 2 separate classes, but that wouldn't be cute. (OK, there's one situation in which it would be useful: if a class implements more than one of these new interfaces, a cast would be required in the constructor to disambiguate. But in such a case, probably the traditional listener interface would be more appropriate than these single-method ones.)
Now we use it like this:
public class MouseMotionDelegateAdapter implements MouseMotionListener {
private MouseDraggedListener _mouseDragged;
private MouseMovedListener _mouseMoved;
public MouseMotionDelegateAdapter(MouseDraggedListener mouseDragged) {
_mouseDragged = mouseDragged;
}
public MouseMotionDelegateAdapter(MouseMovedListener mouseMoved) {
_mouseMoved = mouseMoved;
}
public void mouseDragged(MouseEvent e) {
if (_mouseDragged != null) {
_mouseDragged.mouseDragged(e);
}
}
public void mouseMoved(MouseEvent e) {
if (_mouseMoved != null) {
_mouseMoved.mouseMoved(e);
}
}
}
public class Example implements MouseMovedListener {
public Example() {
JButton button = new JButton();
button.addMouseMotionListener(new MouseMotionDelegateAdapter(this));
// and so forth
}
public void mouseMoved(MouseEvent e) {
// Do something useful.
}
}
Now, to address the issue of private callbacks. Java's solution is to use inner classes, even if the class has one method that just calls a private method in the containing class. To be more delegate-like, one would want a wrapper class that calls the private methods, based on their signatures. We can easily do this using reflection, but unfortunately Java does not give us compile-time signature checking outside of interfaces. However, since the XXX.class syntax gave us a compile-time replacement for Class.forName("XXX"), why cannot we have compile-time versions of other reflections?
Actually, this is what C# appears to do, and it is just a small bit of syntactic sugar.
It would differ slightly from the class object references, in that it would deal with a signature rather than the Method object itself. Something like:
where
public CallbackWrapper(method(String, int) privateCallbackMethod) {
}
method is a keyword and the argument list following it is a signature reference, and the whole thing is treated as a pseudotype. Kind of a combination of how generics work and syntax eerily similar to AspectJ.
OK, maybe it's not so simple. But I bet it's coming -- in Java 1.6 (or, as I am hoping for, 2.0).
- Login or register to post comments
- Printer-friendly version
- javaerb's blog
- 406 reads





