I am going to be developing a game in Java, and it will have many listeners( action, key, mouse, etc..).
My Question is what is the preferable way to implement the listeners.
Method 1:
this.addActionListener(new ActionListener() {
   // Overide methods go here
});
Method 2:
create a new class(or multiple classes) which will implement ActionListener and have the methods for the different Game Componenets (buttons, movement, whatever else needs an ActionListener)
So, for instance. If I am making a button is it better to do
JButton button = new JButton();
button.addActionListener(new ActionListener() {
});
or
JButton button = new JButton();
button.addActionListener(new MyActionListener());
// MyActionListener
class MyActionListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        Object objectPressed = e.getSource();
        if(objectPressed.equals(button) {
          System.out.println("Hello World");
        }
    }
}
I can see advantages in both ways, Method 1 you can see what is happening to that object directly, but method 2 you can see all components.
So when developing large scale applications, which is easier to maintain, having all listeners in separate classes, or using Method 1?
Personally, I would prefer many Listeners to one with "if" checks. It would allow me to modify them independently.
I would embed that code inside the UI. I'd write them as separate classes and inject them as dependencies using constructor or DI factory.
Constructor injection:
public class YourPanel extends JPanel {
    private JButton button;
    public YourPanel(ActionListener buttonListener) {
        this.button = new JButton("Do It");
        this.button.addActionListener(buttonListener);
    }
}
                        Just to add one more stick to this fire, myself, I prefer to use AbstractActions, either as an anonymous inner class, or more often as an independent stand-alone class:
JButton myExitButton = new JButton(new MyExitAction());
As an example, a Control class that is part of an MVC Swing project of mine has this as part of its code:
public class Control {
   // these two types below are interfaces
   private Model model;
   private View view;
   public Control(Model model, View view) {
      this.model = model;
      this.view = view;
      addViewListeners();
   }
   private void addViewListeners() {
      view.setGetPageAction(new GetPageAction(this, "Get Page", KeyEvent.VK_G));
      view.setSetTnRendererBtnAction(new SetTnRendererBtnAction(this, "Show Images", KeyEvent.VK_S));
      view.setClearThumbNailsAction(new ClearThumbNailsAction(this, "Clear ThumbNails", KeyEvent.VK_C));
      view.setSetDestinationAction(new SetDestinationAction(this, "Set Destination", KeyEvent.VK_T));
      view.setDownloadAction(new DownloadAction(this, "Download", KeyEvent.VK_D));
      view.setExitAction(new ExitAction(this, "Exit", KeyEvent.VK_X));
      model.addPropertyChangeListener(new ModelListener());
   }
   public View getView() {
      return view;
   }
   public Model getModel() {
      return model;
   }
   // .....
}
And the abstract class that underlies all of my AbstractActions looks like so:
public abstract class MyAbstractAction extends AbstractAction {
   protected Control control;
   protected Model model;
   protected View view;
   public MyAbstractAction(Control control, String txt, int mnemonic) {
      super(txt);
      putValue(MNEMONIC_KEY, mnemonic);
      this.control = control;
      this.model = control.getModel();
      this.view = control.getView();
   }
}
One caveat: Note that I'm not a professional programmer but rather a hobbiest, and so while my ideas work for me, they may not represent the absolute best in the field. All corrections and advice are most welcome. A weakness to my design above is that I think that I'm "injecting" my Actions in a clumsy way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With