我有没有正确地构建这个关键监听器? [英] Did I structure this key listener properly?
本文介绍了我有没有正确地构建这个关键监听器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我这么问是因为我想在我的的GamePanel
类的<code> addShot()方法被调用时,用户点击<大骨节病>输入,这个初始化一个镜头对象重新presenting从船上发射了一枚导弹,但它不会做任何事情。是否有知名度的问题在这里,还是我只是在结构关键事件和监听的关系错了吗?我只张贴相关code,但如果需要,我可以张贴的其余部分。
这里的code:
公共静态类的GameTest扩展的JFrame { 私有静态最终诠释WINDOW_WIDTH = 800;
私有静态最终诠释WINDOW_HEIGHT = 500;
公众的GamePanel的GamePanel;
公众的GameTest()抛出IOException
超(炸自由);
的setResizable(假);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
的setSize(WINDOW_WIDTH,WINDOW_HEIGHT);
的setLayout(新的BorderLayout());
的GamePanel =新的GamePanel();
添加(的GamePanel);
中心(本);
调用setVisible(真);
this.addKeyListener(新aKeyListener());
this.setFocusable(真); } //结束构造 公共无效中心(JFrame的帧){
GraphicsEnvironment中GE = GraphicsEnvironment.getLocalGraphicsEnvironment();
点中心= ge.getCenterPoint(); INT W = frame.getWidth();
INT H = frame.getHeight(); INT X = center.x - 瓦特/ 2,Y = center.y - H / 2;
frame.setBounds(X,Y,W,H);
frame.validate();
中心的方法} //结束 公共类aKeyListener实现的KeyListener { @覆盖
公共无效的keyTyped(KeyEvent的E){
} //结束时清空法的keyTyped @覆盖
公共无效键pressed(KeyEvent的E){
开关(e.getKey code()){
案例KeyEvent.VK_A:
Launcher.lRun = -20;
gamePanel.move(的GamePanel);
打破;
案例KeyEvent.VK_D:
Launcher.lRun = 20;
gamePanel.move(的GamePanel);
打破;
案例KeyEvent.VK_ENTER:
gamePanel.addShot();
打破;
默认:
Launcher.lRun = 0;
} } //结束键pressed方法 @覆盖
公共无效调用keyReleased(KeyEvent的E){
} //结束时清空的keyReleased方法 } //结束aKeyListener类} //结束的GameTest类
解决方案
- 此致可能是一个焦点问题 - 这是在的GamePanel偷焦点也许,一个非常常见的有KeyListeners问题 。
- 一般的建议:用按键绑定,而不是这种类型的需求的KeyListener的青睐
相关链接:
修改结果
例如:
进口java.awt.Dimension中;
进口java.awt.event.ActionEvent中;
进口java.awt.event.KeyEvent中;进口的javax.swing *。公共类的GameTest扩展的JFrame { 私有静态最终诠释WINDOW_WIDTH = 800;
私有静态最终诠释WINDOW_HEIGHT = 500;
公众的GamePanel的GamePanel; 公众的GameTest(){
超(炸自由);
的setResizable(假);
// setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//的setSize(WINDOW_WIDTH,WINDOW_HEIGHT); //永远不要这样做
的GamePanel =新的GamePanel();
setUpKeyBinding(的GamePanel);
添加(的GamePanel);
包();
setLocationRelativeTo(NULL); //为中心!
调用setVisible(真);
} @覆盖
公共尺寸的get preferredSize(){
返回新的Dimension(WINDOW_WIDTH,WINDOW_HEIGHT);
} 私人无效setUpKeyBinding(的GamePanel gamePanel2){ //只需要窗口具有焦点
INT条件= JComponent.WHEN_IN_FOCUSED_WINDOW; //获取的GamePanel的的InputMap和ActionMap中,因为这些将被用来设置
//我们的键绑定
InputMap中的InputMap = gamePanel2.getInputMap(条件);
ActionMap中的ActionMap = gamePanel2.getActionMap(); //绑定一个重要回迁20个像素
的KeyStroke keyStroke的= KeyStroke.getKeyStroke(KeyEvent.VK_A,0);
inputMap.put(击键keyStroke.toString());
actionMap.put(keyStroke.toString(),新MoveAction(gamePanel2,-20)); //绑定D键向前移动20个像素
keyStroke的= KeyStroke.getKeyStroke(KeyEvent.VK_D,0);
inputMap.put(击键keyStroke.toString());
actionMap.put(keyStroke.toString(),新MoveAction(gamePanel2,20)); //绑定ENTER键
keyStroke的= KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0);
inputMap.put(击键keyStroke.toString());
actionMap.put(keyStroke.toString(),新EnterAction(gamePanel2)); } 公共静态无效的主要(字串[] args){
新的GameTest();
} 这将势必击键//我们的Action类
私有类MoveAction扩展AbstractAction {
私人的GamePanel gamePanel2;
私人诠释距离; 公共MoveAction(的GamePanel gamePanel2,诠释距离){
this.gamePanel2 = gamePanel2;
this.distance =距离;
} @覆盖
公共无效的actionPerformed(ActionEvent的五){
gamePanel2.moveItem(距离);
}
} 私有类EnterAction扩展AbstractAction {
私人的GamePanel gamePanel2; 公共EnterAction(的GamePanel gamePanel2){
this.gamePanel2 = gamePanel2;
} @覆盖
公共无效的actionPerformed(ActionEvent的五){
gamePanel2.addShot();
}
}}//一个简单的GamePanel类只表示一切正在按预期
一流的GamePanel继承JPanel { 公共无效移动选项(int i)以{
//你的移动选项的方法,而不是将实际移动的东西,我的距离
的System.out.println(移动项目方法的距离:+ I);
} 公共无效addShot(){
//你的addShot方法将实际拍摄
的System.out.println(添加拍摄法);
}}
I'm asking because I want the addShot()
method in my GamePanel
class to be called when the user hits enter," this initializes a shot object representing a missile fired from a ship, but it doesn't do anything. Is there a visibility issue here, or did I just structure the key event and listener relationship wrong? I'm only posting relevant code, but I can post the rest if necessary.
Here's the code:
public static class GameTest extends JFrame {
private static final int WINDOW_WIDTH = 800;
private static final int WINDOW_HEIGHT = 500;
public GamePanel gamePanel;
public GameTest() throws IOException {
super("Deep Fried Freedom");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setLayout(new BorderLayout());
gamePanel = new GamePanel();
add(gamePanel);
center(this);
setVisible(true);
this.addKeyListener(new aKeyListener());
this.setFocusable(true);
} // end constructor
public void center(JFrame frame) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Point center = ge.getCenterPoint();
int w = frame.getWidth();
int h = frame.getHeight();
int x = center.x - w / 2, y = center.y - h / 2;
frame.setBounds(x, y, w, h);
frame.validate();
}//end of center method
public class aKeyListener implements KeyListener {
@Override
public void keyTyped(KeyEvent e) {
}//end empty keyTyped method
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_A:
Launcher.lRun = -20;
gamePanel.move(gamePanel);
break;
case KeyEvent.VK_D:
Launcher.lRun = 20;
gamePanel.move(gamePanel);
break;
case KeyEvent.VK_ENTER:
gamePanel.addShot();
break;
default:
Launcher.lRun = 0;
}
}//end keyPressed method
@Override
public void keyReleased(KeyEvent e) {
}//end empty keyReleased method
}//end aKeyListener class
}//end GameTest class
解决方案
- Yours is likely a focus issue -- something in the GamePanel stealing focus perhaps, a very common problem with KeyListeners.
- General advice: favor using Key Bindings, not a KeyListener for this type of need.
Useful links:
- Swing Resources
- Please check my second example program in my answer to a StackOverflow question here.
- Overall Swing Tutorials
- Key Bindings
- Swing Timer
- Concurrency in Swing
Edit
For example:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class GameTest extends JFrame {
private static final int WINDOW_WIDTH = 800;
private static final int WINDOW_HEIGHT = 500;
public GamePanel gamePanel;
public GameTest() {
super("Deep Fried Freedom");
setResizable(false);
// setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// setSize(WINDOW_WIDTH, WINDOW_HEIGHT); // never do this
gamePanel = new GamePanel();
setUpKeyBinding(gamePanel);
add(gamePanel);
pack();
setLocationRelativeTo(null); // to center!
setVisible(true);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT);
}
private void setUpKeyBinding(GamePanel gamePanel2) {
// only need window to have focus
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
// get the GamePanel's InputMap and ActionMap as these will be used to set
// up our Key Bindings
InputMap inputMap = gamePanel2.getInputMap(condition);
ActionMap actionMap = gamePanel2.getActionMap();
// bind the A key to move back 20 pixels
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0);
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), new MoveAction(gamePanel2, -20));
// bind the D key to move forward 20 pixels
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_D, 0);
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), new MoveAction(gamePanel2, 20));
// bind the ENTER key
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), new EnterAction(gamePanel2));
}
public static void main(String[] args) {
new GameTest();
}
// our Action classes that will bound to key strokes
private class MoveAction extends AbstractAction {
private GamePanel gamePanel2;
private int distance;
public MoveAction(GamePanel gamePanel2, int distance) {
this.gamePanel2 = gamePanel2;
this.distance = distance;
}
@Override
public void actionPerformed(ActionEvent e) {
gamePanel2.moveItem(distance);
}
}
private class EnterAction extends AbstractAction {
private GamePanel gamePanel2;
public EnterAction(GamePanel gamePanel2) {
this.gamePanel2 = gamePanel2;
}
@Override
public void actionPerformed(ActionEvent e) {
gamePanel2.addShot();
}
}
}
// a trivial GamePanel class to just show that everything is working as expected
class GamePanel extends JPanel {
public void moveItem(int i) {
// your moveItem method will instead actually move something, a distance of i
System.out.println("Move Item Method distance: " + i);
}
public void addShot() {
// your addShot method will actually shoot
System.out.println("Add Shot Method");
}
}
这篇关于我有没有正确地构建这个关键监听器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文