Reputation: 143
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);
}
}
Upvotes: 0
Views: 348
Reputation: 46841
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) {
}
}
Upvotes: 1
Reputation: 324098
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.
Upvotes: 2