I am getting the following error:
Exception in thread "main" java.lang.NullPointerException
at BallContainerImage.update(BallContainerImage.java:101)
at BallContainer.addBall(BallContainer.java:93)
at Game.ejectBall(Game.java:92)
at LotteryTestB.main(LotteryTestB.java:19)
Line 19 contains:
dramaticGame1.ejectBall();
the Dramatic Game class contains the following:
public class DramaticMachine extends Machine
{
// Constructor is given the person's name.
public DramaticMachine(String name, int length)
{
super(name, length);
}
public Ball ejectBall()
{
if (getNoOfBalls() >= 0)
return null;
else
{
//Math.random() * getNoOfBalls yields a number
//which is >=0 and < number of balls.
int ejectedBallIndex = (int) (Math.random() * getNoOfBalls());
for (int selectedBallIndex = 0; selectedBallIndex < ejectedBallIndex; selectedBallIndex++)
{
Ball selectedBall = getBall(selectedBallIndex);
selectedBall.flash(4, 5);
}
Ball ejectedBall = getBall(ejectedBallIndex);
ejectedBall.flash(4, 5);
swapBalls(ejectedBallIndex, getNoOfBalls() -1);
removeBall();
return ejectedBall;
}//else
}//ejectBall
public String getType()
{
return "Dramatic Lottery Machine";
}//getType
}//dramaticMachine
How can i fix this?
This is the code for the DramaticGame class:
public class DramaticGame extends Game
{
// Constructor is given the person's name.
public DramaticGame(String machineName, int machineSize, String rackName, int
rackSize)
{
super(machineName,machineSize,rackName,rackSize);
}
public Machine makeMachine(String machineName, int machineSize)
{
return new DramaticMachine(machineName, machineSize);
}//makeMachine
}
This is the code for LotteryTestB:
public class LotteryTestB
{
public static void main (String args[])
{
SpeedController speedController
= new SpeedController(SpeedController.HALF_SPEED);
LotteryGUI gui = new LotteryGUI("TV Studio", speedController);
Worker worker = new TraineeWorker("Jim",0);
DramaticGame dramaticGame1 = new DramaticGame("Lott O'Luck Larry", 49,
"Slippery's Mile", 7);
gui.addGame(dramaticGame1);
worker.fillMachine(dramaticGame1);
for (int count = 1; count <=dramaticGame1.getRackSize(); count++)
{
dramaticGame1.ejectBall();
speedController.delay(40);
}//for
}//main
}//LotteryTestB
NullPointerException is one of the easier problems to chase down. It means that some reference wasn't initialized properly. It should be easy to figure out by stepping through your code with a debugger.
If you are incapable of using a debugger, the stack trace makes this easy for you. There are only four places to look, and it says exactly where they are.
at BallContainerImage.update(BallContainerImage.java:101)
at BallContainer.addBall(BallContainer.java:93)
at Game.ejectBall(Game.java:92)
at LotteryTestB.main(LotteryTestB.java:19)
It's not the bottom one. The reference to dramaticGame is the only one on that line, and you call new to initialize it. Go on to the next one. Add a log or print statement to prove where the null reference is, then go and initialize it properly.
I don't think your code is layered properly. You'll never get this working unless you can decompose the problem into smaller chunks, unit test them until they work, and then use that code to build up the complex solution.
Separate UI from the game itself. Get the game working, then worry about display issues.
Related
I am having issues with my code regarding exception in thread main. This is the error that is popping up
Exception in thread "main" java.lang.IllegalStateException: Attempt to create a stack whose capacity exceeds allowed maximum of 10000
at ResizeableArrayStack.checkCapacity(ResizeableArrayStack.java:74)
at ResizeableArrayStack.ensureCapacity(ResizeableArrayStack.java:82)
at ResizeableArrayStack.push(ResizeableArrayStack.java:28)
at ResizeableArrayStack.evaluatePostfix(ResizeableArrayStack.java:98)
at ResizeableArrayStack.main(ResizeableArrayStack.java:157)
This is my code
import java.util.*;
public class ResizeableArrayStack<T> implements StackInterface<T>
{
private T[] stack;
private int topIndex;
private boolean integrityOK = false;
private static final int DEFAULT_CAPACITY = 50;
private static final int MAX_CAPACITY = 100000;
public ResizeableArrayStack()
{
this(DEFAULT_CAPACITY);
}
public ResizeableArrayStack(int initialCapacity)
{
integrityOK = false;
checkCapacity(initialCapacity);
// The cast is safe because the new array contains null entries
#SuppressWarnings("unchecked")
T[] tempStack = (T[])new Object[initialCapacity];
stack = tempStack;
topIndex = -1;
integrityOK = true;
}
public void push(T newEntry) {
checkIntegrity();
ensureCapacity();
stack[topIndex + 1] = newEntry;
topIndex++;
}
private void checkCapacity(int capacity) {
if (capacity > MAX_CAPACITY) {
throw new IllegalStateException("Attempt to create a stack whose capacity exceeds allowed
maximum of " + MAX_CAPACITY);
}
} // end checkCapacity
private void ensureCapacity() {
if (topIndex >= stack.length - 1) {
// If array is full, double its size
int newLength = 2 * stack.length;
checkCapacity(newLength);
stack = Arrays.copyOf(stack, newLength);
}
} //end ensureCapacity
public static void main(String[] args) {
String input = "ab*ca-/de*+";
ResizeableArrayStack<String> astack = new ResizeableArrayStack<>(input.length());
int evaluation = astack.evaluatePostfix(input);
System.out.println("Evaluating Postfix Expressions");
System.out.println("The evaluation of the postfix expression is " + evaluation);
}
}
I'm pretty sure the issue is with how the capacity values are set and compared but I can't figure out why I am getting this error. I think the issues are within the constructors that involve capacity and main method. Please ignore the evaluatePostfix method in the main as the errors all say they come from the constructors and main. I can put the evaluatePostfix up if you think the problem is within it. I also deleted the methods that weren't brought up in the problem.
The code you posted is not a MCVE. It doesn't compile because it is missing methods including checkIntegrity and evaluatePostfix. Even after I work around the missing methods, the code you posted does not cause IllegalStateException to be thrown. At a guess, after looking through the code that you did post, as well as the stack trace, the culprit appears to be method ensureCapacity which contains the following line:
int newLength = 2 * stack.length;
The value assigned to newLength may be greater than MAX_CAPACITY.
After you assign a value to newLength, you call method checkCapacity which explicitly throws a IllegalStateException.
private void checkCapacity(int capacity) {
if (capacity > MAX_CAPACITY) {
throw new IllegalStateException("Attempt to create a stack whose capacity exceeds allowed maximum of " + MAX_CAPACITY);
}
} // end checkCapacity
But as I wrote earlier, in the code that you posted capacity is never greater than MAX_CAPACITY and hence the code in your question never throws IllegalStateException.
I recommend that you run your code through a debugger. If you are using an IDE, then it should give you the option of running your code in "debug" mode. If you don't know how to use the debugger of the IDE then you should learn because knowing how to debug code is an essential skill for a programmer and a debugger helps a lot when it comes to debugging your code.
I'm having bad times with creating typical card/deck class in java. I've read some similar questions & answers but either they're not relatable/helpful or I can't simply comprehend it yet.
Here's the code
public class Cards {
boolean isAvailable;
int card_id;
static final int AC = 32;
public Cards [] deck = new Cards[AC];
public void set () {
int a = 0;
for (int i = 0; i < AC; i++) {
if(a == 4) a = 0;
deck[i].isAvailable = true; // <---------
deck[i].card_id = i + (a * 101); // <---------
a++;
}
}
public void read () {
for (int i = 0; i < AC; i++)
System.out.println(deck[i].isAvailable + " " + deck[i].card_id);
}
public static void main (String[] args) {
Cards c = new Cards();
c.set();
c.read();
}
}
Exception in thread "main" java.lang.NullPointerException
at Cards.set(Cards.java:13)
at Cards.main(Cards.java:24)
1.
I've read about similar issues and found that problem can be in initialization of an array and I've tried to do the same with my prog but it went bad anyway.
I marked 13th and 14th lines because they are being pointed (when i comment 13th line just for check, pointer sets to the next line).
2.
Next part of help I would like to get from you is:
Even though there is main (for training purposes), I see other class using this class (which just creates deck) so I guess I won't be needing main... Is everything well set besides probs in first point?
Very simple:
public Cards [] deck = new Cards[AC];
creates an empty array with AC number of slots for Cards objects.
Now you have to put a non-null Cards object into each slot!
But thing is: actually your abstraction is broken.
You wrote code that seems to take one card to be the same as a card set - by adding that array of Cards into your Cards class! And that makes it actually hard to fix your current code. As the "normal" way to fix this would be to add a constructor like
public Cards() {
deck = new Cards[AC];
for (int i=0; i<deck.length;i++) {
deck[i] = new Cards();
}
If you try that ... you immediately run into an endless recursion (creating one new Cards would result in creating AC new Cards (to fill the array); causing a stackoverflow very soon.
Thus the real answer goes somewhere along these lines:
public class Card {
... a class that represents a SINGLE card in your game
and then
public card GameOfCards {
... a class that (for example!) uses an array to hold n objects of class Card!
Finally, as Peter is indicating in his comment: you should learn to use debugging means to work on such problems yourself. One good way: before using any data structure, iterate it and print out its content. Or even better, learn how to use a debugger, and walk through your code step by step! As you should please understand: this is very basic stuff; that you normally should not bring forward here.
I'm really really stuck and hope that someone can help me. I read and read and still don't understand how to fix my stackoverflow error. I know that its in my constructor, but i don't know how to fix it.
I am creating a derived class called FractionBottle that extends the Bottle class. The FractionBottle class as a private data memeber: Fraction myFraction = new Fraction(); Here is my constructor in my Bottle Class:
public class Bottle
private final int MAX_PILLS = 120;
private int pillsInBottle;
public Bottle()
{
pillsInBottle = 0;
}
Here's what I have in my FractionBottle class:
public class FractionBottle extends Bottle
{
Fraction myFraction = new Fraction();
public FractionBottle()
{
super();
myFraction.getNumerator();
myFraction.getDenominator();
}
public FractionBottle(int wholeValue, int num, int den)
{
super(wholeValue);
myFraction.set(num, den);;
}
public void read()
{
super.read();
System.out.println("Pleas enter value for fraction part:");
myFraction.read();
}
public FractionBottle add(FractionBottle other)
{
FractionBottle sumOfBottles = new FractionBottle();
sumOfBottles = this.add(other);
sumOfBottles.myFraction = this.myFraction.add(other.myFraction);
return (sumOfBottles);
}
Here's the demo I'm using:
public class FractionBottleDemo
{
public static void main (String args[])
{
FractionBottle fbl1 = new FractionBottle();
FractionBottle fbl2 = new FractionBottle();
FractionBottle fbl3 = new FractionBottle();
System.out.println("Enter info for whole value for fbl1: ");
fbl1.read();
System.out.println("Enter infor for whole value for fbl2: ");
fbl2.read();
System.out.println(fbl1);
System.out.println(fbl2);
fbl3 = fbl1.add(fbl2);
}
}
I am really stuck on this assignment for class, and I've been at it for a few days now. I'm getting the following error:
Exception in thread "main" java.lang.StackOverflowError
at FractionBottle.<init>(FractionBottle.java:7)
at FractionBottle.add(FractionBottle.java:32)
the last lin repeats several times...
Please tell me how to fix this! I know its going into a infinite recursive loop. but i don't know how to fix it. My add method in my FractionBottle class, must return a FractionBottle.
Thank you!!!!
Looks like you have an infinite recursive call inside the add method.
sumOfBottles = this.add(other);
All recursive functions require a check to break out of the recursive calls.
Since, you are wanting to call the Bottle's add method.
Replace above line with
sumOfBottles = super.add(other);
Obviously the error lies here:
public FractionBottle add(FractionBottle other){
...
sumOfBottles = this.add(other);
...
}
because you are calling to the add method from this very method, and that causes an infinite number of recursive callings and then, your StackOverflowError
Maybe what you want to do is to call Bottle's add method that is:
public FractionBottle add(FractionBottle other){
...
Bottle sumOfBottles = new FractionBottle();
sumOfBottles = super.add(other);
...
}
that is much safer and wouldn't cause infinite loops
I need to write a parent Java class that classes using recursion can extend. The parent class will be be able to realize whenever the call stack changes ( you enter a method, temporarily leave it to go to another method call, or you are are finsihed with the method ) and then print it out. I want it to print on the console, but clear the console as well every time so it shows the stack horizantaly so you can see the height of each stack to see what popped off and what popped on... Also print out if a baseline was reached for recursive functions.
First. How can I using the StackTraceElements and Thread classes to detect automatically whenever the stack has popped or pushed an element on without calling it manually?
Second, how would I do the clearing thing?
For instance , if I had the code:
public class recursion(int i)
{
private static void recursion(int i)
{
if(i < 10)
System.out.println('A');
else
{
recursion(i / 10 );
System.out.println('B');
}
}
public static void main(String[] argv)
{
recursion(102);
}
}
It would need to print out the stack when entering main(), when entering recursion(102) from main(), when it enters recursion(102 / 10), which is recursion(10), from recursion(102), when it enters recursion(10 / 10), which is recursion(1) from recursion(10). Print out a message out when it reaches the baseline recursion(1).. then print out the stacks of reversed revisitation of function recursion(10), recursion(102) and main(). finally print out we are exiting main().
Thread class allows managing OS threads, it does not have anything to do with the call-stack. StackTraceElement represents a stack-frame but you need a StackTrace to get to it.
You are looking for a notification for when the stack-trace changes, for example a frame is added (a method is entered) or removed (a method is exited).
By far the most appropriate tool for this task is AspectJ. It lets you define advices (a kind of method) that gets called (besides other cases) when other methods are entered or existed. These triggers that result in the advices getting called are called pointcuts -- they can be method entry, exit and the methods can be described using wildcards: the pointcut MyClass.get* applies to all get methods of MyClass.
I started to write my own before seeing your answer. It is simplistic in form but the shell is:
package stackTraceLogger;
import java.util.ArrayList;
public class StackTraceLogger
{
static final int MAX_ROW = Integer.MAX_VALUE;
static final int MAX_COLUMN = Integer.MAX_VALUE;
static public ArrayList<ArrayList<String>> stringTrace;
//private ArrayList<ArrayList<StackTraceElement>> stack;
public StackTraceLogger()
{
stringTrace = new ArrayList< ArrayList <String>>();
//stack = new ArrayList<ArrayList<StackTraceElement>>();
}
static public void addStack(StackTraceElement[] inputTrace)
{
int size = inputTrace.length;
// make an ArrayList with the strings of all the StrackTraceElements
ArrayList<String> str = new ArrayList<>(size);
for(int i = 0; i < size; i++)
{
str.add(i,inputTrace[i].getMethodName());
}
// Add the ArrayList to the 2D ArrayList of the stacks
}
static public void printTrace()
{
/* if(stringTrace.get(0).size() > 0)
{
for(int i = 0; i < stringTrace.size(); i++)
{
System.out.println(stringTrace.get(i));
for(int j = 0; j < stringTrace.get(j).size(); j++)
System.out.println(stringTrace.get(i).get(j));
}
}*/
}
static private ArrayList<String> convertToArrayList(StackTraceElement[] inputTrace)
{
ArrayList<String> strTrace = new ArrayList<>();
for(int j = 0; j < inputTrace.length; j++ )
strTrace.add(inputTrace[j].getMethodName());
return strTrace;
}
}
I'm learning about constructors.
When I try to compile the following code, I get the error "variable input and shape are not initialized."
Could anyone tell me why and how to solve it?
public class Try {
public static void main(String[] args)
{
String input;//user key in the height and width
int shape;//triangle or square
Count gen = new Count(input , shape);//is this the right way to code?
gen.solve();
}
}
public class Count {
public Count(String inp, int shp) {
String input_value = inp;
shape_type = shp;
}
public void solve () {
if shape_type==3{
//count the triangle
}
else if shape_type==4{
//count the square
}
}
}
You haven't given shape or input values yet before you try using them. Either you can give them dummy values for now, like
String input = "test";
int shape = 3;
Or get the string and integer from the user; in that case, you might want to take a look at how to use a Scanner.
By leaving input and shape without values, at:
String input;
int shape;
they are uninitialized, so Java doesn't know what their values really are.
I assume this is some kind of homework. I took the liberty of reformating and fixing your code a little.
You have to initialize any variable you are going to use. The only exception is when you are using class members (those are initialized automatically to some default value). See below that the members of the Count class aren't explicitly initialized.
This is some working code. Also note that i change the solve method a little (the if blocks should have had () around the expression. But what you are trying to do is usually better done with a switch block as shown below. Also I declared two members inside the Count class to remember the values provided at construction time in order to be able to use them when calling the solve() method.
public class Try {
public static void main(String[] args) {
String input = null; //user key in the height and width
int shape = 0; //triangle or square
Count gen = new Count(input, shape);//is this the right way to code?
gen.solve();
}
}
class Count {
String input_value;
int shape_type;
public Count(String inp, int shp) {
this.input_value = inp;
this.shape_type = shp;
}
public void solve() {
switch (this.shape_type) {
case 3:
// count the triangle
break;
case 4:
// count the square
break;
}
}
}
Proper formatting of the code usually helps :).