NullPointerException with JFrame - java

At the moment all I want this program to do is run without any compile errors. Basically, what I need it to do is open the frame and then when the frame is selected, if I press the up arrow key it will set arrows[0] to true and when I release it it will set it to false (same with right, down, and left as well)...
My code will compile. However, I keep getting this error when I try to run it.
java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)
I've done a program somewhat similar to this before and I never had this problem. I originally thought it was because of the "frame.addKeyListener;" or the "frame.setFocasable(true);" but I tried taking those lines out and it still came up with the error...
Here's the code that I am running, any help to fix this problem would be helpful.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.lang.*;
public class arrowTest extends JApplet implements KeyListener {
private boolean[] arrows = new boolean[4];
private int x = 0;
private int y = 0;
public arrowTest() {
}
// Handle the key typed event from the text field.
public void keyTyped(KeyEvent e) {
System.out.println("KEY TYPED: ");
}
// Handle the key-pressed event from the text field.
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
arrows[0] = true;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
arrows[1] = true;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
arrows[2] = true;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
arrows[3] = true;
}
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
arrows[0] = false;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
arrows[1] = false;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
arrows[2] = false;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
arrows[3] = false;
}
}
public void run() {
JFrame frame = new JFrame();
JApplet applet = new arrowTest();
frame.add(applet);
frame.setTitle("arrowTest");
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);
frame.setVisible(true);
frame.addKeyListener(this);
frame.setFocusable(true);
}
public void main(String[] args) {
run();
}
}

At the moment all I want this program to do is run without any compile errors.
For the record, your program does run without "compile errors". What's happening is you're getting an null pointer exception (NPE) thrown during the running of the program, not a compile error. You need to find out what line is causing your NPE and then fix it by making sure all reference variable have been initialized before using them.
But also, you should not be using KeyListeners for this but instead use Key Bindings -- there's a big difference. The Key Binding tutorial will explain all. It may appear a bit daunting at first, but don't give up, follow the examples, and you'll be using it in no time.
And why are you using JApplet anything when you're trying to create a JFrame? That's just a bit funky.
Edit 2
And your code won't even run since your main method is non-static. If you're running your program as an actual JFrame, then you'll need to show us the actual code that you've used. This code has no viable main method and thus isn't it.
Edit 3
No, static isn't your problem, still you need to learn to use key binding and to not mix JApplet and JFrame code in this strange chimera you've got.

Related

Java - KeyListener Multiple Keys

Now I know this topic has been brought up several times, here: Swing's KeyListener and multiple keys pressed at the same time, here: How do I have multiple key inputs Listened to at the same time and here: How do I handle simultaneous key presses in Java? for instance. So I can't really expect to get any different kind of help than what's in these examples. I have also read that most of you suggest that I use KeyBindings instead of KeyListeners for the situation I'm in (see below) which I now have decided to do. However I still want to know if you guys have any idea as to why my code is acting up.
So the situation, I am making a simple 2D game. I have been following thenewboston's tutorials to get started and he recommended KeyListeners. They've been working fine for me until now when I encountered a rather weird bug.
The problem is that when I steer my spaceship up to the left it will not shoot. This only happens in this particular direction (out of the eight possible) and also if I'm already shooting I cannot steer my ship towards the top left corner.
Below is the code where I know the problem occurs. I really see no good explanation as to why though. I honestly do believe there is something wrong where my computer cannot register the up arrow, left arrow and the space bar being pressed at the same time. The ultimate proof of this then is of course that when I change the fire button from space bar to F, for instance, the code runs without issues.
//Imports
public class SpaceGame extends Core implements KeyListener{
public static void main (String[] args){
SpaceGame sg = new SpaceGame();
sg.init();
sg.run();
}
//Making all variables
private ScreenManager s;
private AffineTransform identityTransform;
private Image bg;
private Image[] shipImage = new Image[2];
private Image[] missileImage = new Image[2];
private String shipLocations[] = {/*IMAGE LOCATIONS*/};
private String missileLocations[] = {/*IMAGE LOCATIONS*/};
private Animation shipAnimation;
private Animation missileAnimation;
private Ship ship;
private ArrayList<Shot> shotList = new ArrayList<Shot>();
private boolean shooting;
private int shots = 0;
public void init(){
//Makes image objects, animations and some other stuff.
}
//This is called from the core class which has a continously running while loop in it.
public void update(long timePassed){
if(shooting){
makeShot();
}
ship.update(timePassed);
for(Shot shot : shotList){
if(shot.getAlive()){
shot.update(timePassed);
}
}
}
public void makeShot(){
//Makes shots
}
public synchronized void draw(Graphics2D g, long time) {
Window w = s.getFullScreenWindow();
w.setFocusTraversalKeysEnabled(false);
w.addKeyListener(this);
g.drawImage(bg, 0, 0, null);
for(Shot shot : shotList){
if(shot.getAlive()){
g.setTransform(shot.getTransform());
g.drawImage(shot.getImage(), Math.round(shot.getCorsClone()[0]), Math.round(shot.getCorsClone()[1]), null);
}
}
g.setTransform(ship.getTransform());
g.drawImage(ship.getImage(), Math.round(ship.getCorsClone()[0]), Math.round(ship.getCorsClone()[1]), null);
g.setTransform(identityTransform);
}
//Where the problem occurs
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_ESCAPE){
stop();
} else if(keyCode == KeyEvent.VK_UP){
ship.setDY(-1);
e.consume();
} else if(keyCode == KeyEvent.VK_RIGHT){
ship.setDX(1);
e.consume();
} else if(keyCode == KeyEvent.VK_DOWN){
ship.setDY(1);
e.consume();
} else if(keyCode == KeyEvent.VK_LEFT){
ship.setDX(-1);
e.consume();
} else if(keyCode == KeyEvent.VK_SPACE){
shooting = true;
e.consume();
}
}
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_UP){
ship.setDY(0);
e.consume();
} else if(keyCode == KeyEvent.VK_RIGHT){
ship.setDX(0);
e.consume();
} else if(keyCode == KeyEvent.VK_DOWN){
ship.setDY(0);
e.consume();
} else if(keyCode == KeyEvent.VK_LEFT){
ship.setDX(0);
e.consume();
} else if(keyCode == KeyEvent.VK_SPACE){
shooting = false;
e.consume();
}
}
public void keyTyped(KeyEvent e) {
e.consume();
}
}
So to conclude my question is a vague one of sorts. Is there something special with the space bar I don't know about, is there in fact a bug in my program or maybe, just maybe is there something wrong with my keyboard?
Any comments, ideas, complaints about my coding, complaints about my English, strong opinions about whether to use KeyListeners or KeyBindings, code you feel like you need to see or anything at all just give me a shout and I shall try to be quick to respond.
A lot of people have that problem. It is called Keyboard Ghosting and means that some combinations simply don't work on cheap keyboards. Thats why high class gaming keyboards exists. So nothing wrong with your code. No optimization possible. You need to use key combination that work. To proof my answer here are some links for you.
http://board.flashkit.com/board/showthread.php?789015-wont-respond-to-keyboard-up-left-and-space-at-the-same-time
http://forums.steampowered.com/forums/showthread.php?t=1928521
http://www.tomshardware.co.uk/answers/id-2159074/alt-space-bar-work-holding-left-arrow.html
https://unix.stackexchange.com/questions/268850/leftupspace-keys-not-working-on-thinkpad-x201

Tick Method not Recognizing Variable Change

I am currently working on a Pac-Man remake in Java, and I am having a problem with player movement. I use a KeyListener to detect when the W A S or D keys are pressed, and sets a variable as true or false. The variables are up, down, left, right. This works fine, but the "tick" method does not recognize the value change, almost as if there are two variables. For example, I will press the W key and up is set to true. In the tick method, however, up is not true. This also happens when getting the position of the player. It will only get the first position of the player, but after I edit the position in the KeyListener method, the tick method will not recognize that the position has been changed.
I have also found that when I move the position directly from the KeyListener method and print it to the console, it works correctly. But when I print the position from the tick method, it always prints the original position. If I print both, it seems as if there are two variables, because the KeyListener method will always print the correct value, and the tick method will always print the original, but does not reset the KeyListener value.
Sorry if this sounds confusing, please ask if you need me to describe it in a different way.
Anyway, the tick method is being called 60 times every second.
Can someone please help me fix this problem? Help is appreciated.
Here is the class for the Player, containing the tick and KeyListener methods.
package com.graysullivan.entities;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import com.graysullivan.main.Location;
public class Player implements KeyListener {
Location pos;
private int width = 80;
private int height = 80;
private boolean up, down, left, right;
public Player() {
pos = new Location(360, 701);
}
public void init() {
}
public void tick(double deltaTime) {
//System.out.println(pos.y);
if(up) {
System.out.println("up");
pos.y--;
}
if(down) {
pos.y++;
}
if(left) {
pos.x--;
}
if(right) {
pos.x++;
}
}
public void render(Graphics2D g) {
g.fillRect((int)pos.x,(int)pos.y, 40, 40);
}
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_W) {
up = true;
System.out.println(up);
}
if(key == KeyEvent.VK_S) {
down = true;
}
if(key == KeyEvent.VK_A) {
left = true;
}
if(key == KeyEvent.VK_D) {
right = true;
}
if(key == KeyEvent.VK_DELETE) {
System.exit(0);
}
}
#Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_W) {
up = false;
}
if(key == KeyEvent.VK_S) {
down = false;
}
if(key == KeyEvent.VK_A) {
left = false;
}
if(key == KeyEvent.VK_D) {
right = false;
}
}
#Override
public void keyTyped(KeyEvent e) {
}
Looking at your code, there is a part that look suspicious.
In Game.java you created an instance of Player
frame.addKeyListener(new Player());
Another instance of Player is also created in LevelLoader.java
Player player = new Player();
...which is the one that getting the tick method triggered.
They are two different objects which has nothing to do with each other (other than the fact that they are from the same class). Changing a state of one object doesn't change the state of another. What happen in your case is that the first Player instance listen to key press but the second instance is getting the tick method triggered.
What you need to do is to create a player instance in Game.java and pass the object to LevelLoader.java (via StateManager.java?) instead of creating another instance in LevelLoader.java itself.
I think what you need is to declare synchronized on the method which manipulate up, down, right, and left to avoid memory consistency error and thread interference.
Something like this:
public synchronized void tick(double deltaTime) {
...
}
Edit: you might want to declare the members with volatile to ensure that the changes in keyPressed method happens before the tick.

Java KeyListener not detecting all pressed arrow keys

I am working on a game which takes keyboard input, and a lot of the time you need several keys pressed at the same time. For example, you want to be holding down space to shoot, up arrow to thrust, and left or right arrow to turn. However, the arrow keys act very strangely. Most of the time the keypressed method will not recognize a third arrow key being pressed, and sometimes it is even weirder: it will detect the wrong key if other keys are being held. I understand that's pretty confusing so I made a program to show it:
package resources;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class Keys extends JPanel implements ActionListener, KeyListener {
Timer t = new Timer(5, this);
ArrayList<String> keyspressed;
public Keys() {
JFrame f = new JFrame();
f.setSize(350, 100);
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
f.add(this);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
t.start();
keyspressed = new ArrayList<String>();
}
public void actionPerformed(ActionEvent e) {
repaint(); System.out.println(keyspressed);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString(showKeysPressed(), 20, 20);
}
public String showKeysPressed() {
String s = "Currently pressed keys: ";
for(int i = 0; i < keyspressed.size(); i++) {
s+= keyspressed.get(i) + " ";
}
return s;
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP && !keyspressed.contains("Up"))
keyspressed.add("Up");
if(e.getKeyCode() == KeyEvent.VK_RIGHT && !keyspressed.contains("Right"))
keyspressed.add("Right");
if(e.getKeyCode() == KeyEvent.VK_LEFT && !keyspressed.contains("Left"))
keyspressed.add("Left");
if(e.getKeyCode() == KeyEvent.VK_DOWN && !keyspressed.contains("Down"))
keyspressed.add("Down");
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP)
keyspressed.remove("Up");
if(e.getKeyCode() == KeyEvent.VK_RIGHT)
keyspressed.remove("Right");
if(e.getKeyCode() == KeyEvent.VK_LEFT)
keyspressed.remove("Left");
if(e.getKeyCode() == KeyEvent.VK_DOWN)
keyspressed.remove("Down");
}
public static void main(String[] args) {
new Keys();
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}
Here are a few things to do with that program to show what I mean:
-Hold space, up arrow, and then try to press left or right arrow. (The program only displays array keys because that's what is being weird)
-With a little bit of time in between, hold space, up arrow, and right arrow so up and right are being displayed, and then as you take your finger off of right arrow, hold left arrow. If it is not just my keyboard, it will stay as right arrow being pressed.
So does anyone know what is causing this? Is it just my keyboard? This is really frustrating to try to work with gameplay-wise.
Thanks in advance.
Use these library's instead
http://ksquared.de/blog/releases/stable/keyboard_hook-0.3.zip
these have proper mapping of arrow keys and can efficiently detect multiple key presses, Although JNativeHook is far better than this.

Java KeepPushing Key game Listener

I did a game where ship is moving like i wanna to move him. But my problem is when i have pushed a button. My ship is move but he have to wait a 1 sec to start moving in right way.
public void keyPressed(KeyEvent e) {
int jakiPrzycisk = e.getExtendedKeyCode();
if(jakiPrzycisk == 39 )
{
kierunek="prawo";
czyRuch = true;
}
if(jakiPrzycisk == 37)
{
kierunek="lewo";
czyRuch = true;
}
if(jakiPrzycisk == 38)
{
kierunek="gora";
czyRuch = true;
}
if(jakiPrzycisk == 40)
{
kierunek="dol";
czyRuch = true;
}
In game im checking if he will move with "czyRuch" and i move in right direction with "kierunek". There is a way to fastest reading from keybord ?
Don't use "magic numbers". 37, 38, 39 40 mean nothing to anybody reading your code.
But my problem is when i have pushed a button. My ship is move but he have to wait a 1 sec to start moving in right way.
Then you have a problem with code that is not posted. Java will respond to the KeyEvent right away.
However, there is a "delay" for repeating an event if the key is held down. This delay is OS dependent. If you need the ability to handle repeat events, then you should be using your own Timer to schedule these events. Check out Motion Using the Keyboard for more thoughts on this subject as well as working code.
Yes im sorry that was my mistake. Now i can show u an example where i've got a problem.
There is a example code
public class KeyTest extends JFrame implements KeyListener {
long start;
long end;
public KeyTest() {
super("KeyListener Test");
setPreferredSize(new Dimension(300, 100));
addKeyListener(this);
start = System.nanoTime();;
pack();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void keyPressed(KeyEvent evt) {
end = System.nanoTime();;
char c = evt.getKeyChar();
System.out.print(c+" ");
System.out.println(end-start);
}
#Override
public void keyReleased(KeyEvent evt) {
}
#Override
public void keyTyped(KeyEvent evt) {
}
}
and when i press any key for example "s". Ive got a
s 810407913
s 1312851842
s 1344314575
s 1377971356
s 1409969550
s 1441512603
s 1475051136
s 1507228263
between first and second "s" is a lot of difference. This is why my ship is stoping for a while when i wanna to press any key for few seconds but i dont know how to change that difference between time

Inconsistent keyPressed event: sometimes fires, sometimes doesn't, restart the program without changing anything and it might or might now work

Okay, so I'm pretty frustrated here.
This piece of code here is just a very simple moving JComponent.
What's odd is how, when I'm changing absolutely nothing, the keyPressed event will be incredibly inconsistent. I start the program, and sometimes it'll work, and my ball will move around the screen. On the other hand, I'll close it and open it without changing anything, and it'll fail to work. I don't think focus is a problem here, though I really don't know much about it. I have no idea what's going on.
Any help would be appreciated. I just don't see how the program could so inconsistently fail and succeed.
And here's my code in the character's class, because I don't think just giving you a snippet will help. I don't know if it's just me, or whatever, but if you want to compile it and see, go ahead.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Character extends JComponent implements KeyListener
{
Timer timer = new Timer(5, new TimeListener());
private int x = 250;
private int y = 300;
char whichTimer;
public Character()
{
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
repaint();
}
public void keyReleased(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_W)
{
timer.stop();
}
if(e.getKeyCode() == KeyEvent.VK_A)
{
timer.stop();
}
if(e.getKeyCode() == KeyEvent.VK_S)
{
timer.stop();
}
if(e.getKeyCode() == KeyEvent.VK_D)
{
timer.stop();
}
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_W)
{
timer.stop();
whichTimer = 'W';
timer.start();
}
if(e.getKeyCode() == KeyEvent.VK_A)
{
timer.stop();
whichTimer = 'A';
timer.start();
}
if(e.getKeyCode() == KeyEvent.VK_S)
{
timer.stop();
whichTimer = 'S';
timer.start();
}
if(e.getKeyCode() == KeyEvent.VK_D)
{
timer.stop();
whichTimer = 'D';
timer.start();
}
}
public void keyTyped(KeyEvent e)
{
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// g2d.drawImage(fatsprite, x-10, y-10, null);
g.setColor(Color.BLACK);
g.fillOval(x-10, y-10, 20, 20);
}
class TimeListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(whichTimer == 'W')
{
y-=1;
repaint();
}
if(whichTimer == 'A')
{
x-=1;
repaint();
}
if(whichTimer == 'S')
{
y+=1;
repaint();
}
if(whichTimer == 'D')
{
x+=1;
repaint();
}
}
}
}
Make sure the component is focusable and has focus. Also, it is better to use Key Bindings, see How to Use Key Bindings for more details.
#Max is correct, KeyBindings is better approach to your problem. The key problem (sorry, no pun intended) is that once focus moves to any other component, you will no longer receive key events. Now, you're probably thinking, "but I didn't change focus" - you only need to click on another focusable component to loss key focus, or press tab, which KeyListener won't generally be notified of.
Generally, as you've found, KeyListeners are unreliable, not only are they only ever going to get notification while the component in question has focus, keys can be consumed before they reach you
1. The problem is that you are loosing focus over your components here.
2. Do check that your components are focusable, try using KeyBinding
3. Moreover do remember this... In Swings the focus moves from Left to Right and Top to Bottom, where as in AWT, its according to the sequence in which the components were added to the container.

Categories

Resources