Beginner Java Program-- cannot get key pressed to work - java

I am starting out with Java and I have a problem. When people click "a" on the java applet, I want it to draw a yellow rectangle and if they press anything else it draws a black rectangle but nothing happens.
import java.awt.*;
import java.applet.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
public class guitarGame extends Applet implements ActionListener, KeyListener{
Timer timer = new Timer (1000, this);
String s = "";
char a;
int selection;
public void keyReleased(KeyEvent ae){}
public void keyPressed(KeyEvent ae){}
public void keyTyped(KeyEvent ae){
a = ae.getKeyChar();
}
public void init(){
addKeyListener(this);
}
public void actionPerformed (ActionEvent ae)
{
if (a == a)
{
selection = 1;
}
else{
selection = 2;
}
}
public void paint (Graphics g)
{
if (selection == 1){
g.setColor(Color.YELLOW);
g.fillRect(100,100,100,100);
}
if (selection == 2){
g.setColor(Color.YELLOW);
g.fillRect(100,100,100,100);
}
repaint();
}
}
Any help?

You are not doing anything with your KeyListener methods. Your ActionListener will never be called as it hasnt been registered with any component.
public void keyPressed(KeyEvent ae){
char keyChar = ae.getKeyChar();
if (keyChar == 'a' ) {
selection = 1;
} else {
selection = 2;
}
repaint();
}
Some suggestions:
Don't call repaint inside paint - This will cause the latter to loop indefinitely
Use enums rather than magic numbers for paint selection.
Call super.paint(g)
Consider using Swing which has much better performance over the old heavyweight AWT.

Related

KeyListener doesn't work at all but my code worked fine on my friend's computer

KeyListener doesn't work at all it's like it's not there, it shows the frame with the paddle but it doesn't move when arrowkey pressed , BUT my code worked properly on my friend's computer , i deleted and installed the last version of JDK and eclipse and nothing changed , i even compilated it with cmd and it doesn't work
edit : one in a 100 tries it works properly then the next time it returns to not working
the code is about a paddle that moves with arrowkeys
the Paddle class :
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
public class Paddle extends JPanel implements KeyListener{
private int x=900,y=280 ;
private int sx=20,sy=20 ;
private int valY=0;
public Paddle() {
setFocusable(true);
requestFocus();
addKeyListener(this);
}
public void paintComponent(Graphics g) {
draw(g);
update();
repaint();
}
public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, 1000, 1000);
g.setColor(Color.ORANGE);
g.fillRect(x, y, sx, sy);
}
public void update() {
this.y+=this.valY;
}
public void keyTyped(KeyEvent e) {
System.out.println("typed");
}
public void keyPressed(KeyEvent e) {
System.out.println("typed");
int c=e.getKeyCode();
if (c==KeyEvent.VK_UP){
this.valY=-1;
}
if(c==KeyEvent.VK_DOWN){
this.valY=1;
}
}
public void keyReleased(KeyEvent e) {
valY=0;
}
}
You are violating some rules of custom painting. The fact that it worked at all was mostly luck.
First, remove your call to repaint(). It is causing paintComponent to be called again, which calls repaint, which calls paintComponent, which calls repaint, etc. You are creating a very fast infinite loop which uses up most of Swing’s resources. Instead, call repaint() whenever you change the data on which your drawing relies.
Second, you are not accounting for the fact that painting occurs for many reasons. You don’t control most of them. paintComponent may be called when you move or resize the window, or even when the mouse moves over the window, or for a number of other reasons.
Since it is impossible to predict when the system will request that your class paint its contents, you must not change the state of your object in paintComponent. You must not call your update() method from paintComponent, either directly or indirectly.
The correct way to regularly update your state is to call your updating method from a Timer. For instance:
// Update every 250 milliseconds, that is, 4 times per second.
Timer timer = new Timer(250, e -> update());
timer.start();
Finally, whenever you override paintComponent, the first line of code needs to be a call to super.paintComponent(g);. If you don’t do that, you will eventually see strange painting artifacts. This is discussed in the Performing Custom Painting tutorial.
Your issue appears to have to do with the KeyListener and Focus. I am going to suggest an alternative technique. Use the InputMap/ActionMap for the panel.
KeyStroke us = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false);
panel.getInputMap().put(us, "UP");
panel.getActionMap().put("UP", new AbstractAction(){
#Override
public void actionPerformed(ActionEvent evt){
//call what ever
}
});
When I do this, I don't have to request focus, I have a JFrame and a JPanel, as long as the JFrame is focus, then the respective actions get triggered by the keys.
Here is a complete example that moves a circle around a JPanel.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.EventQueue;
import java.awt.Color;
import javax.swing.KeyStroke;
import javax.swing.AbstractAction;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
public class BallGame{
int x;
int y;
JPanel panel = new JPanel(){
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.RED);
g.drawOval(x-5, y-5, 10, 10);
}
};
public void start(){
JFrame frame = new JFrame();
frame.add(panel);
frame.setSize(640, 480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
KeyStroke us = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false);
KeyStroke ds = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false);
KeyStroke ls = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false);
KeyStroke rs = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false);
panel.getInputMap().put(us, "UP");
panel.getInputMap().put(ds, "DOWN");
panel.getInputMap().put(ls, "LEFT");
panel.getInputMap().put(rs, "RIGHT");
panel.getActionMap().put("UP", new AbstractAction(){
#Override
public void actionPerformed(ActionEvent evt){
up();
}
});
panel.getActionMap().put("DOWN", new AbstractAction(){
#Override
public void actionPerformed(ActionEvent evt){
down();
}
});
panel.getActionMap().put("LEFT", new AbstractAction(){
#Override
public void actionPerformed(ActionEvent evt){
left();
}
});
panel.getActionMap().put("RIGHT", new AbstractAction(){
#Override
public void actionPerformed(ActionEvent evt){
right();
}
});
}
public void up(){
y = y - 5;
y = y<0? panel.getHeight() : y;
panel.repaint();
}
public void down(){
y = y + 5;
y = y>panel.getHeight() ? 0 : y;
panel.repaint();
}
public void left(){
x = x - 5;
x = x<0 ? panel.getWidth() : x;
panel.repaint();
}
public void right(){
x = x + 5;
x = x>panel.getWidth() ? 0 : x;
panel.repaint();
}
public static void main(String[] args){
BallGame bg = new BallGame();
EventQueue.invokeLater( bg::start );
}
}
Check out the api though because you can tune it to catch modifiers and when to trigger the action. In case you want to monitor when the key is pressed and when it is released etc.

Why is my KeyPressed method never called?

I am trying to write my first PacMan game. So I followed a guide and created a small game engine and now I am writing code in the PacMan.java file which includes the game engine as a package. The problem is, the guide instructs you to override the KeyPressed method, but when I do this NOTHING happens. The PacMan on the screen is supposed to change its direction according to what arrowkeys I press according to the KeyPressed() method but when I press the arrowkeys NOTHING happens. I can't control the little pacman through the arrowkeys even though I have the code for it!
I even put a simple System.out.println(); statement inside the KeyPressed() method to see if the KeyPressed() method is even ever actually called, but it is NEVER called it seems? "pressed the key" isn't being printed out when I press the arrowkeys and neither is the PacMan moving when I press them. Can anyone understand why my KeyPressed method won't be called when I press my arrowkeys?
My code:
package game.pacman;
import org.game.engine.Game;
import org.game.engine.GameApplication;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class PacMan extends Game {
public static void main(String[] args){
GameApplication.start(new PacMan());
}
BufferedImage pacman;
int frame;
int dir;
int x, y;
final int STEP = 2;
public PacMan(){
title = "PacMan";
frame = 0;
dir = KeyEvent.VK_RIGHT;
x = 300;
y = 200;
width = height = 400;
try {
pacman = ImageIO.read(new File("images/packman.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void keyPressed(KeyEvent e){
System.out.println("pressed the key");
dir = e.getKeyCode();
}
#Override
public void update(){
frame++;
if (frame > 2){
frame = 0;
}
switch (dir){
case KeyEvent.VK_LEFT:
x -= STEP;
break;
case KeyEvent.VK_RIGHT:
x += STEP;
break;
case KeyEvent.VK_UP:
y -= STEP;
break;
case KeyEvent.VK_DOWN:
y += STEP;
}
if ( x < 0){
x = 0;
} else if (x > width-28-STEP){
x = width-28-STEP;
}
}
#Override
public void draw(Graphics2D g) {
g.drawImage(pacman.getSubimage(frame*30,(dir-37)*30,28,28), x, y, null);
}
}
Obviously it is supposed to override (through the package) a method KeyPressed inside a class Game.java inside the game engine which implements KeyListener, MouseListener, MouseMotionListener. Here is the whole code code for that class:
package org.game.engine;
import java.awt.*;
import java.awt.event.*;
public abstract class Game implements KeyListener, MouseListener, MouseMotionListener{
protected boolean over;
protected int delay = 30;
protected int width = 400;
protected int height = 400;
protected String title = "MyGame";
public String getTitle(){
return title;
}
public long getDelay(){
return delay;
}
public int getWidth(){
return width;
}
public int getHeight(){
return height;
}
public void init(){}
abstract public void update();
abstract public void draw(Graphics2D g);
public boolean isOver(){
return over;
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
}
So as you can see the KeyPressed() method is just empty inside the class and this is how the guide instructs it to be. I am overriding it in the PacMan class (my main class). So why isn't either the arrow keys working, why isn't even the KeyPressed method being called at all when I run the program? Is something missing to call the KeyPressed() method?
Though you implement the handlers in Game class and ovveride them in subclass, you haven't registered the handler to the element you want.
For ex, inside Game class,
something.onKeyPress(this)
// where this is Game class which is of type KeyListener, MouseListener, MouseMotionListener
you have to register component with Key-Listener for that do likewise,
If your component is JTextField then it should be likewise,
JTextField typingArea = new JTextField(20);
typingArea.addKeyListener(this);
while press key inside, typingArea - JTextField it will called this method too,
public void keyPressed(KeyEvent e) {
displayInfo(e, "KEY PRESSED: ");
}

Trying to repaint a jpanel

Please note that I am quite new to all this programming. Right now i have a frame which adds a panel to it. I have use the paintcomponent method on the panel I believe, but now when i am trying to use keylisteners i need to move the image that i have drawn on the panel. I currently do not know how to repaint it.
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings
("serial")
public class Game extends JPanel implements KeyListener
{
Car fo = new Car();
draw a=new draw();
public Game()
{
JFrame frame2=new JFrame("JASA1 Racing");
frame2.add(new draw());
frame2.setSize(500,600);//set frame size
frame2.setVisible(true);//made frame visible
frame2.setResizable(false);
frame2.addKeyListener(this);
frame2.setFocusable(true);
}
public class draw extends JPanel
{
private static final long serialVersionUID = 1L;
public void redraw()
{
repaint();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
ImageIcon ic2=new ImageIcon("C:\\Users\\Shawn\\track.jpg");
Image img=ic2.getImage();
g.drawImage(img, 0, 0,null);
g.drawImage(fo.getcar(),fo.getX(),fo.getY(),null);
System.out.println(fo.getX() + " " + fo.getY());
}
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if(key == KeyEvent.VK_LEFT)
{
fo.move(-50, 0);
System.out.print(fo.getX());
a.repaint();
}
else if(key == KeyEvent.VK_RIGHT)
{
fo.move(50, 0);
System.out.print(fo.getX());
a.redraw();
}
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
}
draw a=new draw(); isn't what you've added to the frame, you've used frame2.add(new draw()); instead.
Try using frame2.add(a);
I'd also consider using Key Bindings as it will allow you to overcome the focus issues related to KeyListener

KeyPress won't work [duplicate]

This question already has answers here:
None of the event occurs
(3 answers)
Closed 8 years ago.
For some reason my program doesn't detect when I press a key even though it should be fine.
This is my code:
import javax.swing.*;
public class Frame {
public static void main(String args[]) {
Second s = new Second();
JFrame f = new JFrame();
f.add(s);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Bouncing Ball");
f.setSize(600, 400);
}
}
This is the Second class:
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.event.KeyListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import javax.swing.*;
public class Second extends JPanel implements ActionListener, KeyListener {
Timer t = new Timer(5, this);
double x = 0, y = 0, velX =0 , velY = 0;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Rectangle2D circle = new Rectangle2D.Double(x, y, 40, 40);
g2.fill(circle);
t.start();
}
public void actionPerformed(ActionEvent e) {
x += velX;
y += velY;
repaint();
}
public void up() {
velY = -1.5;
velX = 0;
}
public void down() {
velY = 1.5;
velX = 0;
}
public void keyPressed(KeyEvent e) {
int KeyCode = e.getKeyCode();
if (KeyCode == KeyEvent.VK_Z) {
up();
}
if (KeyCode == KeyEvent.VK_S) {
down();
}
}
public void keyTyped(KeyEvent e){
}
public void keyReleased(KeyEvent e){
}
}
How can I solve this problem?
The reason the timer doesn't appear to work is because, velX and velY are equals to 0, so, it doesn't increment anything. If you give them a value, it will animate.
The reason the Keys won't work is
because you haven't registered the KeyListener to the panel.
you need to setfocusable(true).
You need to call repaint() in the either the up() down() methods or in the keyPressed() method.
You need to increment/decrement the y value in the up() and down() methods.
Add the below constructor, add the repaint() to the keyPressed() and increment/decrement correctly and it works
public Second(){
setFocusable(true);
addKeyListener(this);
}
Add the above constructor. And the repaint in the keyPressed
public void keyPressed(KeyEvent e) {
int KeyCode = e.getKeyCode();
if (KeyCode == KeyEvent.VK_Z) {
up();
repaint();
}
if (KeyCode == KeyEvent.VK_S) {
down();
repaint();
}
}
Increment/Decrement
public void up() {
y -= 10;
}
public void down() {
y += 10;
}
Though this may work, it is recommended to use key bindings.
See How to use Key Bindings | The complete Creating a GUI with Swing trail
For testing purposes, add a listener to the JFrame and see if you get any response there. If you do, then it means that the JFrame isn't passing the events down to the Second, probably because the Second doesn't have focus.
You could also try calling requestFocusInWindow(): http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html
A component generally gains the focus when the user clicks it, or when the user tabs between components, or otherwise interacts with a component. A component can also be given the focus programmatically, such as when its containing frame or dialog-box is made visible. This code snippet shows how to give a particular component the focus every time the window gains the focus:
//Make textField get the focus whenever frame is activated.
> f.addWindowFocusListener(new WindowAdapter() {
> public void windowGainedFocus(WindowEvent e) {
> s.requestFocusInWindow();
> } });
I would also recommend using more descriptive variables than s, f, and a more descriptive class name than Second.

Java - KeyListener not working

This has been making me want to tear out my hair all day. I'm trying to make it so when I press the right-arrow key, my speed will go to 10. I know that my methods that make my sprite move work, because if I set a value beforehand, it moves across the screen. It's the KeyListener that isn't doing anything:
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class Sprite implements KeyListener{
public Image player = Toolkit.getDefaultToolkit().getImage("player.png");
int x, y, dx, dy;
public void doInit(){
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(600, 400);
window.setLocationRelativeTo(null);
window.getContentPane().add(new ImageDraw());
window.setVisible(true);
window.setIgnoreRepaint(true);
window.createBufferStrategy(2);
window.getContentPane().addKeyListener(this);
}
public Image getSpriteHandle(){
return player;
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_RIGHT){
dx = 10;
}
} //end keyPressed
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_RIGHT){
dx = 0;
}
}
public void keyTyped(KeyEvent arg0) {
}
public int moveX(){
return dx;
}
} //end class
Please help me!
It's the KeyListener that isn't doing anything
You should NOT be using a KeyListener.
Swing was designed to be used with Key Bindings. You can map an Action to a KeyStroke even when a component doesn't have focus.

Categories

Resources