KeyListener not changing the JPanel

霸气de小男生 提交于 2019-12-13 07:34:40

问题


So i have created an extended version of JPanel and unfortunately it doesn't respond to any key typing. Could you tell me what the problem is? I searched all the others posts but i couldn't find my error.

public class MyPanel extends JPanel implements ActionListener,KeyListener{

Timer tm=new Timer(5,this);
int x=0,y=0 ,velX=0, velY=0;

public MyPanel(){
    tm.start();
    addKeyListener(this);
    setFocusable(true);
    requestFocusInWindow();
}

public void paintComponent(Graphics g){
    super.paintComponent(g);

    g.fillRect(0,0,this.getWidth(),this.getHeight());
     g.setColor(Color.RED);
    g.fillRect(x,30,50,30);



}

public void actionPerformed(ActionEvent e){

    if(x<0||x>370)
    velX=-velX;

    if(y<0||y>370)
    velY=-velY;

    y=y+velY;
    x=x+velX;
    repaint();
}

public void keyPressed(KeyEvent e){
    int c=e.getKeyCode();
    System.out.println("Cascsadas");
    if(c==KeyEvent.VK_LEFT){
        velX=-1;
        velY=0;
    }

    if(c==KeyEvent.VK_UP){
        velX=0;
        velY=-1;
    }

     if(c==KeyEvent.VK_RIGHT){
        velX=1;
        velY=0;
    }

    if(c==KeyEvent.VK_DOWN){
        velX=0;
        velY=1;
    }

}

public void keyTyped(KeyEvent e){};
public void keyReleased(KeyEvent e){};



}

And the class where i am using this JPanel is:

public class Tester
{
   public static void main(String[] args){

    MyPanel t=new MyPanel();
    JFrame jf=new JFrame();
    jf.setTitle("Tutorial");
    jf.setVisible(true);
    jf.setSize(600,400);
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.getContentPane().add(t,BorderLayout.CENTER);

}
}

回答1:


Your code doesn't work because your panel doesn't have focus.

The requestFocusInWindow() method only works when the panel is displayed on GUI is visible. Invoking the method in the constructor has no effect (and is not needed).

However, the real problem is that you add the panel to the frame AFTER the frame is visible. Your code should be something like:

jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.getContentPane().add(t,BorderLayout.CENTER);
jf.setSize(600,400);
jf.setVisible(true);

The key is adding the panel to the content pane before the frame is made visible. It also doesn't make sense to make the frame visible and then change its size, so I always make the frame visiable as the last statement.

I searched all the others posts but i couldn't find my error

I find that hard to believe. This question is asked daily and we always recommend to use Key Bindings, so why are you still trying to use a KeyListener?

Swing was designed to be used with Key Bindings. See Motion Using the Keyboard for more information and an approach that does use Key Bindings.




回答2:


I have posted an answer in the same context here

Diagonal movement of a simple sprite (up-down-left-right movement already done).

This post about KeyListener will help you to understand it more.


Here is the sample code to start:

(moving in all the direction left,right,top,bottom and diagonally also)

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Set;
import java.util.TreeSet;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Apple extends JPanel implements ActionListener, KeyListener {

    Timer timer = new Timer(5, this); // this refers to actionListener
    int x = 0, velx = 0;
    int y = 0, vely = 0;

    public Apple() {
        timer.start();
        addKeyListener(this); // this refers to keylistener
        setFocusable(true);
        setFocusTraversalKeysEnabled(false); // because we are not using the shift or ctrl key
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // outer rectangle
        g.setColor(Color.BLUE);
        g.fillRect(x, y, 50, 50);
    }

    public static void main(String[] args) {
        Apple apple = new Apple();
        apple.setSize(500, 500);
        JFrame frame = new JFrame();
        frame.add(apple);
        frame.setLayout(null);
        frame.setTitle("The Game");
        frame.setSize(500, 500);
        frame.setVisible(true);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

    @Override
    // animates rectangle
    public void actionPerformed(ActionEvent arg0) {
        if (x < 0) {
            velx = 0;
            x = 0;
        }
        if (x > 450) {
            velx = 0;
            x = 450;
        }
        if (y < 0) {
            vely = 0;
            y = 0;
        }
        if (y > 450) {
            vely = 0;
            y = 450;
        }

        x = x + velx;
        y = y + vely;
        repaint();
    }

    // Set of currently pressed keys
    private final Set<Integer> pressed = new TreeSet<Integer>();

    @Override
    public void keyPressed(KeyEvent arg0) {
        System.out.println(KeyEvent.VK_LEFT + "-" + KeyEvent.VK_RIGHT + "-" + KeyEvent.VK_UP + "-"
                + KeyEvent.VK_DOWN);
        int c = arg0.getKeyCode();
        pressed.add(c);
        if (pressed.size() > 1) {
            Integer[] array = pressed.toArray(new Integer[] {});
            if (array[0] == KeyEvent.VK_LEFT && array[1] == KeyEvent.VK_UP) {
                velx = -4;
                vely = -4;
            } else if (array[0] == KeyEvent.VK_UP && array[1] == KeyEvent.VK_RIGHT) {
                velx = 4;
                vely = 4;
            } else if (array[0] == KeyEvent.VK_RIGHT && array[1] == KeyEvent.VK_DOWN) {
                velx = 4;
                vely = -4;
            } else if (array[0] == KeyEvent.VK_LEFT && array[1] == KeyEvent.VK_DOWN) {
                velx = -4;
                vely = 4;
            }
        } else {
            if (c == KeyEvent.VK_LEFT) {
                velx = -4;
                vely = 0;
            } else if (c == KeyEvent.VK_RIGHT) {
                velx = 4;
                vely = 0;
            } else if (c == KeyEvent.VK_UP) {
                velx = 0;
                vely = -4;
            } else if (c == KeyEvent.VK_DOWN) {
                velx = 0;
                vely = 4;
            }
        }

    }

    @Override
    public void keyReleased(KeyEvent arg0) {
        velx = 0;
        vely = 0;

        pressed.remove(Integer.valueOf(arg0.getKeyCode()));
    }

    @Override
    public void keyTyped(KeyEvent arg0) {

    }
}


来源:https://stackoverflow.com/questions/22697284/keylistener-not-changing-the-jpanel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!