2013-06-02 57 views
1

我真的不知道我做错了什么。只有重要事件有时注册

有时,关键事件登记,有时他们没有。
而我的意思是,有时当我运行Frogger2时,我得到注册事件,有时甚至没有。

看起来完全是随机的,关键事件注册与否。通常情况下,如果我暂时不测试任何东西并运行Frogger2事件注册,那么当我关闭它并重新运行完全相同的程序时,我就不会收到任何事件。

请帮忙。

import java.util.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.BufferedImage; 
import javax.swing.*; 

public class Frogger2 extends JPanel { 

public static JFrame frame; 
public static Frogger2 F; 

public Frogger2() {} 

public Dimension getPreferredSize() { return new Dimension(500,500); } 
public void paintComponent(Graphics g) { super.paintComponent(g); } 


private int fdir; 

public void moveLeft() { 
    travel(2); 
} 
public void moveRight() { 
    travel(0); 
} 
public void moveUp() { 
    travel(3); 
} 
public void moveDown() { 
    travel(1); 
} 
private void travel(int ddd) { 
    System.out.println(ddd); 
} 


private boolean step() { 
    System.out.println("FDIR: "+fdir); 
    return true; 
} 

public void start() { 
    fdir = 2; 
    while(true) { 
     boolean a = step(); 
     if (!a) break; 
     try { 
      Thread.sleep(25); 
     } catch(Exception e) {} 
    } 
} 

public static void main(String[] args) { 
    frame = new JFrame("Frogger"); 

    F = new Frogger2(); 
    F.setDoubleBuffered(true); 
    frame.add(F); 
    frame.pack(); 
    frame.setVisible(true); 
    frame.setResizable(false); 
    JPanel abc = (JPanel)frame.getContentPane(); 
    abc.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left"); 
    abc.getActionMap().put("left", new AbstractAction() { 
     public void actionPerformed(ActionEvent e) {F.moveLeft();} 
    }); 
    abc.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right"); 
    abc.getActionMap().put("right", new AbstractAction() { 
     public void actionPerformed(ActionEvent e) {F.moveRight();} 
    }); 
    abc.getInputMap().put(KeyStroke.getKeyStroke("UP"), "up"); 
    abc.getActionMap().put("up", new AbstractAction() { 
     public void actionPerformed(ActionEvent e) {F.moveUp();} 
    }); 
    abc.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down"); 
    abc.getActionMap().put("down", new AbstractAction() { 
     public void actionPerformed(ActionEvent e) {F.moveDown();} 
    }); 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    F.start(); 

} 

} 
+1

- [*如何写一个按键侦听器*](HTTP “要发射的键盘事件,_must_有键盘焦点的组件。”://文档。 oracle.com/javase/tutorial/uiswing/events/keylistener.html) – trashgod

回答

4

这个问题通常发生在面板焦点上,每次按任何键都必须确保面板处于焦点。
你会想看看Java教程以获得一个很好的Key Bindings概述,因为@camickr在评论中提到它。
也看看question回答@mKorbel(非常感兴趣的答案)。

在按键绑定有兴趣的事情是:说,当你按下按Ctrl + + 空间程序做一些操作,这是非常有趣的,强烈建议使用键绑定,还看到我first question上堆栈是关于这个问题。

这是你的代码我心中已经做出了一些改变:

  • KeyListener每次按下一个键的重点将是在面板上。
  • MouseListener当鼠标进入面板或鼠标单击面板时,焦点将重新放在面板上。
  • FocusListener:要知道面板是否可以对焦。

下面是代码:

import java.awt.event.*; 
import javax.swing.*; 
import java.awt.*; 
public class MovingJPanel { 

    public static void main(String[] args) { 
    JFrame frame = new JFrame("Frogger"); 

    frame.pack(); 
    frame.setVisible(true); 
    frame.setResizable(true); 
    frame.setLocationRelativeTo(null); 
    frame.setSize(400,400); 
    JPanel abc = new JPanel(); 
    abc.setBackground(Color.CYAN); 
    abc.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left"); 
    abc.getActionMap().put("left", new AbstractAction() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("LEFT");} 
    }); 
    abc.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right"); 
    abc.getActionMap().put("right", new AbstractAction() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("ROIGHT");} 
    }); 
    abc.getInputMap().put(KeyStroke.getKeyStroke("UP"), "up"); 
    abc.getActionMap().put("up", new AbstractAction() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("UP");} 
    }); 
    abc.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down"); 
    abc.getActionMap().put("down", new AbstractAction() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("DOWN");} 
    }); 

    abc.addFocusListener(new FocusAdapter() { 
     @Override 
     public void focusGained(FocusEvent e) { 
      System.out.println("Focus Gained"); 
     } 
     @Override 
     public void focusLost(FocusEvent e) { 
      System.out.println("Focus Lost"); 
     } 
}); 
    abc.addKeyListener(new KeyAdapter() { 
     @Override 
     public void keyTyped(KeyEvent e) { 
      JPanel p = (JPanel)e.getSource(); 
      p.requestFocus(); 
     } 
}); 

    abc.addMouseListener(new MouseAdapter() { 

     @Override 
     public void mouseEntered(MouseEvent e) { 
      JPanel p = (JPanel)e.getSource(); 
      p.requestFocus(); 
     } 

}); 
    frame.getContentPane().add(abc,"Center"); 
    frame.getContentPane().add(new JButton("Click Me"),"North"); 
    abc.requestFocusInWindow(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

} 
} 
+1

+1,用于使用密钥绑定。虽然更好的答案是在[如何使用关键绑定](http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html)中包含Swing教程的链接,以便OP能够理解你为什么做这些改变。 – camickr

+1

+1 [但看到如何真正的工作](http://stackoverflow.com/a/7940227/714968)(您将通过@camickr通知相同) – mKorbel

+1

不需要添加,寻找焦点,必须定义InputMap inMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);确定有三个选项,无论如何,但非常好的编辑,成功的基本用法 – mKorbel