Mike said:
Inner classes. Their most common uses are handled much more
intuitively by method pointers.
Including iterators? These "method pointers" would have to be able to
carry a context with them that was distinct for each invocation of the
method-pointer-returning method. I.e. would have to be closures.
Anonymous inner classes perhaps.
Allowing function literals and use of static methods as
first-class-object functions would let you get rid of many of the
commonest anonymous inner classes -- Runnable, ActionListener, etc. --
but the multi-method event listeners would need to be handled
differently. Preferably by deprecating the lot of them and adding a new
event framework that puts all of the important information in the event
objects, has more separated events, and so forth. And gets rid of event
component getting. That leads to lots of ugly code, switches,
instanceofs, and casts included.
My usual pattern of use of event listeners is to use two different ones
where I want two different behaviors. So if button A should do X and
button B should do Y, I don't have
public void actionPerformed (ActionEvent e) {
Component c = // etc.
if (c == buttonA) doX();
if (c == buttonB) doY();
// etc.
}
but rather a button A action listener and a separate button B action
listener.
So which component can be inferred by which listener we're in.
For ActionEvent, this means I tend never to even refer to the event
object. A simple "somethingGotClicked()" callback with no args would
have done as well, methinks.
For other listeners ...
Well, consider WindowListener.
void windowOpened(WindowEvent e);
void windowClosing(WindowEvent e);
void windowClosed(WindowEvent e);
void windowIconified(WindowEvent e);
void windowDeiconified(WindowEvent e);
void windowActivated(WindowEvent e);
void windowDeactivated(WindowEvent e);
and WindowFocusListener
void windowGainedFocus(WindowEvent e);
void windowLostFocus(WindowEvent e);
and WindowStateListener
void windowStateChanged(WindowEvent e);
The latter supersedes windowIconified and windowDeiconified from
WindowListener, and puts all information needed in the event.
WindowFocusListener's methods likewise supersede windowActivated and
windowDeactivated. They could be combined into a single method,
windowFocusChanged(boolean nowFocused), with the focus state change in a
parameter, or encoded in an event object if that model was kept.
That leaves WindowListener with windowOpened, windowClosing, and
windowClosed.
The semantics of these are tricky and sometimes wacky.
A windowOpened that is only called once when a window is first
constructed might as well just be inlined in the code that builds the
window. This could stand to go away. Right now its only use is if a
window is constructed but not immediately shown, and something is lazily
initialized only when it's shown. The showing code can as easily lazily
create the whole damn window when it's first shown, e.g. by invoking a
singleton-returning factory method (if there's only going to be the one
window in the app), or (if it isn't supposed to preserve state across
user-visible instances) create a new one each time and dispose it when done.
Getting rid of that leaves windowClosing and windowClosed. Closing has
tricky semantics -- is it hiding-or-disposing or only disposing? Does it
count if the close box is clicked but the window has DO_NOTHING_ON_CLOSE
set?
I'd redesign this so that there was a WindowCloseButtonListener and the
options were DO_NOTHING_ON_CLOSE (greys the "X" button), HIDE_ON_CLOSE,
DISPOSE_ON_CLOSE, and a new one, GENERATE_EVENT_ON_CLOSE. Setting this
last would make the "X" button enabled and cause it to call a
WindowCloseBoxListener when clicked. This could hide or dispose the
window, return without doing either, pop up a "you have unsaved changes?
are you sure?", or whatever, at the coder's pleasure, more or less as
windowClosing is currently used. The other choices would behave exactly
like (and be implemented under the hood as) a listener that just does a
setVisible(false) or a dispose(), aside from DO_NOTHING, which disables
the button.
(And there really should be obvious ways to enable/disable the maximize
and, separately, the minimize buttons, too. Affecting their
corresponding window-icon-menu items. With appropriate translations to
other platforms.)
And we're left with windowClosed, which might be made the sole method of
a WindowCloseListener. This would run if a window was hidden or
disposed, and get a boolean parameter or an event object containing a
boolean that was "true" if the window was disposed.
That's the window listeners (and the old ones would be preserved, with
their present semantics, for compatibility purposes, but deprecated).