Are there any benefits or drawbacks to creating a nested class that implements ActionListener:
public class Foo{
Foo(){
something.addActionListener(new ButtonListener());
}
//...
private class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//...
}
}
}
versus implementing ActionListener in the main class itself:
public class Foo implements Act开发者_Go百科ionListener{
Foo(){
something.addActionListener(this);
}
//...
public void actionPerformed(ActionEvent e){
//...
}
}
I've seen both examples quite often, and just want to know if there's a 'best practice.'
@Ankur, you can still use anonymous inner classes as your listeners and have a separate free-standing control class and thus have code that's quite maintainable, a technique I like to use a bit. For example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AnonymousInnerEg {
private static void createAndShowUI() {
GuiPanel guiPanel = new GuiPanel();
GuiControl guiControl = new GuiControl();
guiPanel.setGuiControl(guiControl);
JFrame frame = new JFrame("AnonymousInnerEg");
frame.getContentPane().add(guiPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class GuiPanel extends JPanel {
private GuiControl control;
public GuiPanel() {
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (control != null) {
control.startButtonActionPerformed(e);
}
}
});
JButton endButton = new JButton("End");
endButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (control != null) {
control.endButtonActionPerformed(e);
}
}
});
add(startButton);
add(endButton);
}
public void setGuiControl(GuiControl control) {
this.control = control;
}
}
class GuiControl {
public void startButtonActionPerformed(ActionEvent ae) {
System.out.println("start button pushed");
}
public void endButtonActionPerformed(ActionEvent ae) {
System.out.println("end button pushed");
}
}
I think first approach is better, as your class will have a separate code for handling action. And usually also composition is better than inheritance so a class should extend a class or implement a interface only if it truly is-a super type.
Also for maintainability, let us say Foo class has a new requirement to listen for another different type of events and then perform action, in that case also first class can be easily modified.
If I am not worried about maintainability I would rather go for a anonymous class.
If the class Foo has no other responsibility than encapsulating this button, then the first solution is sort of ok.
However, as soon as Foo gets more "somethings" that it has to listen to then it gets messy. I prefer the second solution since it is more explicit and has a better scalability.
An even better solution may be to create an anomymous inner class.
public class Foo{
Foo(){
something.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
//...
}
});
}
}
Usually you want to use a nested or even anonymous class rather than exposing ActionListener to the API of the enclosing class. (public class Foo implements ActionListener -> Javadoc will state that Foo is an ActionListener, though this is usually just an implementation detail -> bad)
精彩评论