KeyListener 出现问题 [重复]

Posted

技术标签:

【中文标题】KeyListener 出现问题 [重复]【英文标题】:Trouble with KeyListener [duplicate] 【发布时间】:2015-08-03 11:19:21 【问题描述】:

这是我第一次使用KeyListener,如果我犯了明显的错误,请原谅。我的问题是,每当我按箭头键或 WASD 键时,省略号都没有反应。我知道我的代码中还有其他缺陷,但我只想关注KeyListener 问题。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.event.KeyListener;

public class idkdude extends JPanel implements ActionListener, KeyListener 

    Timer t = new Timer(5, this);
     int rx = 395, ry = 395, rvelx = 0, rvely = -2, bx = 195, by = 195, bvelx =     0, bvely = 2;
     boolean redWins = false;
     boolean blueWins = false;

     public void paint(Graphics g)
        
            super.paint(g);
             drawSurface(g);
            Graphics2D g2 = (Graphics2D) g;             
            g.setColor(Color.red);
            Ellipse2D rcircle = new Ellipse2D.Double(rx, ry, 10, 10);
            g2.fill(rcircle);
            g2.drawLine(400, 400, rx+5, ry+5);
            g.setColor(Color.blue);
            Ellipse2D bcircle = new Ellipse2D.Double(bx, by, 10, 10);
            g2.fill(bcircle);
            g2.drawLine(200, 200, bx+5, by+5);
            if (redWins == true)
            
                redWins(g);
            
            if (blueWins == true)
            
                blueWins(g);
            
            t.start();
        

     public void init()
     
         addKeyListener(this);
     
     public void keyReleased(KeyEvent e)
        public void keyTyped(KeyEvent e) 
        public void keyPressed(KeyEvent e)
         //make sure to put
            //rx+=rvelx;
            //ry+=rvely;
            // and draw a new line
            int key = e.getKeyCode();
            if (key == KeyEvent.VK_LEFT) 
            rvelx = -2;rvely = 0;
            if (key == KeyEvent.VK_RIGHT)
            rvelx = 2; rvely = 0;
            if (key == KeyEvent.VK_UP)
            rvelx = 0; rvely = -2;
            if (key == KeyEvent.VK_DOWN)
            rvelx = 0; rvely = 2;
            if (key == KeyEvent.VK_W)
            bvelx = 0; rvely = -2;
            if (key == KeyEvent.VK_A)
            bvelx = -2; rvely = 0;
            if (key == KeyEvent.VK_S)
            bvelx = 0; rvely = 2;
            if (key == KeyEvent.VK_D)
            bvelx = 2; rvely = 0;
        
     public void actionPerformed(ActionEvent e)
        
            rx+=rvelx;
            ry+=rvely;
            bx+=bvelx;
            by+=bvely;
            if (rx> 600 || rx <0)
            
                blueWins = true;
            

            if (ry<0 || ry>600)
            
                blueWins = true;
            
            if (bx>600 || bx<0)
            
                redWins = true;
            
            if (by>600 || by<0)
            
                redWins = true;             
                            
            repaint();              
        

     public void redWins(Graphics g)
     
         g.setColor(Color.black);
            g.fillRect(0,0,600,600);
            g.setColor(Color.white);
            g.drawString("RED HAS WON!!!!!", 250, 250);
            g.drawString("Click Anywhere to Start Another Game", 250, 350);  
     
     public void blueWins(Graphics g)
     
         g.setColor(Color.black);
            g.fillRect(0,0,600,600);
            g.setColor(Color.white);
            g.drawString("BLUE HAS WON!!!!!", 250, 250);
            g.drawString("Click Anywhere to Start Another Game", 250, 350);
     
     public void drawSurface(Graphics g)
     
        g.setColor(Color.black);
        g.fillRect(0,0,600,600);
        g.setColor(Color.white);
        for (int x = 0; x <= 600; x+=25)
            g.drawLine(x,0,x,600);
        for (int y= 0; y <=600; y+=25)
            g.drawLine(0,y,600,y);
     

【问题讨论】:

你曾经调用过init 方法吗?此外,由于您使用的是 JPanel,因此您应该改用 Key Bindings。 也许最后:repaint(100L); 稍后强制更新屏幕。 见this。 【参考方案1】:

KeyListener 上的键绑定

恕我直言,使用Key bindings 是一种更灵活、更可靠的方法,具有以下好处:

将动作本身与击键区分开来。 有不同的条件可以触发这些操作:WHEN_FOCUSEDWHEN_IN_FOCUSED_WINDOWWHEN_ANCESTOR_OF_FOCUSED_COMPONENT 我们可以利用这些条件,根据基于优先级的策略将不同的操作附加到不同的组件(参见here 提供的示例)。

话虽如此,您可以创建KeyStrokes,如下所示:

KeyStroke upKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
KeyStroke leftKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0);
KeyStroke downKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
KeyStroke rightKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);

您还可以指定按键释放事件触发按键:

KeyStroke upReleasedKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true);

注意: 0 表示没有修饰符,true 是一个标志,表示击键表示按键释放事件。详情请见the API。

最后,您应该使用WHEN_IN_FOCUSED_WINDOW 条件将不同的操作附加到面板的输入映射(面板不可聚焦)。

另请参阅此主题:Key bindings vs. key listeners in Java 和 How to Use Key Bindings 教程

进行自定义绘画

请注意,您不应覆盖 paint(...) 方法,而应覆盖 paintComponent(...)。见A Closer Look at the Paint Mechanism

【讨论】:

以上是关于KeyListener 出现问题 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

jQuery根据name属性进行选择

Android 的 EditText 问题:KeyListener

java keylistener 未调用

我的 KeyListener 无法读取按键输入

简单的 KeyListener 不起作用

如何为 JavaFX 编写 KeyListener