2012-05-20 38 views
2

我正在寫一個簡單的遊戲,並且我有4個放置在CardLayout中的JPanel的主框架。 主幀看起來像這樣:在CardLayout中添加keylistener到面板

private static JPanel[] panele = new JPanel[4]; 
private static JPanel panel;  
public GameWindow() 
{ 
    super("Sokoban"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setLayout(new BorderLayout()); 
    panele[0] = new MainMenu(); 
    panele[1] = new LoadGameMenu(); 
    panele[2] = new SaveGameMenu();  
    panele[3] = new GameScene();   
    panel = new JPanel(new CardLayout()); 

    //((MainMenu)panele[0]).setSaveOptionState(false); 
    panel.add(panele[0], "MainMenu"); 
    panel.add(panele[1], "LoadGameMenu"); 
    panel.add(panele[2], "SaveGameMenu"); 
    panel.add(panele[3], "GameScene");  
    add(panel, BorderLayout.CENTER); 


} 

的GameScene面板具有反應以鍵盤輸入。首先,我試過的KeyListener:

public GameScene() {   
    setFocusable(true); 
    initWorld(); //Drawing on JPanel takes place here  
    addKeyListener(new Keyboard());   
} 
class Keyboard extends KeyAdapter 
{ 
    private int key; 
    public void keyPressed(KeyEvent event) 
    { 
     System.out.println("Tu jestem"); 
     key = event.getKeyCode(); 
     if(key == KeyEvent.VK_ESCAPE) 
     { 
      Game.gra = new GameWindow(MenuAction.MAIN_MENU); 
      System.out.println("Escape"); 
     } 

這是行不通的......所以我想鍵綁定(簡單實現):

public GameScene() {  

    setFocusable(true); 
    initWorld(); //Drawing on JPanel takes place here  
    // requestFocus(); 
    setInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, getInputMap()); 
    KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); 
    getInputMap().put(key, "pressed");  
    getActionMap().put("pressed", new AbstractAction(){   
     public void actionPerformed(ActionEvent arg0) { 
      System.out.println("Spacja"); 
      //Game.gra = new GameWindow(MenuAction.MAIN_MENU); 

     } 

    }); 
} 

它仍然沒有工作...我嘗試添加requestFocus的和requestFocusInWindow( )但沒有效果。任何想法如何解決或做到這一點?

已找到解決方案。在密鑰綁定我應該寫:

getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(key, "pressed"); 

insted的的:

getInputMap().put(key, "pressed"); 
+0

什麼是GameScene的超類?組件,JComponent或JPanel等? –

+0

GameScene擴展JPanel – lukasz128

回答

2

通過使用Action所示here,可以綁定一個鍵(或組合)到Action,如圖here。有關其他指導,請編輯您的問題,使用其中一個或兩個示例包含sscce

+0

正如您在我的代碼中看到的,我在第二個鏈接中執行的操作幾乎完全相同。不同之處在於我不想將按鈕操作綁定到關鍵交互。在mainmenu我更換卡,但是當我更改爲GameScene時,我畫板和使用鍵盤輸入我想移動字符(推箱子) – lukasz128

+1

我聽起來像是希望綁定在面板更改時發生改變。使用'WHEN_IN_FOCUSED_WINDOW'將這個[示例](http://stackoverflow.com/a/10015234/230513)使用'WHEN_ANCESTOR_OF_FOCUSED_COMPONENT'與此[示例](http://stackoverflow.com/a/10186676/230513)進行比較。 – trashgod

+1

它的工作......非常感謝。 WHEN_IN_FOCUSED_WINDOW解決了我的問題。 – lukasz128

1

我不知道這是不是你真的什麼,但如果你想簡單地作出反應的關鍵事件,當你「再在‘GameScene’卡,您應該切換到該卡首先(搶焦點):

 CardLayout cl = new CardLayout(); 
     panel = new JPanel(cl); 
     ... 
     add(panel, BorderLayout.CENTER); 
     cl.show(panel, "GameScene"); 

也期待你的代碼 - 考慮使用JMenu和/或JTabbedPane

+0

我沒有提到它,因爲我認爲這很明顯。 show方法被稱爲按鈕點擊操作。我正在創建全屏遊戲,所以我不能使用JMenu,也不想顯示選項卡名稱。 – lukasz128

3

試試這個:

setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)); 

編輯:對於reference, 「每個JComponent有一個動作映射和三個輸入地圖。」

+0

我試過了......我得到了這個錯誤: 線程「main」中的異常java.lang.IllegalArgumentException:WHEN_IN_FOCUSED_WINDOW InputMaps必須是ComponentInputMap類型 – lukasz128

+0

我猜你還需要使用'getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);'而不是'getInputMap()' –