【问题标题】:KeyListener doesn't do anything after using getContentPane() through ActionListener通过 ActionListener 使用 getContentPane() 后 KeyListener 不做任何事情
【发布时间】:2015-11-26 18:18:16
【问题描述】:

大家好,我是新手,这是我在编码论坛上的第一篇文章(抱歉我的英语不好 XD)我决定制作一个菜单来开始游戏,但是当我使用 JFrame setContentPane() 我的菜单添加它时类,keylistener 不能做任何事情,虽然当我通过直接添加我的 Tank 类进行测试时,它运行正常,我该如何解决这个问题?谢谢 :D

我的菜单类:

public class Menu extends JPanel {
private JButton jb1=new JButton("Start game"),
        jb2=new JButton("Exit");
private JFrame frame;
public Menu(JFrame x){
    this.frame=x;
    setLayout(new FlowLayout());
    add(jb1);
    add(jb2);
    jb1.addActionListener(new ActionListener(){
       public void actionPerformed(ActionEvent e){
           frame.setContentPane(new Tank(frame));
           frame.pack();
       }
    });

    jb2.addActionListener(new ActionListener(){
       public void actionPerformed(ActionEvent e){
           frame.dispose();
           System.exit(0);
       }
    });    
}
public Dimension getPreferredSize(){
    return new Dimension(1200,600);
}}

我的坦克课:

public class Tank extends JPanel implements ActionListener,KeyListener{
private int xTank=0,   
            yTank=0,
            xTankMotion=0,
            yTankMotion=0;
private int xAlien=800,
            yAlien=0,
            xAlienMotion=0,
            yAlienMotion=0;
private Image tank=new ImageIcon("Tank.jpg").getImage(),
              alien= new ImageIcon("Alien.jpg").getImage();
private int tankWidth=tank.getWidth(this), 
            tankHeight=tank.getHeight(this);
private int fire=0,
            xRocket=0,
            yRocket=0,
            xRocketMotion=0,
            yRocketMotion=0;
private int alienWidth=alien.getWidth(this), 
            alienHeight=alien.getHeight(this);
private int key=1;
private Timer time=new Timer(1,this);
private int angle;
private int truot=0,trung=0;
private boolean banduoc=true;
private JFrame frame;
private void gameOver(JFrame jf){
    jf.setContentPane(new Victory());
}

public Tank(JFrame frame){ 
    this.frame=frame;
    time.start();
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
    requestFocus();
    addKeyListener(this);
}
@Override
public void actionPerformed(ActionEvent e){

    if(xTank<=0) xTank=0;
    if(xTank>=400) xTank=400;
    if(yTank<=0) yTank=0;
    if(yTank>=600-tankHeight) yTank=600-tankHeight;

    if(truot==0){
    if(xAlien<=1200-alienWidth) {
        xAlienMotion=1; 
        yAlienMotion=0;}
    if(xAlien>=1200-alienWidth){ 
        xAlienMotion=0; 
        yAlienMotion=1;}
    if(yAlien>=600-alienHeight){ 
        xAlienMotion=-1; 
        yAlienMotion=0;}
    if(xAlien<=800&&yAlien>=0){ 
        xAlienMotion=0; 
        yAlienMotion=-1;}}
    else {
        if(trung==0&&((xTank<=xAlien+alienWidth&&xTank+tankWidth>=xAlien+alienWidth&&((yTank>=yAlien&&yTank<=yAlien+alienHeight)||(yTank+tankHeight>=yAlien&&yTank+tankHeight<=yAlien+alienHeight)))||
            (yTank<=yAlien+alienHeight&&yAlien+alienHeight<=yTank+tankHeight&&((xTank>=xAlien&&xTank<=xAlien+alienWidth)||(xTank+tankWidth>=xAlien&&xTank+tankWidth<=xAlien+alienWidth)))||
            (xTank+tankWidth>=xAlien&&xAlien>=xTank&&((yTank>=yAlien&&yTank<=yAlien+alienHeight)||(yTank+tankHeight>=yAlien&&yTank+tankHeight<=yAlien+alienHeight)))||
            (yTank+tankHeight<=yAlien&&yAlien>=yTank&&((xTank>=xAlien&&xTank<=xAlien+alienWidth)||(xTank+tankWidth>=xAlien&&xTank+tankWidth<=xAlien+alienWidth)))))
        {time.stop();  frame.setContentPane(new Defeated(frame)); frame.pack(); return;}
        else{
            if(yAlien>yTank){
                yAlienMotion=-1;
                if(xAlien>xTank) xAlienMotion=-1;
                else if(xAlien<xTank) xAlienMotion=1;
                else xAlienMotion=0;
            }
            else if(yAlien<yTank){
                yAlienMotion=1;
                if(xAlien>xTank) xAlienMotion=-1;
                else if(xAlien<xTank) xAlienMotion=1;
                else xAlienMotion=0;
            }
            else{
                yAlienMotion=0;
                if(xAlien>xTank) xAlienMotion=-1;
                else if(xAlien<xTank) xAlienMotion=1;
            }
        }
    }
    xTank+=xTankMotion;
    yTank+=yTankMotion;

    xRocket+=xRocketMotion;
    yRocket+=yRocketMotion;

    xAlien+=xAlienMotion;
    yAlien+=yAlienMotion;

    if((xRocket>=1200||xRocket<0||yRocket<0||yRocket>600)&&truot==0)  {truot=1; banduoc=true;}
    if(xRocket>=xAlien&&xRocket<=xAlien+alienWidth&&yRocket>=yAlien&&yRocket<=yAlien+alienHeight) {trung=1; frame.setContentPane(new Victory());  frame.pack();}
    repaint();
}
@Override
public Dimension getPreferredSize(){
    return new Dimension(1200,600);
}
@Override
protected void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, this.getWidth(), this.getHeight());
    AffineTransform at= AffineTransform.getTranslateInstance(xTank,yTank);
    at.rotate(Math.toRadians(angle),tankWidth/2,tankHeight/2);
    Graphics2D g2d=(Graphics2D) g;
    g2d.drawImage(tank,at,null);
    g.drawImage(alien, xAlien, yAlien, this);
    if(fire==1) {
        g.setFont(new Font("Monospaced",Font.BOLD,20));
        g.setColor(Color.yellow);
        g.fillOval(xRocket,yRocket, 5, 5);
    }
    if(truot==1) {
        g.setColor(Color.red);
        g.drawString("Noooooo! :(", xTank, yTank-50);
    }
}
public static void main(String[] args) {
    JFrame frame=new JFrame("Tank");
    frame.setContentPane(new Menu(frame));
    frame.setContentPane(new Tank(frame));
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.setResizable(false);
}

@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void keyPressed(KeyEvent e) {
    int i=e.getKeyCode();
    if(i==KeyEvent.VK_UP) {
        key=2;
        xTankMotion=0;
        yTankMotion=-1; 
        angle=90;}
    else if(i==KeyEvent.VK_DOWN) {
        key= 4;  
        xTankMotion=0;
        yTankMotion=1; 
        angle=-90;}
    else if(i==KeyEvent.VK_RIGHT) {
        key=3;  
        xTankMotion=1; 
        yTankMotion=0;
        angle=180;}
    else if(i==KeyEvent.VK_LEFT) {
        key=1;   
        xTankMotion=-1;
        yTankMotion=0;
        angle=0;}
    if(i==KeyEvent.VK_SPACE&&banduoc) {
        fire=1; 
        if(key==1) {
            xRocket=xTank;
            yRocket=yTank+tankHeight/2;
            xRocketMotion=-2;
            yRocketMotion=0;
        }
        if(key==2) {
            xRocket=xTank+tankWidth/2;
            yRocket=yTank;
            yRocketMotion=-2;
            xRocketMotion=0;
        }
        if(key==3) {
            xRocket=xTank+tankWidth;
            yRocket=yTank+tankHeight/2;
            xRocketMotion=2;
            yRocketMotion=0;
        }
        if(key==4) {
            xRocket=xTank+tankWidth/2;
            yRocket=yTank+tankHeight;
            yRocketMotion=2;
            xRocketMotion=0;
        }
        banduoc=false;
    }
}

@Override
public void keyReleased(KeyEvent e) {
    xTankMotion=0;
    yTankMotion=0;
}}

【问题讨论】:

  • 不要使用KeyListener,它们只有在注册的组件是可聚焦且有焦点时才能响应按键事件。这是一个众所周知的文档问题。相反,您应该使用旨在修复此限制的键绑定 API。更多详情请见How to Use Key Bindings
  • 天哪,你回复了我! XD 谢谢!我会尝试,但我不知道为什么我不能集中注意力,你能告诉我我的错误吗?:我使用了 setFocusable 和 requestFocus 但它仍然无法获得焦点
  • 可能是其他一些控件窃取了焦点,而您的组件(带有KeyListener 的组件)再也没有找回它
  • 是的,是的!按钮导致它,但我不知道为什么,我将这些函数放在 Tank 类的构造函数中,因为我认为单击按钮后面板会再次获得焦点,但它不会工作
  • 专注是一件棘手的事情。当您调用requestFocus(并且您应该使用requestFocusInWindow)时,该组件不会添加到任何东西或附加到任何可显示的东西

标签: java swing actionlistener keylistener


【解决方案1】:

这是我的答案,我使用 KeyBindings 而不是 KeyListener(感谢 MadProgrammer :D),并且我在 Tank 类的构造函数中编写了它

public class Tank extends JPanel implements ActionListener{
private int xTank=0,   
            yTank=0,
            xTankMotion=0,
            yTankMotion=0;
private int xAlien=800,
            yAlien=0,
            xAlienMotion=0,
            yAlienMotion=0;
private Image tank=new ImageIcon("Tank.jpg").getImage(),
              alien= new ImageIcon("Alien.jpg").getImage();
private int tankWidth=tank.getWidth(this), 
            tankHeight=tank.getHeight(this);
private int fire=0,
            xRocket=0,
            yRocket=0,
            xRocketMotion=0,
            yRocketMotion=0;
private int alienWidth=alien.getWidth(this), 
            alienHeight=alien.getHeight(this);
private int key=1;
private Timer time=new Timer(1,this);
private int angle;
private int truot=0,trung=0;
private boolean banduoc=true;
private JFrame frame;
private InputMap im= getInputMap(WHEN_IN_FOCUSED_WINDOW);
private ActionMap am= getActionMap();
public Tank(JFrame frame){ 
    this.frame=frame;
    time.start();
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "moveleft");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "moveup");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "moveright");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "movedown");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "release");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "release");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "release");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "release");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "fire");

    am.put("moveleft", new AbstractAction(){
        public void actionPerformed(ActionEvent e){
            key=1;   
            xTankMotion=-1;
            yTankMotion=0;
            angle=0;
        }
    });
    am.put("moveup", new AbstractAction(){
        public void actionPerformed(ActionEvent e){
            key=2;
            xTankMotion=0;
            yTankMotion=-1; 
            angle=90;
        }
    });
    am.put("moveright", new AbstractAction(){
        public void actionPerformed(ActionEvent e){
            key=3;  
            xTankMotion=1; 
            yTankMotion=0;
            angle=180;
        }
    });
    am.put("movedown", new AbstractAction(){
        public void actionPerformed(ActionEvent e){
            key= 4;  
            xTankMotion=0;
            yTankMotion=1; 
            angle=-90;
        }
    });
    am.put("release", new AbstractAction(){
        public void actionPerformed(ActionEvent e){
            xTankMotion=0;
            yTankMotion=0;
        }
    });
    am.put("fire", new AbstractAction(){
        public void actionPerformed(ActionEvent e){if(banduoc){
            fire=1; 
            if(key==1) {
                xRocket=xTank;
                yRocket=yTank+tankHeight/2;
                xRocketMotion=-2;
                yRocketMotion=0;
            }
            if(key==2) {
                xRocket=xTank+tankWidth/2;
                yRocket=yTank;
                yRocketMotion=-2;
                xRocketMotion=0;
            }
            if(key==3) {
                xRocket=xTank+tankWidth;
                yRocket=yTank+tankHeight/2;
                xRocketMotion=2;
                yRocketMotion=0;
            }
            if(key==4) {
                xRocket=xTank+tankWidth/2;
                yRocket=yTank+tankHeight;
                yRocketMotion=2;
                xRocketMotion=0;
        }
            banduoc=false;
        }}
    });

    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
    requestFocusInWindow();

}
@Override
public void actionPerformed(ActionEvent e){

    if(xTank<=0) xTank=0;
    if(xTank>=400) xTank=400;
    if(yTank<=0) yTank=0;
    if(yTank>=600-tankHeight) yTank=600-tankHeight;

    if(truot==0){
    if(xAlien<=1200-alienWidth) {
        xAlienMotion=1; 
        yAlienMotion=0;}
    if(xAlien>=1200-alienWidth){ 
        xAlienMotion=0; 
        yAlienMotion=1;}
    if(yAlien>=600-alienHeight){ 
        xAlienMotion=-1; 
        yAlienMotion=0;}
    if(xAlien<=800&&yAlien>=0){ 
        xAlienMotion=0; 
        yAlienMotion=-1;}}
    else {
        if(trung==0&&((xTank<=xAlien+alienWidth&&xTank+tankWidth>=xAlien+alienWidth&&((yTank>=yAlien&&yTank<=yAlien+alienHeight)||(yTank+tankHeight>=yAlien&&yTank+tankHeight<=yAlien+alienHeight)))||
            (yTank<=yAlien+alienHeight&&yAlien+alienHeight<=yTank+tankHeight&&((xTank>=xAlien&&xTank<=xAlien+alienWidth)||(xTank+tankWidth>=xAlien&&xTank+tankWidth<=xAlien+alienWidth)))||
            (xTank+tankWidth>=xAlien&&xAlien>=xTank&&((yTank>=yAlien&&yTank<=yAlien+alienHeight)||(yTank+tankHeight>=yAlien&&yTank+tankHeight<=yAlien+alienHeight)))||
            (yTank+tankHeight<=yAlien&&yAlien>=yTank&&((xTank>=xAlien&&xTank<=xAlien+alienWidth)||(xTank+tankWidth>=xAlien&&xTank+tankWidth<=xAlien+alienWidth)))))
        {time.stop();  frame.setContentPane(new Defeated(frame)); frame.pack(); return;}
        else{
            if(yAlien>yTank){
                yAlienMotion=-1;
                if(xAlien>xTank) xAlienMotion=-1;
                else if(xAlien<xTank) xAlienMotion=1;
                else xAlienMotion=0;
            }
            else if(yAlien<yTank){
                yAlienMotion=1;
                if(xAlien>xTank) xAlienMotion=-1;
                else if(xAlien<xTank) xAlienMotion=1;
                else xAlienMotion=0;
            }
            else{
                yAlienMotion=0;
                if(xAlien>xTank) xAlienMotion=-1;
                else if(xAlien<xTank) xAlienMotion=1;
            }
        }
    }
    xTank+=xTankMotion;
    yTank+=yTankMotion;

    xRocket+=xRocketMotion;
    yRocket+=yRocketMotion;

    xAlien+=xAlienMotion;
    yAlien+=yAlienMotion;

    if((xRocket>=1200||xRocket<0||yRocket<0||yRocket>600)&&truot==0)  {truot=1; banduoc=true;}
    if(xRocket>=xAlien&&xRocket<=xAlien+alienWidth&&yRocket>=yAlien&&yRocket<=yAlien+alienHeight) {trung=1; frame.setContentPane(new Victory(frame));  frame.pack();}
    repaint();
}
@Override
public Dimension getPreferredSize(){
    return new Dimension(1200,600);
}
@Override
protected void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, this.getWidth(), this.getHeight());
    AffineTransform at= AffineTransform.getTranslateInstance(xTank,yTank);
    at.rotate(Math.toRadians(angle),tankWidth/2,tankHeight/2);
    Graphics2D g2d=(Graphics2D) g;
    g2d.drawImage(tank,at,null);
    g.drawImage(alien, xAlien, yAlien, this);
    if(fire==1) {
        g.setFont(new Font("Monospaced",Font.BOLD,20));
        g.setColor(Color.yellow);
        g.fillOval(xRocket,yRocket, 5, 5);
    }
    if(truot==1) {
        g.setColor(Color.red);
        g.drawString("Noooooo! :(", xTank, yTank-50);
    }
}
public static void main(String[] args) {
    JFrame frame=new JFrame("Tank");
    frame.setContentPane(new Menu(frame));
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.setResizable(false);
}}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2013-02-14
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多