d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Thread Help > Application Class Nullreference
12Next
Add Reply New Topic New Poll
Member
Posts: 14,631
Joined: Sep 14 2006
Gold: 575.56
Sep 20 2016 05:57pm
so... i dont really know what my problem is here
it's a very strange problem but the timeline isn't working at all throwing a nullreference exception on the toggle buttons but they're not null... i dont understand

Code
package sample;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

@Override
public void start(Stage primaryStage) throws Exception {
ToggleButton[] toggleButtons = new ToggleButton[25];
GridPane root = new GridPane();

int x = 0, y = 0;
for (ToggleButton toggleButton : toggleButtons) {
toggleButton = new ToggleButton("A");
toggleButton.setMinSize(50, 50);
toggleButton.setSelected(false);
root.add(toggleButton, x, y);
if (y < 4) {
y++;
} else if (y == 4) {
y = 0;
x++;
}
}


ToggleButton goButton = new ToggleButton("Go!");
goButton.setMinWidth(50);
root.add(goButton, 2, 6);

Timeline changeTextField = new Timeline(
new KeyFrame(Duration.millis(20), event -> {
for (ToggleButton button :
toggleButtons) {
button.setText("b");
}
})
);

goButton.setOnAction(event -> {
if (goButton.isSelected()) {
changeTextField.play();
} else {
changeTextField.stop();
}
});
primaryStage.setTitle("Game of life");
primaryStage.setScene(new Scene(root, 250, 275));
primaryStage.show();
}


public static void main(String[] args) {
launch(args);
}
}
Member
Posts: 32,925
Joined: Jul 23 2006
Gold: 3,804.50
Sep 20 2016 06:50pm
i'm skeptical about this line:
Code
for (ToggleButton toggleButton : toggleButtons) {
toggleButton = new ToggleButton("A");


i dont think that's adding your button to the array.

so i suspect that makes `button` null:
Code
for (ToggleButton button :
toggleButtons) {
button.setText("b");
}


honestly, i'd recommend using some kind of collection / arraylist so you know it's empty instead of having 25 nulls in your array. but if you want to use arrays, a small change should fix it.

Code
for (int i = 0; i < toggleButtons.length; i++){
toggleButtons[i] = new ToggleButton("A");
ToggleButton toggleButton = toggleButtons[i];
}


This post was edited by carteblanche on Sep 20 2016 07:02pm
Member
Posts: 14,631
Joined: Sep 14 2006
Gold: 575.56
Sep 20 2016 07:15pm
ya that was my problem for some reason it didn't work right in a foreach loop but when i switched it over to a regular for it worked fine

as for the list rather than an array i plan to later, i'm trying to make a little conway game of life program, i figured i'ld make a nice easy 5x5 and then scale it later
Member
Posts: 32,925
Joined: Jul 23 2006
Gold: 3,804.50
Sep 20 2016 07:35pm
Quote (Ideophobe @ Sep 20 2016 09:15pm)
ya that was my problem for some reason it didn't work right in a foreach loop but when i switched it over to a regular for it worked fine

as for the list rather than an array i plan to later, i'm trying to make a little conway game of life program, i figured i'ld make a nice easy 5x5 and then scale it later


i would advise against using buttons for the game of life. it's better to use some kind of paint canvas imo.

and the "enhanced for loop" uses an interator in the back end. but assigning a new value to a variable wouldn't change the array regardless.

eg:
Code

for (int i = 0; i < toggleButtons.length; i++){
ToggleButton toggleButton = toggleButtons[i];
toggleButton = new ToggleButton("A");
}



This post was edited by carteblanche on Sep 20 2016 07:37pm
Member
Posts: 14,631
Joined: Sep 14 2006
Gold: 575.56
Sep 20 2016 08:32pm
Quote (carteblanche @ Sep 20 2016 07:35pm)
i would advise against using buttons for the game of life. it's better to use some kind of paint canvas imo.

and the "enhanced for loop" uses an interator in the back end. but assigning a new value to a variable wouldn't change the array regardless.

eg:
Code
for (int i = 0; i < toggleButtons.length; i++){
ToggleButton toggleButton = toggleButtons[i];
toggleButton = new ToggleButton("A");
}


all i know is that the loop looks like this now
Code
for (int i = 0; i < toggleButtons.length; i++) {
toggleButtons[i] = new ToggleButton(""+i);
toggleButtons[i].setMinSize(50, 50);
toggleButtons[i].setSelected(false);
root.add(toggleButtons[i], x, y);
if (y < 4) {
y++;
} else if (y == 4) {
y = 0;
x++;
}
}

and if i try to turn it into a foreach loop it doesnt work, it builds just fine but hits a null reference when i try to access the buttons later

as for togglebuttons, ya they are ugly and limit me to a stationary grid, but i dont have to waste time extending new rect objects, adding listeners and painting blah blah blah im lazy right now

got my simple 3x3 + alternating and i think that's good enough for tonight

This post was edited by Ideophobe on Sep 20 2016 08:34pm
Member
Posts: 7,324
Joined: Dec 22 2002
Gold: 1,261.00
Sep 21 2016 01:48pm
Quote (Ideophobe @ Sep 20 2016 06:15pm)
ya that was my problem for some reason it didn't work right in a foreach loop but when i switched it over to a regular for it worked fine

as for the list rather than an array i plan to later, i'm trying to make a little conway game of life program, i figured i'ld make a nice easy 5x5 and then scale it later


It doesn't work in a foreach because 'toggleButton' is a copy of the reference, not the actual reference stored in the array itself. So when you new up another ToggleButton, the reference stored in the array still points to null, only the "toggleButton" copy is affected.
When you do something like
Code
toggleButtons[0] = new ToggleButton()
you are modifying the array member directly, not a copy of it.
Member
Posts: 14,631
Joined: Sep 14 2006
Gold: 575.56
Sep 21 2016 02:05pm
Good to know, thank you for the explanation I think it makes sense
Member
Posts: 7,324
Joined: Dec 22 2002
Gold: 1,261.00
Sep 21 2016 02:51pm
Quote (Ideophobe @ Sep 21 2016 01:05pm)
Good to know, thank you for the explanation I think it makes sense


In Java all object variables are references. Imagine an object is like a box, and the reference is a piece of rope tied to it. You can follow the rope to find the box that it's tied to, and then do stuff to the box. A null reference is a piece of rope that's not tied to anything. When you copy a variable, you are getting another piece of rope and tying it to the same box. So now two different ropes lead to the same physical object. But when you do something like 'toggleButton = new ToggleButton()' you are making a brand new box and tying your rope to it. This doesn't affect any other ropes, and it doesn't affect the box your rope used to be tied to (if any).

Your initially declared array 'toggleButtons' is just an array of ropes. In a foreach loop, you declared a new variable to iterate over the array, specifically 'toggleButton'. This is a new piece of rope that's gonna get tied to the same physical box as every rope in the array, one by one. Since the array ropes aren't tied to anything, this rope won't be tied to anything either. When you tie it to a new box by calling 'new ToggleButton()', it doesn't affect the rope that was in the array. That rope is still not tied to anything, and it's still null.

On the other hand, when you go over the array and say 'toggleButton[0] = new ToggleButton()' you are picking up the actual rope in the array and tying it to a box. So when you come back to it later, there will be a box on the other end and it won't be null.

Makes sense?
Member
Posts: 14,631
Joined: Sep 14 2006
Gold: 575.56
Sep 21 2016 07:44pm
the foreach loop in c# just aliases the reference for scope of the loop; i didnt realize that java's enhanced for loop was making a new reference variable

this is pretty much what i'm gathering from you right?
Member
Posts: 32,925
Joined: Jul 23 2006
Gold: 3,804.50
Sep 21 2016 08:03pm
Quote (Ideophobe @ Sep 21 2016 09:44pm)
the foreach loop in c# just aliases the reference for scope of the loop; i didnt realize that java's enhanced for loop was making a new reference variable


i think eclipse lets you turn it into a warning or error. change your compiler settings to avoid bugs like that.

it's been a few years, but i think c# throws an error and won't let you do that at all. i dont have visual studio anymore, but try running it:

Code
int[] numbers = { 1, 2, 3, 4 };
foreach (int number in numbers) {
Console.WriteLine(number);
number = 5;
}
foreach (int number in numbers) {
// since you assigned 5 previously, do you expect to see all 5?
Console.WriteLine(number);
}


forgive me if my syntax is off. but you get the idea

Quote
In Java all object variables are references.


i'm always iffy describing it like that since java is always pass by value. for objects, it's the "value of reference". in c you can pass a reference and another function can change what the reference points to, but java you cannot. you just get the value that the reference points to.

referring to them always as reference can be a little confusing since it depends on what you mean by reference (do you mean the pointer or the result from the pointer?). usually in non-formal environments we know what you mean, but i'd be careful about using that term to teach someone how it works.

This post was edited by carteblanche on Sep 21 2016 08:14pm
Go Back To Programming & Development Topic List
12Next
Add Reply New Topic New Poll