0

When I use my keybinds, they work just fine. But the minute I hold shift and try to use keybinds, my computer doesn't detect that keys are being pressed/changed. Also, when trying to detect if shift is being pressed/released, it seems like nothing happens.

package main;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.KeyStroke;

public class Input 
{

    private InputMap im;
    private ActionMap am;

    public Input(JComponent component)
    {
        im = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        am = component.getActionMap();

        im.put(KeyStroke.getKeyStroke("released ESCAPE"), "exitGame");
        am.put("exitGame", new AbstractAction()
                {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public void actionPerformed(ActionEvent e)
                    {
                        System.exit(0);
                    }
                });
    }

    public void createKey(String key, AbstractAction action)
    {
        String command = key + "Action";
        im.put(KeyStroke.getKeyStroke(key), command);
        am.put(command, action);
    }

    public void createKey(int key, boolean released, AbstractAction action)
    {
        String command = key + "Action";
        im.put(KeyStroke.getKeyStroke(key, 0, released), command);
        am.put(command, action);
    }

}
public void keyInput(Input input)
    {
        input.createKey("A", new MoveAction(Direction.LEFT, false));
        input.createKey("released A", new MoveAction(Direction.LEFT, true));
        input.createKey("D", new MoveAction(Direction.RIGHT, false));
        input.createKey("released D", new MoveAction(Direction.RIGHT, true));

//Added this for testing purposes, but without it, holding shift down seems to stop all other inputs.
        input.createKey(KeyEvent.VK_SHIFT, false, new AbstractAction()
            {
                @Override
                public void actionPerformed(ActionEvent e) {
                    sprint = true;
                    System.out.println("Test!"); //THIS LINE NEVER APPEARS.
                }
            });
        input.createKey(KeyEvent.VK_SHIFT, true, new AbstractAction()
            {
                @Override
                public void actionPerformed(ActionEvent e) {
                    sprint = false;
                }
            });
    }

(The keyInput method is part of a seperate class.)

  • 1
    [Shift] is a "modifier", so it's a seperate binding – MadProgrammer Jul 25 '19 at 02:09
  • @MadProgrammer Right I've read this online, that's why i implemented a seperate createKey() method that takes an integer as a parameter (Apparently using KeyEvent.VK_SHIFT solves this) but even with this it doesn't work. Also I don't understand why holding it causes my other keys to stop taking input – HelpMeImStuck Jul 25 '19 at 02:39
  • Basically, you’re saying when “key A is pressed do something”, but, when you press A & shift together, you’re getting a different key stroke, which doesn’t meet what you’ve asked for – MadProgrammer Jul 25 '19 at 03:02
  • Remember, there is a difference between “a” and “A”, maybe have a look at https://stackoverflow.com/questions/15605109/java-keybinding-plus-key/15605266?r=SearchResults#15605266 – MadProgrammer Jul 25 '19 at 03:09
  • Ahh I see, thank you! – HelpMeImStuck Jul 26 '19 at 00:31

1 Answers1

0

A key stroke is made up of a number of parts. The key code which generated the event, zero or more modifiers, which can change the meaning of the key code, and if it was pressed or released.

A individual key stroke could have different meaning based on the modifiers, for example Shift will change a to A or 1 to !.

This makes Shift+a different from just a. When you also consider that you have Ctrl, Alt, Wnd and Cmd as well and they can be combined together, this gives every key a large number of additional possible meanings.

Key bindings are fun. You can define a single action and apply it to multiple key stroke configurations

For example, we could start with...

InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();

am.put("left", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent arg0) {
        label.setText("left");
    }
});
am.put("right", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent arg0) {
        label.setText("right");
    }
});
am.put("released", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent arg0) {
        label.setText("---");
    }
});

This defines three actions which can be executed, left, right, released. Each one simply changes the the text of JLabel to some state, but you get the idea.

Then you can apply these actions to multiple key strokes, for example...

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false), "left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.SHIFT_DOWN_MASK, false), "left");

So, pressing a or Shift+a will trigger the left action

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "right");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, KeyEvent.SHIFT_DOWN_MASK, false), "right");

Pressing d or Shift+d will trigger the right action

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true), "released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.SHIFT_DOWN_MASK, true), "released");

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, true), "released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, KeyEvent.SHIFT_DOWN_MASK, true), "released");

and releasing any four of those keys will generate the released action

Runnable example...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JLabel label = new JLabel("---");

        public TestPane() {
            setLayout(new GridBagLayout());
            add(label);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            am.put("left", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    label.setText("left");
                }
            });
            am.put("right", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    label.setText("right");
                }
            });
            am.put("released", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    label.setText("---");
                }
            });

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false), "left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.SHIFT_DOWN_MASK, false), "left");

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "right");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, KeyEvent.SHIFT_DOWN_MASK, false), "right");

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true), "released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.SHIFT_DOWN_MASK, true), "released");

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, true), "released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, KeyEvent.SHIFT_DOWN_MASK, true), "released");
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366