Getting NPE after creating new object of class - java

I'm trying to make a 'game' using swing and I'm experiencing a problem which I can't solve. It's probably something easy and obvious but I still can't figure out. Here's a piece of my code:
public class LevelOne {
private static Crate[] crates = new Crate[3];
public LevelOne(){
crates[0].setX(200);
crates[0].setY(200);
crates[1].setX(280);
crates[1].setY(40);
crates[2].setX(440);
crates[2].setY(40);
}
//more code here
}
I try to create object of LevelOne class to make my crates variable living. (is this a way to do so?).
public static void main(String[] args) {
LevelOne l = new LevelOne();
JFrame frame = new JFrame("blabla");
Board board = new Board();
frame.add(board);
frame.setSize(805, 830);
frame.setVisible(true);
frame.setFocusable(false);
frame.setResizable(false);
frame.setDefaultCloseOperation(3);
frame.setLocation(400, 200);
board.requestFocus(true);
}
It gives me NPE at line
LevelOne l = new LevelOne();
As I said, it's a small piece of project but I think this might solve whole issue. I'm using this Crate[] crates to paint components on my board, to check collision and other stuff. Without creating object of LevelOne class, I still get NPE when trying to draw them. Any suggestions, ideas, solutions?

You forgot to initialize elements in crates:
private static Crate[] crates = new Crate[3];
public LevelOne(){
crates[0] = new Crate(); // <= add this
crates[0].setX(200);
crates[0].setY(200);
// same for other elements

You have to propagate Crate object into your crates array. You are getting NullPointerException because crates array doesn't have any reference of Carte in it. Do the following.
private static Crate[] crates = new Crate[3];
public LevelOne(){
for(int i = 0; i < crates.length; i++)
crates[i] = new Crate();
crates[0].setX(200);
crates[0].setY(200);
crates[1].setX(280);
crates[1].setY(40);
crates[2].setX(440);
crates[2].setY(40);
}

Related

Java- How to ask "if a JButton is disabled then ___"

so I'm a 6th grader who's trying to program a TicTacToe program using netbeans 8.1 and java.
This is my code so far (for the sake of simplicity i've only included the code of one button):
public class TicTacToe extends JFrame{
static Random computerGenerate = new Random();
static int rounds = 0;
static JPanel panel = new JPanel();
static JButton s1 = new JButton();
public static void main(String[] args) {
Gui();
}
public static void Gui() {
JFrame Gui = new JFrame("TicTacToe");
Gui.setVisible(true);
Gui.setResizable(false);
Gui.setSize(320, 340);
Gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.setLayout(null);
Gui.add(panel);
s1.setBounds(0, 0, 100, 100);
s1.setFont(new Font("Times New Roman", Font.PLAIN, 50));
s1.addActionListener(new Response());
panel.add(s1);
}
private static class Response extends TicTacToe implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == tictactoe.TicTacToe.s1) {
s1.setText("X");
s1.setEnabled(false);
rounds += 1;
}
}
}
public static void Moves() {
if (rounds == 1) {
int computerStartPos = 1 + computerGenerate.nextInt(8);
switch (computerStartPos) {
case 1:
if (button"s1" is disabled)) {
computer will generate a new starting position for the AI
} else {
button s1 will be disabled and it will show a "O" to show the computer has selected the square
}
break;
}
}
}
}
The section which I have a problem with is the very last method, method Moves().
What I'm trying to do is, after the player has selected their starting square, the computer will generate a number, 1-9 which will determine its own starting position.
The problem I have is if the player has already selected that button before the computer, I need the computer to re-generate a new number as its starting point.
My idea to solve this is "if s1.setEnabled() is equal to false, then the computer will re-generate a new number which corresponds to its new starting position".
Is this posible to write? This is only a small time project but I would appreciate the help.
Oh, and I have been told I'm incorrectly using static in java, however if I don't include "static" in the code netbeans gives me errors for days until all of my code is like RED ERROR!!!! If anyone knows why or can explain how to properly use it please do as well :D
I sincerely appreciate any help I receive.
There is a method for checking whether a button is enabled or not...
if (button.isEnabled()) {
}else {}
and
if I don't include "static" in the code netbeans gives me errors for
days until all of my code is like RED ERROR!!
you Cannot make a static reference to the non-static field...
try dont using static things and create instances instead...
you can use as start point:
remove the static keyword from the fields, define a construtor and create an instance in the main method..
like this:
// YOU NEED A CONSTRUCTOR
public TicTacToe () {
computerGenerate = new Random();
panel = new JPanel();
s1 = new JButton();
}
public static void main(String[] args) {
TicTacToe demoExample = new TicTacToe ();
demoExample.Gui();
}
Static methods in java belong to the class (not an instance of it).
They use no instance variables and will usually take input from the
parameters, perform actions on it, then return some result
Secondly yes you can check that.
if(! s1.isEnabled())
{
...
}
Remember there is ! at the start of the condition which will check for enabled or not!

How to change jlabel text from another class

Hi I'm making an app but, I found a problem. I'm using netbeans gui builder to build my gui.
So, the first gui class has a lot of button(every button does the same function) that have an actionlistener that looks like this:
public class Guipanel extends JPanel {
private void jbtTTActionPerformed(java.awt.event.ActionEvent evt) {
if(mb.getlevel() > 16){
if(ttp != 20 && mb.getpoints() != 0){
point();
ttp++;
jbtTT.setText(""+ttp);
}
}
}
private void point(){
mb.reducepoints();
}
int ttp;
Base mb = new Base();
JButton jbtTT = new JButton();
}
The Base Class has a lot of method but the one that is related to this problem looks like this:
public class Base extends JFrame {
//point decrement method
public void reducepoints(){
points--;
jlbPoints.setText("Points Available: "+points);
}
//return point value
public int getpoints(){
return this.points;
}
//return level value
public int getlevel(){
return this.level;
}
private static int level = 1;
private static int points = 20;
private JLabel jlbPoints = new JLabel("Points Available: "+points);
}
So the problem is this, when I pressed the jbtTT the points variable will decrement so the value will change from 20 to 19. I used System.out.println to verify that. As you can see, the reducepoints() method should update the jlbPoints text which it doesnt. I have tried making the Base mb = new Base() to static Base mb = new Base() but it still doesn't work. Am I doing this wrong? Anyone have a suggestion?
EDIT: I've tried to do System.out.println(jlbPoints.getText()); and the text did changed. The only one that didn't change is the text that the user can see. Even repaint() and revalidate didn't work.
EDIT2: I finally found the answer to this question. I have to pass the 'Base' class object to the 'Guipanel' class since I created the 'Base' class object in a main class(I don't want to use this class as a main class). I passed it with the following method:
public void passObj(Base mb){
this.mb = mb;
}
and changing the constructor of 'Guipanel' class like this:
public Guipanel(Base mb) {
initComponents();
this.mb = mb;
}
also changing this Base mb = new Base(); to Base mb;
I wanted to thank everyone that have tried to answer this question.
Try using SwingUtilities.invokeLater() to ensure you are changing the text on the event dispatch thread, as you are supposed to. All we can do is guess given the current information.

How do you design a new graphic to add to a JFrame Form?

I am trying to design a very basic aircraft attitude indicator to put into a JFrame Form using Netbeans 7.3, essentially consisting of a black box with a white line in the middle that rotates proportionally with the degree of roll of the aircraft. This then needs to be put into a JFrame form to create a virtual cockpit user interface. I am a novice programmer with very limited knowledge of the Java library, so any help would be greatly appreciated!
So far, I have created the following class:
public class AttitudeIndicator extends JPanel {
private Graphics attIndBackground;
private Graphics attIndLine;
private int aILStartX;
private int aILStartY;
private int aILEndX;
private int aILEndY;
public AttitudeIndicator(int a,int b,int c,int d){
aILStartX = a;
aILStartY = b;
aILEndX = c;
aILEndY = d;
}
public void createAttitudeIndicator(){
attIndBackground.setColor(Color.BLACK);
attIndBackground.fillRect(0, 0, 200, 150);
attIndBackground.setColor(Color.RED);
attIndBackground.drawLine(0,75,200,75);
attIndLine.setColor(Color.WHITE);
attIndLine.drawLine(aILStartX,aILStartY,aILEndX,aILEndY);
}
}
The idea is that arguments a,b,c and d will change and therefore change the line with the degree of pitch and roll, but I am yet to get to that point. I have then put this into the main class to try and create it:
public static void main(String[] args) {
JFrame f = new JFrame("Title");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
AttitudeIndicator a = new AttitudeIndicator(50,50,150,75);
a.createAttitudeIndicator();
f.add(a);
f.setSize(500,400);
f.setVisible(true);
}
}
When I try to run this, I am getting a null pointer exception. Any ideas?
i think this might help you. NetBeans has a great GUI to help you make GUI's for your programs
https://netbeans.org/kb/70/java/quickstart-gui.html

Strange behavior of Java code with static attribute

I do not have much to ask really. Heck I don't even know what the question should say. Basically, this Java code works fine without any compilation errors.
public class Application {
static String[][] tiles;
public Application() {
tiles = new String[9][9];
}
public static void main(String[] args) {
Application app = new Application();
Grid mines = new Grid();
mines.fillTiles(tiles, 9, 9, 10);
}
}
class Grid {
Random rand;
public void fillTiles(String[][] tiles, int rowSize, int colSize,
int numMines) {
rand = new Random();
int rowIndex;
int columnIndex;
while (numMines > 0) {
rowIndex = rand.nextInt(rowSize);
columnIndex = rand.nextInt(colSize);
tiles[rowIndex][columnIndex] = "M";
numMines--;
}
}
}
But, when I remove the line
Application app = new Application();
from the main method in the first class, it is throwing a NullPointerException at
tiles[rowIndex][columnIndex] = new String("M");
Any reason why?
Application app = new Application();
If you don't instantiate Application, tiles will be pointing to null. Operation on null reference results in NullPointerException.
Your Array initialization logic is in constructor.
public Application() {
tiles = new String[9][9];
}
Constructor will be executed only on Object creation (new Application())
If you don't want to do Application app = new Application();
Just change static String[][] tiles=new String[9][9];
Defining static array variable doesn't mean that instantiation will happen on load. It just means that that variable is class variable.
You notice that you have instantiated your array in your constructor?
static String[][] tiles;
public Application() {
tiles = new String[9][9]; <--- Here
}
So, if you don't instantiate your Application using new Application(), your array would not be initialized, and your reference will be pointing to null.
Also, it is not a good idea to initialize your static variables in constructor. Ideally, you should initialize your static array in a static initializer block or at the place of declaration itself: -
static {
tiles = new String[9][9];
}
or
static String[][] tiles = new String[9][9];
If you initialize your array in your constructor, it will be re-initialized for every instance, every time you create one. As static variables are common to all the instances. So, the change you make to your static variable, will be reflected in all your instances.
I think I might know the reason why:
public class Application {
static String[][] tiles;
public Application() {
tiles = new String[9][9];
}
public static void main(String[] args) {
Application app = new Application();
Grid mines = new Grid();
mines.fillTiles(tiles, 9, 9, 10);
}
}
In this you have a static 2d array that holds strings called tiles. However, you only initialize it in the constructor of Application. Thus when calling "mines.fillTiles(tiles", tiles is still null and
tiles[rowIndex][columnIndex] = new String("M");
will throw a NullPointerException.
Because you are initializing tiles = new String[9][9]; in your constructor. You constructor is only called when you use new to create the object instance as new Application().
If you don't want to use the constructor, declare your static variable with initialization as:
static String[][] tiles = new String[9][9];
That should work fine without constructor call.
You are initializing the array in the constructor of an instance. If you create another instance after the first, it will re-initialize the static member.

Java how and where to initialize variable with NullPointerException

I'm having a problem where I receive this error:
Exception in thread "main" java.lang.NullPointerException
at com.noxia.Main.startCombat(Main.java:101)
at com.noxia.Area1.createArea1Enemy(Area1.java:43)
at com.noxia.Main.main(Main.java:30)
I know that I need to initialize the variables because they are null, but I can't seem to figure out what I need to put where. I've minimized the code to show just the relevant parts as there are many other variables and methods left out, but this seems to pertain to the issue. Any help would be greatly appreciated =)
public class Main {
Player p;
Enemy e;
Area1 a1;
public static void main(String[] args) {
Main main = new Main();
main.a1 = new Area1();
main.p = new Player(100);
//the line directly below this is line 30 where the error occurs
main.a1.createArea1Enemy(10);
}
public void startCombat()
{
//the line directly below this is line 101 where the error occurs
while (p.getCurrentLife() > 0 & a1.e.getLife() > 0)
{
p.playerAttack();
if (p.getCurrentLife() > 0 & a1.e.getLife() > 0)
{
e.enemyAttack();
}
}
}
public class Player extends Main {
private int currentLife;
public int getCurrentLife()
{
return currentLife;
}
public void setCurrentLife(int cl)
{
currentLife = cl;
}
public Player(int cl)
{
currentLife = cl;
}
public class Enemy extends Main {
private int life;
public int getLife()
{
return life;
}
public void setLife(int lf)
{
life = lf;
}
public Enemy (inf lf)
{
life = lf;
}
public class Area1 extends Main {
public void createArea1Enemy(int enemyCounter)
{
while (enemyCounter > 0)
{
String[] enemyList = {"Enemy1", "Enemy2"} //code for Enemy2 left out below
int enemyListLength = enemyList.length;
int randomEnemy = (int) (Math.random() * enemyListLength);
if (enemyList[randomEnemy].equals("Enemy1"))
{
Enemy enemy1 = new Enemy("Enemy1", 100);
//the line directly below this is line 43 where the error occurs
startCombat();
}
enemyCounter--;
}
}
}
The simple answer is that you have to set e to an enemy before calling startCombat.
But a better way to do this would be to remove e, and pass the enemy object to startCombat using a method parameter. The e field is conceptually wrong. To understand the wrongness, try to come up with a coherent explanation of what it means in terms of the state of a Main object.
Clearly this is beginner code ... and there are a number of bad things about what you have written:
The fields of a class should be for object state, not for passing parameter values to methods.
You should avoid writing code that accesses the innards of a class ... like your main method does.
Best practice is to make fields private, and defined getter and / or setter methods (as required) for external classes to access / modify them.
You need to learn how to write constructors with parameters.
You need to design your code properly. Everything extending Main means that there is going to be no rational model of what the objects "mean". And there's the problem that each instance of Enemy and Area1 will have their own copies of the p, e, and a1 fields, and a whole bunch of inappropriate methods.
The main problem is that you never initialize Enemy e;. You create an enemy but never assign it to this.e.
Change this line:
Enemy enemy1 = new Enemy("Enemy1", 100);
To this:
this.e = new Enemy("Enemy1", 100);
There are also many other problems with your code.
Learn how to write a constructor properly. This code is wrong.
I see no reason at all why a Play, Area1, and Enemy should extend Main.

Categories