2011-12-12 31 views
7

Tôi đã viết mã mẫu bằng cách sử dụng KeyListener trong Java, Tôi đã tạo một JPanel, sau đó đặt tiêu điểm thành true, tôi đã tạo KeyListener, yêu cầu lấy nét rồi thêm KeyListener vào bảng điều khiển của tôi. Nhưng các phương thức cho keyListener không bao giờ được gọi. Dường như mặc dù tôi đã yêu cầu tập trung, nó không tập trung.java keylistener không được gọi là

Có ai giúp được không?

listener = new KeyLis(); 
this.setFocusable(true); 
this.requestFocus(); 
this.addKeyListener(listener); 

class KeyLis implements KeyListener{ 

    @Override 
    public void keyPressed(KeyEvent e) { 
     currentver += 5; 
     switch (e.getKeyCode()) { 
      case KeyEvent.VK_LEFT : if(horizontalyInBounds()) currentPos-= 5; 
       break; 
      case KeyEvent.VK_RIGHT: if(horizontalyInBounds()) currentPos+= 5; 
       break; 
     } 
     repaint(); 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
    } 
} 

Nếu bất kỳ mã Runnable nên cần thiết:

import java.awt.Color; 
    import java.awt.Graphics; 
    import java.util.Random; 

    import javax.swing.JFrame; 
    import javax.swing.JLabel; 


public class test extends JFrame { 

private AreaOfGame areaOfGame; 

public test() 
{ 
    super(""); 
    setVisible(true); 
    this.setBackground(Color.darkGray); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    this.pack(); 
    setLayout(null); 
    setBounds(200, 10, 400, 700); 

    areaOfGame = new AreaOfGame(); 
    this.add(areaOfGame); 

    startGame(); 
} 

public int generateNext() 
{ 
    Random r = new Random(); 
    int n = r.nextInt(7); 
    return n; 
} 

public void startGame() 
{ 
    while(!areaOfGame.GameOver()) 
    { 
     areaOfGame.startGame(generateNext()); 
    } 
} 


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


import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 

import javax.swing.JPanel; 

public class AreaOfGame extends JPanel { 


    private static final int rightside = 370; 

    private int bottom; 
    private int top; 

    private int currentPos; 
    private int currentver; 
    private KeyLis listener; 

    public AreaOfGame() 
    { 
     super(); 

     bottom = 650; 
     top = 50; 
     setLayout(null); 
     setBounds(20, 50, 350, 600); 
     setVisible(true); 


     this.setBackground(Color.lightGray); 

     listener = new KeyLis(); 
     this.setFocusable(true); 
     if(this.requestFocus(true)) 
      System.out.println("true");; 
     this.addKeyListener(listener); 


     currentPos = 150; 
     currentver=0; 
    } 

    public void startGame(int n) 
    { 
     while(verticallyInBound()){ 
      System.out.println("anything"); 

     } 


    } 

    public boolean verticallyInBound() 
    { 
     if(currentPos<= bottom -50) 
      return true; 
     return false; 
    } 


    public boolean GameOver() 
    { 
     if(top>= bottom){ 
      System.out.println("game over"); 
      return true; 
     } 

     else return false; 
    } 


    public boolean horizontalyInBounds() 
    { 
     if(currentPos<=rightside && currentPos>= 20) 
      return true; 
     else return false; 
    } 


class KeyLis implements KeyListener{ 

     @Override 
     public void keyPressed(KeyEvent e) { 
      System.out.println("called"); 
      currentver += 5; 
      switch (e.getKeyCode()) { 
       case KeyEvent.VK_LEFT : if(horizontalyInBounds()) currentPos-= 5; break; 
       case KeyEvent.VK_RIGHT: if(horizontalyInBounds()) currentPos+= 5; break; 
      } 
      repaint(); 


     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void keyTyped(KeyEvent e) { 
      System.out.println("called 3"); 
     } 
} 

} 
+1

Sẽ hữu ích nếu bạn có thể cung cấp cho chúng tôi lớp "KeyLis" của bạn, có thể sự cố ở đó. – eboix

+0

cảm ơn bạn, tôi đã thêm lớp người nghe – BBB

+0

Hmmm ... Tôi nghĩ rằng tôi có một vấn đề tương tự cùng một lúc. Hãy thử gọi phương thức "e.consume()" vào cuối phương thức keyPressed (KeyEvent e) của bạn. Cho tôi biết nếu nó hoạt động. – eboix

Trả lời

12

Tôi sẽ đặt cược rằng bạn đang yêu cầu tập trung trước khi JPanel đã được trả lại (trước khi cửa sổ cấp cao nhất đã hoặc có pack() hoặc setVisible(true) được gọi), và nếu có, điều này sẽ không hoạt động. Yêu cầu lấy nét sẽ chỉ có thể được cấp sau khi các thành phần được hiển thị. Bạn đã kiểm tra xem cuộc gọi của bạn đến số requestFocus() đã trở lại chưa? Nó phải trở lại đúng cho cuộc gọi của bạn để có cơ hội thành công. Ngoài ra, tốt hơn nên sử dụng requestFocusInWindow() thay vì requestFocus().

Nhưng quan trọng hơn, bạn không nên sử dụng KeyListeners cho điều này nhưng đúng ràng buộc chính, một khái niệm cấp cao hơn mà chính Swing sử dụng để đáp ứng với các lần nhấn phím.

Sửa
Một ví dụ về một SSCCE:

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

public class TestKeyListener extends JPanel { 
    private KeyLis listener; 

    public TestKeyListener() { 
     add(new JButton("Foo")); // something to draw off focus 
     listener = new KeyLis(); 
     this.setFocusable(true); 
     this.requestFocus(); 
     this.addKeyListener(listener); 
    } 

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

    private class KeyLis extends KeyAdapter { 
     @Override 
     public void keyPressed(KeyEvent e) { 
     switch (e.getKeyCode()) { 
     case KeyEvent.VK_LEFT: 
      System.out.println("VK_LEFT pressed"); 
      break; 
     case KeyEvent.VK_RIGHT: 
      System.out.println("VK_RIGHT pressed"); 
      break; 
     } 
     } 
    } 

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

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

Chỉnh sửa 2
Và tương đương SSCCE sử dụng chính Bindings:

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class TestKeyBindings extends JPanel { 

    public TestKeyBindings() { 
     add(new JButton("Foo")); // something to draw off focus 
     setKeyBindings(); 
    } 

    private void setKeyBindings() { 
     ActionMap actionMap = getActionMap(); 
     int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; 
     InputMap inputMap = getInputMap(condition); 

     String vkLeft = "VK_LEFT"; 
     String vkRight = "VK_RIGHT"; 
     inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), vkLeft); 
     inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), vkRight); 

     actionMap.put(vkLeft, new KeyAction(vkLeft)); 
     actionMap.put(vkRight, new KeyAction(vkRight)); 

    } 

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

    private class KeyAction extends AbstractAction { 
     public KeyAction(String actionCommand) { 
     putValue(ACTION_COMMAND_KEY, actionCommand); 
     } 

     @Override 
     public void actionPerformed(ActionEvent actionEvt) { 
     System.out.println(actionEvt.getActionCommand() + " pressed"); 
     } 
    } 

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

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

Sửa 3
Liên quan đến SSCCE gần đây của bạn, các vòng while (true) đang chặn chuỗi sự kiện Swing của bạn và có thể ngăn không cho tương tác người dùng hoặc tranh vẽ xảy ra. Tốt hơn là sử dụng Bộ hẹn giờ xoay thay vì while (true). Ví dụ:

import java.awt.*; 
import java.awt.event.*; 
import java.util.Random; 

import javax.swing.*; 

public class BbbTest extends JFrame { 

    private AreaOfGame areaOfGame; 

    public BbbTest() { 
     super(""); 
//  setVisible(true); 
     this.setBackground(Color.darkGray); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.pack(); 
     setLayout(null); 
     setBounds(200, 10, 400, 700); 

     areaOfGame = new AreaOfGame(); 
     this.add(areaOfGame); 
     setVisible(true); 

     startGame(); 
    } 

    public int generateNext() { 
     Random r = new Random(); 
     int n = r.nextInt(7); 
     return n; 
    } 

    public void startGame() { 
     // while (!areaOfGame.GameOver()) { 
     // areaOfGame.startGame(generateNext()); 
     // } 

     areaOfGame.startGame(generateNext()); 
    } 

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

    class AreaOfGame extends JPanel { 

     private static final int rightside = 370; 

     private int bottom; 
     private int top; 

     private int currentPos; 
     private int currentver; 
     private KeyLis listener; 

     public AreaOfGame() { 
     super(); 

     bottom = 650; 
     top = 50; 
     setLayout(null); 
     setBounds(20, 50, 350, 600); 
     setVisible(true); 

     this.setBackground(Color.lightGray); 

     listener = new KeyLis(); 
     this.setFocusable(true); 
     if (this.requestFocus(true)) 
      System.out.println("true"); 
     ; 
     this.addKeyListener(listener); 

     currentPos = 150; 
     currentver = 0; 
     } 

     public void startGame(int n) { 
     // while (verticallyInBound()) { 
     // System.out.println("anything"); 
     // } 

     int timeDelay = 50; // msecs delay 
     new Timer(timeDelay , new ActionListener() { 

      public void actionPerformed(ActionEvent arg0) { 
       System.out.println("anything"); 
      } 
     }).start(); 

     } 

     public boolean verticallyInBound() { 
     if (currentPos <= bottom - 50) 
      return true; 
     return false; 
     } 

     public boolean GameOver() { 
     if (top >= bottom) { 
      System.out.println("game over"); 
      return true; 
     } 

     else 
      return false; 
     } 

     public boolean horizontalyInBounds() { 
     if (currentPos <= rightside && currentPos >= 20) 
      return true; 
     else 
      return false; 
     } 

     class KeyLis implements KeyListener { 

     @Override 
     public void keyPressed(KeyEvent e) { 
      System.out.println("called"); 
      currentver += 5; 
      switch (e.getKeyCode()) { 
      case KeyEvent.VK_LEFT: 
       if (horizontalyInBounds()) 
        currentPos -= 5; 
       break; 
      case KeyEvent.VK_RIGHT: 
       if (horizontalyInBounds()) 
        currentPos += 5; 
       break; 
      } 
      repaint(); 

     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void keyTyped(KeyEvent e) { 
      System.out.println("called 3"); 
     } 
     } 
    } 
} 
+0

Trên thực tế, tất cả đều được thực hiện sau khi khung của tôi đã có gói() và setVisible (true) .Nếu sử dụng các ràng buộc chính là lựa chọn duy nhất tôi sẽ làm điều đó, nhưng tôi thực sự muốn biết tại sao điều này không hoạt động để có vấn đề này trước, tôi đã kiểm tra con trỏ null, để tập trung, cho các phương thức được gọi, người nghe được thêm vào, nhưng không làm việc. – BBB

+0

@BBB: một lần nữa, bạn đã kiểm tra với lời gọi phương thức 'requestFocus()' đã trở lại chưa? Nó trở lại đúng hay sai? –

+0

nó trở về sai tất cả các thời gian – BBB

0

Có thể sử dụng nút "TAB" để chuyển đổi giữa các nút và trình nghe khóa. Tôi có một chương trình với một nút mà sau khi tôi nhấn nó, trình nghe chính không hoạt động. Tôi nhận ra rằng nếu bạn nhấn nút "TAB", "Chú ý" hoặc "tiêu điểm" của chương trình sẽ trở lại trình nghe chính.

có thể điều này sẽ giúp: http://docstore.mik.ua/orelly/java-ent/jfc/ch03_08.htm

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