2012-12-21 42 views
4

對不起,但我很難想出一個方法來提出這個問題,並提出一個sscce,所以請裸露在我身邊。您有任何問題都會大大改善我的問題。KeyAdapter在JPanel類中不起作用,但在JFrame類中起作用

背景
我建立一個遊戲庫,使遊戲開發速度快,到目前爲止,它會相當順利。

我有以下幾點:

  • 主要入門級public static void main(String[] args)
    • 這個類,然後開始從我的圖書館一類叫做Game
    • 然後設置窗口的大小,並增加了一個RoomJFrame
  • 當可擴展Room(房間是一個遊戲關卡)創建類時,它會從房間開始繪製所有添加到其中的對象。
    • 對象可以有

加入到他們的活動(我停留在部分),所以上面是主要的想法需要什麼。

這是入門級(非常簡單)。

package test; 

import JGame.Game.Game; 
import JGame.Room.Room; 
import javax.swing.JFrame; 
import test.Rooms.Room1; 

public class Main extends JFrame{ 

    public static void main(String[] args){ 
     Game game = new Game("Test Game"); // This sets the window title 
     game.start(800, 600); // This sets the size of the window 

     Room room1 = new Room1(); 
     game.setRoom(room1); // adds the JPanel to the main frame 
    } 
} 

Room1延伸Room。在Room1之內,與該房間相關聯的所有遊戲對象都被添加到其中。

public class Room extends JPanel implements Runnable{ 
    ArrayList<GameObject> gameObjects = new ArrayList<>(); 
    @Override 
    public void run(){ 
     try{ 
      while(true){ 
       this.repaint(); 
       Thread.sleep(5); 
      } 
     } 
    } 
    public void addGameObjectAt(GameObject gameObject, int x, int y){ 
     // Sets private variables in GameObject 
     // These are then grabbed in the paintComponent to draw at that location 
     gameObject.setX(x); 
     gameObject.setY(y); 
     gameObjects.add(gameObject); 
    } 
    @Override 
    public void paintComponent(Graphics g){ 
     g.drawImage(bg, 0, 0, this); 
     for(int i = 0; i < gameObjects.size(); i++){ 
      GameObject go = gameObjects.get(i); 
      g.drawImage(go.getSprite(), go.getX(), go.getY(), this); 
     } 
    } 
} 

因此,可以說我們創建了一個房間:

public class Room1 extends Room{ 
    public Room1(){ 
     this.createShip(); 
    } 
    public void createShip(){ 
     Ship = new Ship(); 
     // Add an object to a list setting its x,y to 10,10 
     this.addGameObjectAt(ship, 10, 10); 
    } 
} 

注:這些對象不添加到窗口addGameObjectAt它們只是添加到ArrayList,然後在房間線程被畫在屏幕上。

現在,我們添加了Ship到房間,可以使用paintComponent()在屏幕上繪製。這一切工作正常!

這裏是事情開始停止工作的地方。現在我們添加了一個Ship類,我想添加一些關鍵事件,目前我必須添加Main才能工作,但我不想在那裏添加它們,因爲它變得雜亂,我想添加他們到Ship,因爲這是事件最終會產生什麼結果。

此代碼不能附加的KeyListener

// GameObject extends JPanel 
public class Ship extends GameObject{ 
    public Ship(){ 
     this.addKeyListener(new AL()); 
    } 

    public class AL extends KeyAdapter{ 

     @Override 
     public void keyPressed(KeyEvent evt){ 
      System.out.println("here"); 
     } 

     @Override 
     public void keyReleased(KeyEvent evt){ 
     } 
    } 
} 

這不起作用,按下一個鍵不會打印出這裏,但如果我移動AL類和addKeyListener()Game類它的工作原理,但我不希望它在我想要Ship類中的Game類中。

// This class just sets up the size of the application window 
// It also holds an int list of all the game rooms 
public class Game extends JFrame{ 

} 

我一直在努力,現在到這出至少一個星期,我似乎無法弄清楚如何我能得到這個,使其工作在Ship類?

+0

「..但是如果我將AL類和addKeyListener()移動到Game類,它的作用是」你能告訴我們你在'Game'類中做了什麼嗎?另外,爲什麼要用'JFrame'擴展你的'Main'類? –

回答

5

JPanel不是一個可對焦的組件,因此不能與KeyEvents進行交互。

在Swing中,首選的方法是使用Key Bindings。即使組件沒有焦點,也可以將Action映射到KeyStroke。

看到這個example

+0

這是乾淨的解決方案。 – sorencito

+0

我目前有鍵綁定,但他們似乎沒有按照我想要的方式工作。我認爲KeyAdpter確實按我想要的方式工作。我希望能夠一次按2個鍵,並且keyadpter不允許我這樣做。 –

+0

使用'KeyBindings',您可以使用類似於常規的'KeyListener'的修飾符來定義一個鍵。你想要結合哪兩個鍵? – Reimeus

0

我認爲你需要做的JPanel可獲得焦點。嘗試ship.setFocusable(true);

+0

我將它添加到船級,並沒有'工作。然後我嘗試將它添加到創建實例的位置,但仍然無法工作。 –

+0

您是否嘗試點擊面板以獲得焦點?如果它不起作用,我很抱歉。 – sorencito

+0

如果確實有效,那麼只需將其作爲首先關注焦點的組件即可。 – sorencito

相關問題