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