2014-03-27 106 views
0

所以我創建了JPanel的擴展版本,不幸的是它不響應任何鍵入。你能告訴我問題是什麼嗎?我搜查了所有其他帖子,但我找不到我的錯誤。KeyListener不改變JPanel

public class MyPanel extends JPanel implements ActionListener,KeyListener{ 

Timer tm=new Timer(5,this); 
int x=0,y=0 ,velX=0, velY=0; 

public MyPanel(){ 
    tm.start(); 
    addKeyListener(this); 
    setFocusable(true); 
    requestFocusInWindow(); 
} 

public void paintComponent(Graphics g){ 
    super.paintComponent(g); 

    g.fillRect(0,0,this.getWidth(),this.getHeight()); 
    g.setColor(Color.RED); 
    g.fillRect(x,30,50,30); 



} 

public void actionPerformed(ActionEvent e){ 

    if(x<0||x>370) 
    velX=-velX; 

    if(y<0||y>370) 
    velY=-velY; 

    y=y+velY; 
    x=x+velX; 
    repaint(); 
} 

public void keyPressed(KeyEvent e){ 
    int c=e.getKeyCode(); 
    System.out.println("Cascsadas"); 
    if(c==KeyEvent.VK_LEFT){ 
     velX=-1; 
     velY=0; 
    } 

    if(c==KeyEvent.VK_UP){ 
     velX=0; 
     velY=-1; 
    } 

    if(c==KeyEvent.VK_RIGHT){ 
     velX=1; 
     velY=0; 
    } 

    if(c==KeyEvent.VK_DOWN){ 
     velX=0; 
     velY=1; 
    } 

} 

public void keyTyped(KeyEvent e){}; 
public void keyReleased(KeyEvent e){}; 



} 

我所在的地方使用此JPanel類是:

public class Tester 
{ 
    public static void main(String[] args){ 

    MyPanel t=new MyPanel(); 
    JFrame jf=new JFrame(); 
    jf.setTitle("Tutorial"); 
    jf.setVisible(true); 
    jf.setSize(600,400); 
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    jf.getContentPane().add(t,BorderLayout.CENTER); 

} 
} 
+0

爲了更好地幫助更快(在左,右,上,下斜也是所有方向移動),後一個[MCVE](http://stackoverflow.com/help/mcve)(最小完整和可驗證示例)。 –

回答

2

您的代碼不工作,因爲你的面板沒有焦點。

requestFocusInWindow()方法僅在面板顯示在GUI上時可見。在構造函數中調用該方法不起作用(並且不需要)。

但是,真正的問題在於,在框架可見之後,將面板添加到框架。你的代碼應該是這樣的:

jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
jf.getContentPane().add(t,BorderLayout.CENTER); 
jf.setSize(600,400); 
jf.setVisible(true); 

關鍵是在框架可見之前將面板添加到內容窗格。使框架可見然後改變其大小也是沒有意義的,所以我總是將框架視爲最後一個陳述。

我找遍了所有的其他職位,但我找不到我的錯誤

我覺得很難相信。每天都會問這個問題,我們總是建議使用Key Bindings,那麼爲什麼你仍然試圖使用KeyListener?

Swing設計用於鍵綁定。有關更多信息和使用密鑰綁定的方法,請參閱Motion Using the Keyboard

+0

我按照你的建議改變了代碼,但它仍然不起作用。如果不在構造函數中,我應該在哪裏放置requestFocusInWindow()? –

+1

重讀我的答案,我說你不需要使用該方法。默認情況下,焦點轉到添加到框架中的第一個可聚焦組件,在您的代碼中該組件將成爲面板。右/左鍵對我來說工作得很好。上/下不起作用,因爲你硬編碼「y」偏移量。 – camickr

1

我已經張貼在這裏

Diagonal movement of a simple sprite (up-down-left-right movement already done)同樣情況下的答案。

這篇文章約KeyListener將幫助你更多地理解它。


下面是示例代碼開始:

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.util.Set; 
import java.util.TreeSet; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class Apple extends JPanel implements ActionListener, KeyListener { 

    Timer timer = new Timer(5, this); // this refers to actionListener 
    int x = 0, velx = 0; 
    int y = 0, vely = 0; 

    public Apple() { 
     timer.start(); 
     addKeyListener(this); // this refers to keylistener 
     setFocusable(true); 
     setFocusTraversalKeysEnabled(false); // because we are not using the shift or ctrl key 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     // outer rectangle 
     g.setColor(Color.BLUE); 
     g.fillRect(x, y, 50, 50); 
    } 

    public static void main(String[] args) { 
     Apple apple = new Apple(); 
     apple.setSize(500, 500); 
     JFrame frame = new JFrame(); 
     frame.add(apple); 
     frame.setLayout(null); 
     frame.setTitle("The Game"); 
     frame.setSize(500, 500); 
     frame.setVisible(true); 
     frame.setResizable(false); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    } 

    @Override 
    // animates rectangle 
    public void actionPerformed(ActionEvent arg0) { 
     if (x < 0) { 
      velx = 0; 
      x = 0; 
     } 
     if (x > 450) { 
      velx = 0; 
      x = 450; 
     } 
     if (y < 0) { 
      vely = 0; 
      y = 0; 
     } 
     if (y > 450) { 
      vely = 0; 
      y = 450; 
     } 

     x = x + velx; 
     y = y + vely; 
     repaint(); 
    } 

    // Set of currently pressed keys 
    private final Set<Integer> pressed = new TreeSet<Integer>(); 

    @Override 
    public void keyPressed(KeyEvent arg0) { 
     System.out.println(KeyEvent.VK_LEFT + "-" + KeyEvent.VK_RIGHT + "-" + KeyEvent.VK_UP + "-" 
       + KeyEvent.VK_DOWN); 
     int c = arg0.getKeyCode(); 
     pressed.add(c); 
     if (pressed.size() > 1) { 
      Integer[] array = pressed.toArray(new Integer[] {}); 
      if (array[0] == KeyEvent.VK_LEFT && array[1] == KeyEvent.VK_UP) { 
       velx = -4; 
       vely = -4; 
      } else if (array[0] == KeyEvent.VK_UP && array[1] == KeyEvent.VK_RIGHT) { 
       velx = 4; 
       vely = 4; 
      } else if (array[0] == KeyEvent.VK_RIGHT && array[1] == KeyEvent.VK_DOWN) { 
       velx = 4; 
       vely = -4; 
      } else if (array[0] == KeyEvent.VK_LEFT && array[1] == KeyEvent.VK_DOWN) { 
       velx = -4; 
       vely = 4; 
      } 
     } else { 
      if (c == KeyEvent.VK_LEFT) { 
       velx = -4; 
       vely = 0; 
      } else if (c == KeyEvent.VK_RIGHT) { 
       velx = 4; 
       vely = 0; 
      } else if (c == KeyEvent.VK_UP) { 
       velx = 0; 
       vely = -4; 
      } else if (c == KeyEvent.VK_DOWN) { 
       velx = 0; 
       vely = 4; 
      } 
     } 

    } 

    @Override 
    public void keyReleased(KeyEvent arg0) { 
     velx = 0; 
     vely = 0; 

     pressed.remove(Integer.valueOf(arg0.getKeyCode())); 
    } 

    @Override 
    public void keyTyped(KeyEvent arg0) { 

    } 
}