therladbsgh
therladbsgh

Reputation: 71

Java key bindings with multiple actions

So for reference, I am following Trystan's roguelike tutorial for java.

The tutorial above uses Key Listeners, which does not work for Mac OS X (and appears to be discouraged by the community), so I am trying to change the code to use Key Bindings instead.

Here's the question. In his "roguelike game", the game is divided into screens, where each screen has separate actions for a particular key. For instance, the "Start Screen" sends the player to the "Play screen" upon pressing the enter key:

public class StartScreen implements Screen {

    public void displayOutput(AsciiPanel terminal) {
        terminal.write("rl tutorial", 1, 1);
        terminal.writeCenter("-- press [enter] to start --", 22);
    }

    public Screen respondToUserInput(KeyEvent key) {
        return key.getKeyCode() == KeyEvent.VK_ENTER ? new PlayScreen() : this;
    }
}

While the "Play Screen" sends the player to the "Win screen" upon pressing the enter key:

public class PlayScreen implements Screen {

    public void displayOutput(AsciiPanel terminal) {
        terminal.write("You are having fun.", 1, 1);
        terminal.writeCenter("-- press [escape] to lose or [enter] to win --", 22);
    }

    public Screen respondToUserInput(KeyEvent key) {
        switch (key.getKeyCode()){
        case KeyEvent.VK_ESCAPE: return new LoseScreen();
        case KeyEvent.VK_ENTER: return new WinScreen();
        }

        return this;
    }
}

Now, from what I can see from Key Bindings examples such as this and this, all the bindings and actions seem to be "dumped" into one class. This is unsatisfactory, because:

  1. One keystroke leads to only one action (I suppose I could have the action do a switch case, and check what screen I am in, and then execute some code specific to said screen, but perhaps there is a better way.)
  2. It becomes more difficult to determine what action is from/for what screen.

Would there be a way to get Key Bindings to have one keystroke execute different actions depending on the "Screen"? Would I just use conditionals? Can I put Key Binding logic in other classes (Screens) and then call them in the main class, like what is happening with Key Listeners above?

Upvotes: 0

Views: 499

Answers (1)

John Bollinger
John Bollinger

Reputation: 180201

Key bindings are not necessarily dumped into one class. They are associated with input maps, which in turn are associated with specific JComponents. If you register screen-specific bindings in the WHEN_ANCESTOR_OF_FOCUSED_COMPONENT input map of the JComponent representing that screen, then they will be recognized when any component in that screen has the keyboard focus (supposing a component in between has not overridden the binding with its own), but not when a component in a different screen has the focus.

Overall, the system is very flexible. You might consider reading the Java Tutorial section on this topic to bring yourself up to speed.

Upvotes: 2

Related Questions