2012-05-11 1 views
4

Im utilisant un KeyAdpater pour obtenir les événements et la méthode addKeyListener et fonctionne très bien. Le problème est que lorsque l'on appuie sur la touche, l'action ne s'exécute qu'une seule fois et pas tant qu'elle est pressée, après 3-4 secs en maintenant enfoncée la touche l'action se produit tout le temps ce que je veux.Java Swing: faire quelque chose pendant que la touche est pressée

Je voudrais savoir s'il y a un bon moyen de faire l'action tout le temps que la touche est pressée à partir du tout début, pas après 3-4 secondes de maintien.

Je pensais que la solution suivante, mais peut-être il y a déjà un moyen mis en œuvre pour le faire:

public abstract class MyKeyAdapter extends KeyAdapter{ 
    private boolean isPressed = false; 
    private int pressedKey = 0; 
    Thread t = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while(isPressed) 
       keyPressedAction(pressedKey); 
     } 
    });  

    @Override 
    public void keyPressed(KeyEvent e) { 
      if(!isPressed){ 
       pressedKey = e.getKeyCode(); 
       t.start(); 
      } 
    } 
    @Override 
    public void keyReleased(KeyEvent e) { 
     if(isPressed && e.getKeyCode()==pressedKey)} 
      isPressed = false; 
    } 

    public abstract void keyPressedAction(int key); 
} 

Répondre

4

J'ai eu un bon succès avec cela en utilisant Key Bindings, pas KeyListener, et commencer une Swing Timer en appuyant sur la touche, puis en arrêtant la minuterie à la libération de Swing. Vous pouvez différencier la pression et la libération de la touche en transmettant l'objet KeyStroke correct dans le InputMap du composant lié en utilisant la méthode KeyStroke.getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease) trouvée ici: KeyStroke API. Si le paramètre booléen est faux, l'entrée répondra à la touche, et l'inverse si le paramètre est vrai.

Pour un exemple rapide et inélégante:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class KeyBindingEg extends JPanel { 
    private static final String UP_KEY_PRESSED = "up key pressed"; 
    private static final String UP_KEY_RELEASED = "up key released"; 
    private static final int UP_TIMER_DELAY = 200; 
    private static final Color FLASH_COLOR = Color.red; 

    private Timer upTimer; 
    private JLabel label = new JLabel(); 

    public KeyBindingEg() { 
     label.setFont(label.getFont().deriveFont(Font.BOLD, 32)); 
     label.setOpaque(true); 
     add(label); 

     setPreferredSize(new Dimension(400, 300)); 

     int condition = WHEN_IN_FOCUSED_WINDOW; 
     InputMap inputMap = getInputMap(condition); 
     ActionMap actionMap = getActionMap(); 
     KeyStroke upKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false); 
     KeyStroke upKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true); 

     inputMap.put(upKeyPressed, UP_KEY_PRESSED); 
     inputMap.put(upKeyReleased, UP_KEY_RELEASED); 

     actionMap.put(UP_KEY_PRESSED, new UpAction(false)); 
     actionMap.put(UP_KEY_RELEASED, new UpAction(true)); 

    } 

    private class UpAction extends AbstractAction { 
     private boolean onKeyRelease; 

     public UpAction(boolean onKeyRelease) { 
     this.onKeyRelease = onKeyRelease; 
     } 

     @Override 
     public void actionPerformed(ActionEvent evt) { 
     if (!onKeyRelease) { 
      if (upTimer != null && upTimer.isRunning()) { 
       return; 
      } 
      System.out.println("key pressed"); 
      label.setText(UP_KEY_PRESSED); 

      upTimer = new Timer(UP_TIMER_DELAY, new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        Color c = label.getBackground(); 
        if (FLASH_COLOR.equals(c)) { 
        label.setBackground(null); 
        label.setForeground(Color.black); 
        } else { 
        label.setBackground(FLASH_COLOR); 
        label.setForeground(Color.white); 
        } 
       } 
      }); 
      upTimer.start(); 
     } else { 
      System.out.println("Key released"); 
      if (upTimer != null && upTimer.isRunning()) { 
       upTimer.stop(); 
       upTimer = null; 
      } 
      label.setText(""); 
     } 
     } 

    } 

    private static void createAndShowGui() { 
     KeyBindingEg mainPanel = new KeyBindingEg(); 

     JFrame frame = new JFrame("KeyBindingEg"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+0

cela pourrait être possible avec ...., mais pourquoi prendre la peine +1 – mKorbel

+0

@Pete J'ai essayé ce code de bas en haut et vice versa, je peux » t trouvé des mots en comparant ..., jusqu'à votre allée, aaaach – mKorbel

Questions connexes