2012-01-22 29 views
9

Tôi đang viết một chương trình đơn giản trong Java bao gồm một KeyListener như sau trọng họ KeyTyped phương pháp:Java KeyListener không đăng ký Arrow Keys

@Override 
     public void keyTyped(KeyEvent e) 
     { 
      int key = e.getKeyCode(); 
      System.out.println("TEST"); 

      if (key == KeyEvent.VK_KP_LEFT || key == KeyEvent.VK_LEFT) 
      { 
       System.out.println("LEFT"); 
       //Call some function 
      } 
      else if (key == KeyEvent.VK_KP_RIGHT || key == KeyEvent.VK_RIGHT) 
      { 
       System.out.println("RIGHT"); 
       //Call some function 
      } 
     } 

Khi tôi gõ bất cứ điều gì khác hơn là các phím mũi tên (ví dụ: "một "), nó in TEST như nó phải. Tuy nhiên, khi tôi gõ một phím mũi tên, nó chỉ in TEST và khi tôi gõ một phím mũi tên tiêu chuẩn nó không in bất cứ điều gì cả. Đây có phải là vì tôi đang ở trên máy tính xách tay hay tôi vừa mắc sai lầm ngớ ngẩn ở đâu đó?

+0

Các bạn đã thử sử dụng 'keyPressed' thay vì' keyTyped'? –

Trả lời

20

Đúng, bạn sẽ thấy các phím mũi tên phản hồi với phímPress and keyReleased, not keyTyped. My SSCCE:

import java.awt.Dimension; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 

import javax.swing.*; 

public class ArrowTest extends JPanel { 
    private static final int PREF_W = 400; 
    private static final int PREF_H = PREF_W; 

    public ArrowTest() { 
     setFocusable(true); 
     requestFocusInWindow(); 

     addKeyListener(new KeyAdapter() { 

     @Override 
     public void keyTyped(KeyEvent e) { 
      myKeyEvt(e, "keyTyped"); 
     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      myKeyEvt(e, "keyReleased"); 
     } 

     @Override 
     public void keyPressed(KeyEvent e) { 
      myKeyEvt(e, "keyPressed"); 
     } 

     private void myKeyEvt(KeyEvent e, String text) { 
      int key = e.getKeyCode(); 
      System.out.println("TEST"); 

      if (key == KeyEvent.VK_KP_LEFT || key == KeyEvent.VK_LEFT) 
      { 
       System.out.println(text + " LEFT"); 
       //Call some function 
      } 
      else if (key == KeyEvent.VK_KP_RIGHT || key == KeyEvent.VK_RIGHT) 
      { 
       System.out.println(text + " RIGHT"); 
       //Call some function 
      } 
     } 


     }); 
    } 

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

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

     JFrame frame = new JFrame("ArrowTest"); 
     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(); 
     } 
     }); 
    } 
} 

Vì vậy, để giải quyết việc này, ghi đè keyPressed hơn keyTyped nếu bạn muốn nghe mũi tên sự kiện.

Hoặc cho một giải pháp tốt hơn: sử dụng Key Bindings

Sửa
My chính Bindings phiên bản:

import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class ArrowTest extends JPanel { 
    private static final int PREF_W = 400; 
    private static final int PREF_H = PREF_W; 

    public ArrowTest() { 
     ActionMap actionMap = getActionMap(); 
     int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; 
     InputMap inputMap = getInputMap(condition); 

     for (Direction direction : Direction.values()) { 
     inputMap.put(direction.getKeyStroke(), direction.getText()); 
     actionMap.put(direction.getText(), new MyArrowBinding(direction.getText())); 
     } 
    } 

    private class MyArrowBinding extends AbstractAction { 
     public MyArrowBinding(String text) { 
     super(text); 
     putValue(ACTION_COMMAND_KEY, text); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
     String actionCommand = e.getActionCommand(); 
     System.out.println("Key Binding: " + actionCommand); 
     } 
    } 

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

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

     JFrame frame = new JFrame("ArrowTest"); 
     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(); 
     } 
     }); 
    } 
} 

enum Direction { 
    UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)), 
    DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)), 
    LEFT("Left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)), 
    RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0)); 

    Direction(String text, KeyStroke keyStroke) { 
     this.text = text; 
     this.keyStroke = keyStroke; 
    } 
    private String text; 
    private KeyStroke keyStroke; 

    public String getText() { 
     return text; 
    } 

    public KeyStroke getKeyStroke() { 
     return keyStroke; 
    } 

    @Override 
    public String toString() { 
     return text; 
    } 
} 
+0

Điều đó thật thú vị. Có lý do nào khiến họ không trả lời keyPressed không? – Landric

+1

@Landric: xin lỗi, nhưng tôi không có ý tưởng và đang gãi đầu của tôi về điều này. Tôi đã không bao giờ chạy vào điều này bản thân mình, bởi vì đối với một cái gì đó như thế này, tôi luôn luôn sử dụng Key Bindings, và tôi mạnh mẽ đề nghị bạn làm như vậy. –

+1

@Landric: vui lòng xem chỉnh sửa cho phiên bản Khóa Bindings của [SSCCE] của tôi (http://SSCCE.org). –

Các vấn đề liên quan