# Java: Managing KeyListeners for different states

## Recommended Posts

Sirveaux    122
I'm having trouble deciding which is the best way to go with this. My game has a few different interfaces that the player interacts with. The normal moving around the world interface, the shopping interface, and the battle interface. Currently, my main applet class is set as the KeyListener. One way I could handle the different input for the various states is to just have a big switch statement in the key events for the applet's class that checks a state flag and processes the input there. Or, I could set up an object for each interface and make them KeyListeners that are added and removed, depending on what the player is doing. Or, I could still just use the applet's class as the keylistener, check the state flag and then manually call the KeyPressed/KeyReleased methods from within those methods in the main class. In other words: Option 1: (within my applet class)
public void KeyPressed (KeyEvent e) {
switch (state) {
case STATE_MOVEMENT:
// process key event
case STATE_BATTLE:
// process key event
...
}
}


Option 2: I'd have a few classes classes (MovementKeyListener, BattleKeyListener, ShoppingKeyListener, etc), each one interfacing KeyListener. When the player enters a battle, for example, the MovementKeyListener object would be removed and the BattleKeyListener would be added. Option 3: Like option #2, but without adding/removing any KeyListeners.
public void KeyPressed (KeyEvent e) {
switch (state) {
case STATE_MOVEMENT:
MovementKeyListener.KeyPressed(e);
case STATE_BATTLE:
BattleKeyListener.KeyPressed(e);
...
}
}


Assuming you can make any sense of what I tried to say there, which would be the better way to go (if any)? Or does it really matter? I'd prefer not to have all of the key events handled within the main class just for organization's sake. So I'm thinking either option 2 or 3.

##### Share on other sites
Promit    13246
I think the basic idea of Option #3 is a good idea. You don't want to use #1 as it'll get messy very fast, and #2 is bad because you want to minimize interaction with Java's windowing components as much as possible.

Now, it would be great if we could get rid of the switch statement and implement some sort of registration based system. if you're interested in that, just say so and I'll detail what you would do for registration based systems, if you want.

##### Share on other sites
Sirveaux    122
Hmm. Registration? I'm not exactly sure what you mean, but if you think it could be a better/cleaner approach, I'd like to see it.

##### Share on other sites
Zahlman    1682
Option 3 is a bad idea, you are (a) manually implementing the dispatch that polymorphism is supposed to already be doing for you, and (b) manually calling callback methods (bad mojo).

Option 1 is the sort of thing you really only want to do if you're in a really space-constrained environment and can't afford to make extra classes (read: mobile).

Option 2 looks the most like how KeyListeners are supposed to be treated, but as mentioned you may not want to be adding/removing them all the time.

There is a modification you can make, of course; just add another layer of indirection:

- Applet adds a KeyListenerWrapper as its KeyListener, which implements KeyListener by delegating to a member KeyListener.

- Upon state changes, you send the KeyListenerWrapper a message like changeHandling(new MovementKeyListener()). The KLW responds by setting its member to the input KL, and the old one gets garbage-collected. You don't need to remember "add" or "remove", you just "set" on each change.

- When a key is pressed, the Applet sends the message to KLW, which sends it to the wrapped object. Because of the indirection, you don't mess directly with the windowing component.