title: Java Timer & KeyEvents problem
body: <p>I have been making Tetris game and it's almost complete. I have a problem with KeyEvents and a Timer.</p>
  
  <p>My Timer calls <code>actionPerformed</code> every 400ms which drops down tetris block. Problem is that if I press something from the keyboard (down, left, right etc), those commands are noted also every 400 milliseconds. How can I make the timer call <code>actionPerformed</code> every 400ms but so that I can press whenever and how many times I want something from the keyboard and it's instantly recognized/responded to?</p>
  
  <p>EDIT: Here's some of code like people asked</p>
  
  <pre><code>public class Game extends JPanel implements ActionListener {
  
  public static final HashMap&lt;Character, Color&gt; colors = new HashMap&lt;Character,Color&gt;();
  Timer timer;
  Block kpl;
  Grid gameBoard;
  char[][] grid;
  boolean paused = false;
  
  public Game() {
  
      colors.put('P', Color.blue); colors.put('S', Color.green);
      colors.put('D', Color.pink); colors.put('L', Color.red);
      colors.put('Z', Color.orange); colors.put('A', Color.cyan);
      colors.put('T', Color.magenta);
      kpl = new Block();
      gameBoard = new Grid(21,10); // 21x10 sized gameboard
      grid = gameBoard.getGrid();
      addKeyListener(new KeyListening());
      setDoubleBuffered(true);
      setFocusable(true);
      timer = new Timer(100, this);
      timer.start();
  
  }
  
  @Override
  public void paint(Graphics g) { // draws the current game situation
      super.paint(g);
  
          int height = getHeight()/grid.length;
          int width = getWidth()/grid[0].length/2;
  
  
          for (int row = 0; row &lt; grid.length; ++row) {
              for (int column = 0; column &lt; grid[row].length; ++column) {
  
                  if (grid[row][column] == '.') { // if empty, paint white
                      g.setColor(Color.white);
                      g.fillRect(column*width, row*height , width, height);
                      g.setColor(Color.LIGHT_GRAY);
                      g.drawRect(column*width, row*height , width, height);
                  }
                  else if (grid[row][column] != '.') { // if not empty, paint with the color of the block
                      g.setColor(colors.get(grid[row][column]));
                      g.fillRect(column*width, row*height , width, height);
                      g.setColor(Color.BLACK);
                      g.drawRect(column*width, row*height , width, height);
                  }
              }
          }
  
      Toolkit.getDefaultToolkit().sync();
      g.dispose();
  }
  
  
  
  public void actionPerformed(ActionEvent e) {
      if (!gameBoard.isFallingBlock())
          gameBoard.drop(kpl); // if not any falling blocks, drops a new block
  
      gameBoard.updateView(); // moves the block down
      repaint();
  }
  
      private class KeyListening extends KeyAdapter {
  
      @Override
      public void keyPressed(KeyEvent e) {
  
          int key = e.getKeyCode();
  
          switch (key) {
              case KeyEvent.VK_LEFT:
                  gameBoard.move("v"); // moves block left
                  break;
              case KeyEvent.VK_RIGHT:
                  gameBoard.move("o"); // moves block right
                  break;
              case KeyEvent.VK_DOWN:
                  gameBoard.updateView(); // moves block down
                  break;
              case KeyEvent.VK_SPACE:
                  gameBoard.move("p"); // drops the block to the bottom
                  break;
              case KeyEvent.VK_UP: // rotates block
                  gameBoard.move("k");
                  break;
              case KeyEvent.VK_P: // makes the game pause
                  if (paused) {
                      timer.start();
                      paused = false;
                      return;
                  }
  
                  timer.stop();
                  paused = true;
                  break;
  
          }
  
      }
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Had to translate the variables a little since I have been naming them with my own language. GUI is also pretty simple since I made first a text version of my Tetris so it basically runs the text version of it in the background and just paints the situation of the game.</p>
  
  <p>Text version itself is char typed matrix where I move the blocks, for example:</p>
  
  <pre><code>..P..
  ..ppp
  .....
  .....
  </code></pre>
  
  <p><strong>SOLVED:</strong></p>
  
  <p>Problem solved! In public void keyPressed() after every command coming from keyboard I just called repaint()-method again like</p>
  
  <pre><code>        public void keyPressed(KeyEvent e) {
  
          int key = e.getKeyCode();
          switch (key) {
              case KeyEvent.VK_LEFT:
                  gameBoard.move("v");
                  repaint();
                  break;
  </code></pre>
  
  <p>Originally my game responded to my keyboard commands instantly but drew the current state of game every 400ms in actionPerformed() where the repaint() was called. Now my blocks can be moved whenever I want without any "delay" and they're still dropping steady every 400ms :)</p>