OutOfBoundsException with JavaFX - java

I have a problem with my code. I'm writing a program that has to manage weekly squat trainings. There is the possibility to record a previous training or to program a full week. In the second case, for each day, user has to put in the number of squat and the difficulty he thinks it will be. I manage the difficulty of each day with a choicebox that has 3 voices (easy, medium, hard) and when I read the value selected, I save it as an int in order to use it easly for other things in the program (easy=1, medium=2, hard=3).
Now, my problem is that I have 7 choiceBox, one per day, and I need just one method to handle them. Everytime user select a value from one of those choiceBox, it should call the method that scans the value of all the 7 choiceBox and update the relative int values. I adopted this solution because I use only one method for 7 choiceBox and I don't know which one calls the method. To do this, I created a vector of choiceBox and I use a for cicle from 0 to < .length, but everytime I select a voice in any choiceBox, the cicle goes out of bounds. I also created a relative array of int to save the different difficulties.
Here the exception and my method:
Exception in thread "JavaFX Application Thread" java.lang.ArrayIndexOutOfBoundsException: 7
public void weekDifficulties() {
for (j = 0; j < arrayCB.length; j++) {
arrayCB[j].getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue ov, Number oldValue, Number newValue) {
if ((Integer) newValue >= 0 && (arrayCB[j].getItems().get((Integer) newValue).equals("Easy")))
arrayDifficulties[j] = "1";
else if ((Integer) newValue >= 0 && (arrayCB[j].getItems().get((Integer) newValue).equals("Medium")))
arrayDifficulties[j] = "2";
else if ((Integer) newValue >= 0 && (arrayCB[j].getItems().get((Integer) newValue).equals("Hard")))
arrayDifficulties[j] = "3";
}
});
}
}
Thanks for helping

j seems to be a field. In that case when the listeners are triggered, it contains the value last assigned to it, which is arrayCB.length = arrayCB.length (= the first int where the j < arrayCB.length yielded false). This of course leads to a ArrayIndexOutOfBoundsException.
Since you obviously need to access the value of the j field at the time the loop body is executed, you need to copy it to a variable:
for (j = 0; j < arrayCB.length; j++) {
final int index = j;
arrayCB[j].getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue ov, Number oldValue, Number newValue) {
if ((Integer) newValue >= 0 && (arrayCB[index].getItems().get((Integer) newValue).equals("Easy")))
arrayDifficulties[index] = "1";
...
}
});
}
Furthermore j probably shouldn't be declared a field in the first place

Check if the arrayCB.length and arrayDifficulties.length are equal otherwise you would get java.lang.ArrayIndexOutOfBoundsException. Else
EDIT
Can you store the index j in final variable and use it in the changed method. Possibly it get incremented by the time change Listener notify the method.

Related

How to create an if/then boolean string to execute autoclick

I'm trying to create a simple Java GUI window in which when I a number is placed in the window, the program determines what the value of the number is (ie greater than 2, or less than 2), and then executes an autoclick depending on the int value.
private void buttonActionPerformed(java.awt.event.ActionEvent evt) {
for (int field = 0; field <= 2; field++) {
if (field <= 2) {
(EXECUTE AUTOCLICK;
}
else if ( field >= .15 ) {
do nothing
Obviously it's broken and the 'EXECUTE AUTOCLICK' is not a function, but I figured i'd put it in to show what i'm trying to accomplish.
Additionally, how would I add an auto click function into the code and where would I add it?
Can you tell tell that I'm a noob?

Array not looping correctly Java

I have a simple fact app that has an array of different facts.
I have a next, previous, and home button.
When the home button is pressed, I want the first fact to be displayed again, and after, it will start incrementing again from the first array value.
My home button is not working. If I hit the next button 5 times, then hit the home button, I will be directed to the first fact, but if I hit the next button, then the 6th fact will display, not the second.
Here is my code:
public String nextFact() {
i++;
if(i >= facts.length) {
i = 0;
}
return facts[i];
}
public String previousFact() {
i--;
if(i < 0) {
i = facts.length - 1;
}
return facts[i];
}
public String homeButton() {
int i = 0;
return facts[i];
}
You are declaring a new local version of i.
It should be:
public String homeButton() {
i = 0;
return facts[i];
}
According to your code, I am assuming i is a variable shared across the three methods, which keeps track of the index of the question currently displayed. If that is the case, your method should reset the class member i to 0, instead of creating a local variable.
public String homeButton() {
i = 0;
return facts[i];
}
This should do the trick.

Getting an"index:0" and "size:0" error from ArrayList.size()

I have been working on this program for hours, and have worked out nearly all of the errors that have cropped up in every other class. This one, however, I can's seem to fix the receive method. The receive method should first check (by comparing SKUs) whether or not the incoming product is already in myCatalog. If not, add the product (via its SKU) to the catalog. After that, in any case -- as long as there is still some of the incoming product not yet been placed in a bin -- I want to locate which bin contains the least total quantity. (If all the bins are full, add a new, empty bin to use)I'd add that specific product to that bin until the bin is either full -- at which point I'd repeat -- or I run out of the product. This repeats until no more incoming product is left.
public class Warehouse
{
private int myBinMax;
private ArrayList<MusicMedia> myCatalog;
private ArrayList<Bin> myBins;
public Warehouse( int binMax )
{
myBinMax = binMax;
myCatalog = new ArrayList<MusicMedia>();
myBins = new ArrayList<Bin>( 5 );
}
public String toString()
{
return Tester.detailedInventory(myCatalog,myBins);
}
public void addBin()
{
myBins.add( new Bin( "B" + myBins.size() ) );
}
public void receive( MusicMedia product, int quantity )
{
boolean contained = false;
int lowestAmount = myBinMax,
leastFullBinIndex,
i,
insertQuantity;
for(MusicMedia entry : myCatalog)
{
if(entry.getSKU().equals(product.getSKU()))
{
contained = true;
}
}
if(!contained)
{
myCatalog.add(product);
}
while(quantity > 0)
{
lowestAmount = myBinMax;
for(i = 0; i < myBins.size(); i++)
{
if(myBins.get(i).totalQuantity() < lowestAmount)
{
lowestAmount = myBins.get(i).totalQuantity();
leastFullBinIndex = i;
}
if((i == myBins.size() - 1 && lowestAmount == myBinMax)||(myBins.size() == 0))
{
myBins.add(new Bin("bin" + Integer.toString(i)));
}
}
if(quantity >= myBinMax - lowestAmount)
{
insertQuantity = myBinMax - lowestAmount;
}
else
{
insertQuantity = quantity;
}
quantity -= insertQuantity;
myBins.get(i).add(new BinItem(product.getSKU(), insertQuantity));
}
}
}
Before my last edit, nothing would print -- just a blank console -- but in an attempt to fix that, I added this (also contained within the code above):
if((i == myBins.size() - 1 && lowestAmount == myBinMax)||(myBins.size() == 0))
{
myBins.add(new Bin("bin" + Integer.toString(i)));
}
Now, it won't run without giving me an error:
java.lang.IndexOutOfBoundsException
Index: 0, Size 0 (in java.util.ArrayList)
As well as highlighting the following line:
myBins.get(i).add(new BinItem(product.getSKU(), insertQuantity));
Here's a breakdown on the various classes that have been created for this colossal program:
MusicMedia has three private variables, but the only one that has any bearing here is the String mySKU, obtained by getSKU()
Bin has a private String, name, which is also its only argument, as well as a private ArrayList of class BinItem. In order to access this ArrayList of BinItems from another class, you would use getContents(). It also has method totalQuantity(), which returns the total quantity of objects already in a bin.
BinItem has private variables mySKU (String) and myQuantity (int) and methods getSKU() and getQuantity(), both being its arguments in that order
So to start with you have no bins.
Your "for" block is skipped because size is zero;
So we get to the final line of the "while" loop, and we execute myBins.get(i)...
This is where we get the error because we can't get the bin at index 0, because we got no bins at all.
The problem is we reached this line of code without adding any bins...
I'm not sure if you realized, the line below doesn't start your program with 5 bins.
myBins = new ArrayList<Bin>( 5 );
The 5 in this code sets the internal buffer for the array to hold 5 items. If we supplied no number it would start with 10. But the numbers are just there to give programmers control over how much memmory is initalized.
If your goal was to start with 5 bins, you should do something as follows:
myBins = new ArrayList<Bin>( 5 );
for(int i=0; i<5; i++){
myBins.add(new myBin());
}

Checking Left/Right in an int array for Tetris, Android/Java

I'm trying to make a tetris game for android to help learn game programming for android. My goLeft/Rights break right when the button is pressed, the code for going left is in a class separate of the fields int array, and the list parts array. The fields array is accessed by a referenced variable (TetrisWorld tetrisworld;). While part list array is public so accessed through a variable(part) code for which is in the goLeft() code. It breaks at: if(tetrisworld.fields[x][part.y] != 0) Code for left:
public void goLeft() {
int x = 0;
for(int i = 0; i < 4; i++) {
TetrisParts part = parts.get(i);
x = part.x - 1;
if(tetrisworld.fields[x][part.y] != 0) {
noleft = true;
break;
}
}
if(noleft == false) {
for(int i = 0; i < 4; i++) {
TetrisParts part = parts.get(i);
part.x--;
}
}
}
The code for the fields int array:
int fields[][] = new int[WORLD_WIDTH][WORLD_HEIGHT];
WORLD_WIDTH and WORLD_HEIGHT are both static final ints, width being 9 and height being 19
I've tried putting if(tetrisworld.fields[0][0] == 0) and it still crashes so I don't think it has to do with the variables. Also It doesn't go out of bound even if I haven't added the code to check for that yet because I have the teroid spawning around x = 5 and since I can't go left/right once there's not a chance of that happening
I've tried moving the goLeft/Right methods to the gamescreen class which has a "world = TetrisWorld();" and it still bugs out at the same spot
UPDATE:
Ok just adding:
tetrisworld != null
to the first if statement fixed it, my question now is, why did it fix it? Why can't I move without this check? It clearly isn't null cause as far as I know; it's fully responsive now.
But an easier way to have solved this which is SOOOO easy is changing fields to static... then access it lika so: TetrisWorld.fields so my updated code is:
public void goLeft()
{
noleft = false;
for (int i = 0; i < 4; i++)
{
part = parts.get(i);
if (part.x - 1 < 0 || TetrisWorld.fields[part.x - 1][part.y] != 0)
{
noleft = true;
break;
}
}
if (noleft == false)
{
for (int i = 0; i < 4; i++)
{
part = parts.get(i);
part.x--;
}
}
}
Looks like you are hitting IndexOutOfBoundsException.
When you are doing x = part.x - 1;, your x variable can become lesser tan zero, thus your code will act like if(tetrisworld.fields[-1][part.y] != 0
It looks like you're getting a java.lang.NullPointerException when trying to access the array in tetrisworld. In the line you mention there are several ways that this could occur:
if(tetrisworld.fields[x][part.y] != 0) {
tetrisworld could be null.
The fields member of tetrisworld could be null.
The second array that you're looking up by using tetrisworld.fields[x].
The value of part could be null.
Having a quick look through your source code it looks to me like you never initialise tetrisworld, either at declaration using:
TetrisWorld tetrisworld = new TetrisWorld();
Or at some other point which is certain to have happened before your goLeft() method is called.
Ok I believe I found the answer, referencing: http://en.wikipedia.org/wiki/Null_Object_pattern
Apparently java will throw an NPE if you don't check for it first if you have a null reference? Is there any way to initialize it without doing a TetrisWorld tetrisworld = new TetrisWorld(); because it's already created in a different class so i get a thousand errors, an actual stack overflow! lul... Still not 100% positive. Please comment to verify and possibly suggest a better way to go about this.

help manipulating a 3D array

This game is a 3D version of tic-tac-toe with 3 boards. Each position on the boards are made up of [x,y,z] coordinates. x is the number of the board and y,z are the coordinates on that board. I'm trying to define a method that only lets you choose from the first board for the first 9 turns of the game, but am having problems. Here is the code.
public void set(Position p, int v) throws IOException {
if (board[p.x][p.y][p.z]!= 0) throw new IOException("Position taken");
board[p.x][p.y][p.z] = v;
I'm not sure what to add to this method to only allow moves on board one for the first 9 turns. I have tried using a counter such as an if statement such as...
public void set(Position p, int v) throws IOException {
int counter = 0;
if (board[p.x][p.y][p.z]!= 0) throw new IOException("Position taken");
board[p.x][p.y][p.z] = v;
while (counter < 10) {
if (p.x != 1) throw new IOException("Invalid Move");
}
When I tried this and other manipulated versions of this same method I kept getting the "Invalid Move" error everytime, even when p.x was equal to 1. Any suggestions on how to loop this or any other ways to accomplish this?
You really ought to do your own learning rather than asking us to do your homework assignments for you. I am not going to answer your question but I will point out that there are several huge problems with your code:
1: counter is scoped within the set method and will therefore always be set zero at the start of that method even if this is the 20th turn.
2: counter is never incremented and will therefore always have its initial value.
3: Arrays in Java start at zero not one.
4: IOException is not a suitable exception for this method to throw as it is not doing any IO.
[...] only lets you choose from the first board for the first 9 turns of the game [...]
Note that the first element of an array has index 0, so you may want to change
p.x != 1
to
p.x != 0
Also, I think you have a problem with:
int counter = 0;
// ...
// ...
while (counter < 10) {
if (p.x != 1)
throw new IOException("Invalid Move");
}
as it will go into an infinite loop.
You probably want to have counter as a member variable and do counter++ in the move method (if the move was successful).

Categories