2012-05-20 41 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()' –