Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 2 of 2

Thread: Two questions about key binding.

  1. #1
    Junior Member
    Join Date
    Jul 2012
    Posts
    4
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Two questions about key binding.

    1. With key binding, how do you make it so that when you press and hold TWO keys simultaneously, they do something? So far I can only get two keys to do something if they are typed (pressed and released without holding both).

    2. Is there a way to eliminate the delay when you switch between holding down one key to holding down another? I'm moving an image with the arrow keys, and when I switch from one arrow key to another, the image stops completely for about half a second.

    Here's the relevant code that I came up with so far:
          int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
          InputMap inputMap = getInputMap(condition);
          ActionMap actionMap = getActionMap();
     
          inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), UP);
          actionMap.put(UP, new AbstractAction() {
             public void actionPerformed(ActionEvent arg0) {
                shipy-=4;
                repaint();
             }
          });
     
          inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), DOWN);
          actionMap.put(DOWN, new AbstractAction() {
             public void actionPerformed(ActionEvent arg0) {
                shipy+=4;
                repaint();
             }
          });
     
          inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), RIGHT);
          actionMap.put(RIGHT, new AbstractAction() {
             public void actionPerformed(ActionEvent arg0) {
                shipx+=4;
                repaint();
             }
          });
     
          inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), LEFT);
          actionMap.put(LEFT, new AbstractAction() {
             public void actionPerformed(ActionEvent arg0) {
                shipx-=4;
                repaint();
             }
          });


  2. #2
    Member
    Join Date
    Jul 2012
    Posts
    83
    My Mood
    Cynical
    Thanks
    3
    Thanked 9 Times in 9 Posts

    Default Re: Two questions about key binding.

    When you press and hold a key, the operating system (OS) signals it's pressed, then there's a delay, then it repeatedly signals that it's pressed. I believe that this is all controlled by the OS and that there isn't a way to change this in Java. But having said that, you still can likely get what you want by starting a Swing Timer on key press and stopping it on key release, via key bindings of course, using the getKeyStroke method that accepts booleans as its last parameter.

    For example, here is code that I published in a thread on another forum that does a similar action:

    package yr12.m07.a;
     
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import java.util.HashMap;
    import java.util.Map;
    import javax.swing.*;
     
    public class KeyBindingsGuiTest {
       private static void createAndShowUI() {
          KeyBindingsGui guiPanel = new KeyBindingsGui();
     
          JFrame frame = new JFrame("KeyBindingsGuiTest");
          frame.getContentPane().add(guiPanel);
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
     
       public static void main(String[] args) {
          java.awt.EventQueue.invokeLater(new Runnable() {
             public void run() {
                createAndShowUI();
             }
          });
       }
    }
     
    @SuppressWarnings("serial")
    class KeyBindingsGui extends JPanel {
       private static final Dimension SIZE = new Dimension(600, 600);
       private static final int SPRITE_WIDTH = 26;
       private static final int SPRITE_HEIGHT = SPRITE_WIDTH;
       private static final int STROKE_WIDTH = 3;
       private static final Color SPRITE_COLOR = Color.red;
       private static final Color GUI_BCKGRD = Color.white;
       private static final String PRESSED = "Pressed";
       private static final String RELEASED = "Released";
       public static final int SPRITE_STEP = 8;
       private static final int SPRITE_STEP_PERIOD = 20;
       private BufferedImage sprite;
       private int spriteX = 0;
       private int spriteY = 0;
       private Map<Direction, Boolean> directionMap = new HashMap<Direction, Boolean>();
     
       public KeyBindingsGui() {
          setBackground(GUI_BCKGRD);
          setPreferredSize(SIZE);
          sprite = createSprite();
          spriteX = (SIZE.width - SPRITE_WIDTH) / 2;
          spriteY = (SIZE.height - SPRITE_HEIGHT) / 2;
     
          for (Direction direction : Direction.values()) {
             directionMap.put(direction, Boolean.FALSE);
          }
     
          setBindings();
          Timer timer = new Timer(SPRITE_STEP_PERIOD, new GameLoopListener());
          timer.start();
       }
     
       @Override
       protected void paintComponent(Graphics g) {
          super.paintComponent(g);
          if (sprite != null) {
             g.drawImage(sprite, spriteX, spriteY, null);
          }
       }
     
       private void setBindings() {
          int context = JComponent.WHEN_IN_FOCUSED_WINDOW;
          InputMap inputMap = getInputMap(context);
          ActionMap actionMap = getActionMap();
     
          for (Direction direction : Direction.values()) {
             inputMap.put(KeyStroke.getKeyStroke(direction.getKeyCode(), 0, false),
                   direction.getName() + PRESSED);
             inputMap.put(KeyStroke.getKeyStroke(direction.getKeyCode(), 0, true),
                   direction.getName() + RELEASED);
     
             // set corresponding actions for the key presses and releases above
             actionMap.put(direction.getName() + PRESSED, new ArrowKeyAction(true,
                   direction));
             actionMap.put(direction.getName() + RELEASED, new ArrowKeyAction(
                   false, direction));
          }
     
       }
     
       private BufferedImage createSprite() {
          BufferedImage sprite = new BufferedImage(SPRITE_WIDTH, SPRITE_HEIGHT,
                BufferedImage.TYPE_INT_ARGB);
          Graphics2D g2d = sprite.createGraphics();
          g2d.setStroke(new BasicStroke(STROKE_WIDTH));
          g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
          g2d.setColor(SPRITE_COLOR);
          g2d.drawOval(STROKE_WIDTH, STROKE_WIDTH, SPRITE_WIDTH - 2 * STROKE_WIDTH,
                SPRITE_HEIGHT - 2 * STROKE_WIDTH);
          g2d.dispose();
          return sprite;
       }
     
       private class ArrowKeyAction extends AbstractAction {
          private Boolean pressed;
          private Direction direction;
     
          public ArrowKeyAction(boolean pressed, Direction direction) {
             this.pressed = Boolean.valueOf(pressed);
             this.direction = direction;
          }
     
          @Override
          public void actionPerformed(ActionEvent arg0) {
             directionMap.put(direction, pressed);
          }
       }
     
       private class GameLoopListener implements ActionListener {
     
          public void actionPerformed(ActionEvent e) {
             int x0 = spriteX;
             int y0 = spriteY;
             for (Direction direction : Direction.values()) {
                if (directionMap.get(direction)) {
                   spriteX += SPRITE_STEP * direction.getVector().x;
                   spriteY += SPRITE_STEP * direction.getVector().y;
                }
             }
             int x = Math.min(x0, spriteX);
             int y = Math.min(y0, spriteY);
             int w = Math.max(x0, spriteX) - x + SPRITE_WIDTH;
             int h = Math.max(y0, spriteY) - y + SPRITE_HEIGHT;
             repaint(x, y, w, h);
          }
       }
    }
     
    enum Direction {
       UP("Up", KeyEvent.VK_UP, new Point(0, -1)), DOWN("Down", KeyEvent.VK_DOWN,
             new Point(0, 1)), LEFT("Left", KeyEvent.VK_LEFT, new Point(-1, 0)), Right(
             "Right", KeyEvent.VK_RIGHT, new Point(1, 0));
     
       private String name;
       private int keyCode;
       private Point vector;
     
       private Direction(String name, int keyCode, Point vector) {
          this.name = name;
          this.keyCode = keyCode;
          this.vector = vector;
       }
     
       public String getName() {
          return name;
       }
     
       public int getKeyCode() {
          return keyCode;
       }
     
       public Point getVector() {
          return vector;
       }
     
       @Override
       public String toString() {
          return name;
       }
    }
    Last edited by Fubarable; July 9th, 2012 at 04:34 PM.

  3. The Following User Says Thank You to Fubarable For This Useful Post:

    cselic (July 13th, 2012)

Similar Threads

  1. difference between late binding and runtime polymorphism?
    By saajan.josemk in forum Member Introductions
    Replies: 1
    Last Post: June 15th, 2012, 08:08 AM
  2. Late binding problem ?
    By sanguinarius in forum What's Wrong With My Code?
    Replies: 5
    Last Post: December 28th, 2011, 06:27 AM
  3. Replies: 3
    Last Post: December 27th, 2011, 06:55 AM
  4. key binding: VK_ALT and VK_SHIFT not working
    By gib65 in forum AWT / Java Swing
    Replies: 5
    Last Post: November 25th, 2010, 04:54 PM
  5. Extracting the BINDING element from WSDL file
    By Sai in forum What's Wrong With My Code?
    Replies: 1
    Last Post: March 26th, 2010, 02:56 AM

Tags for this Thread