Getting round a Nullpointer Exception
Let me start with an overview. I have a Gui which has three scrollbars, a panel and a button. When the button is pressed the listener fires off the values of the respective positions of the three scrollbars. In the panel is an image.
There is a class which reads a series of integers (between 0-255) from a text file into int arrays and creates a simple GIF image by setting the rgb value equal to this. This is slightly complicated by the fact the image is created by adding the value at position of three int arrays and then averaged to effectively merge three images together. The conceptual idea is that each int array is a seperate (desirable) characteristic for locating say a factory. The final image is in fact of a map with the lighter areas proving better sites.
To complicate things further the scrollbars are designed in fact to 'weight' each of the three int arrays all of which have a corresponding scrollbar, hence the value of the scrollbars needed on the press of a button.
The problem I have is that on returning the values of the scrollbars and using them in the calculations I get a null pointer exception. This is understandable as on initializing the Gui the value returned by the button listener class used in the calculation to create the image doesn't exist as no button has been pushed.
Are there ways around this by say creating a statement where the value of a variable is equal to 50, but when the button is pressed it changes to the value of the scrollbar? This would conviently allow the code to run. Alternatively have I gone down the wrong route with the structure of the code by using the button listener to just get these values, which are then read by a different class rather than perhaps creating the image in the button listener although to me that doesn't seem as effective as having one class to create an image etc.?
Message was edited by:
geo3gjs
[1945 byte] By [
geo3gjsa] at [2007-11-26 15:39:32]

I'm not sure I understand fully, but something like this might help:
if (referenceInQuestion == null) {
someOtherValue = 50;
}
else {
someOtherValue = referenceInQuestion.aMethod();
}
> The problem I have is that on returning the values of the scrollbars and
> using them in the calculations I get a null pointer exception.
This means you are using a reference with a null value in a context that
requires it to reference an actual object - eg you are dereferencing it (using
dot to invoke a method or access a variable), or passing it as an argument to
some method that requires a non-null parameter.
The error method will state which variable holds this null reference and on
which line you are using it in a way that gives rise to this error.
Go to that line of code, examine that variable and ask yourself: what value
should that variable have and where should it have been assigned?
If you believe that it should have a sensible (non-null) value then you need to
debug your program your program to see why the assignment you thought
would happen, did not in fact happen.
If you agree with the compiler that the variable in question will be null then
you face a logic error: you are using a null value in an invalid way. So change
your code to ensure the variable has a non null value, or don't use it in the
way you do until it does have a non-null value.
Sorry there's no specific "solution" here - but I can't really see a specific
question. Mostly I wanted to suggest that you should change your focus
from "I get a null pointer exception" to "I caused a null pointer exception".
If you're stuck, post some code. A small (30 lines or so) example that shows
the problem. Post the actual error message and a statement of the expected
or desired behaviour. (I do realise that constructing such examples is not
easy - but the effort and time invested in isolating the problem from the
"noise" of all the detail of the rest of the program is often well rewarded.
Small examples of a problem often suggest their own solution.)
Using the above example:
if (referenceInQuestion == null) {
someOtherValue = 50;
}
else {
someOtherValue = referenceInQuestion.aMethod();
}
referenceInQuestion is a returned int value from the button listener class, which returns the value of the position of a scrollbar when the button is pressed.
Unfortunately I fear it may be a logic error (as pbrockway2 suggests) as the value that I'm trying to use in the calculation of the int array does not exist prior to clicking the button so it will fail to run. I was hoping something like the code suggested would get round the problem, but on testing I get an incomparable types: int and <nulltype> on the line below.
if { b.getG() == null) {
Ok, it looks like I didn't understand the problem.
> Unfortunately I fear it may be a logic error (as
> pbrockway2 suggests) as the value that I'm trying to
> use in the calculation of the int array does not
> exist prior to clicking the button so it will fail to
> run. I was hoping something like the code suggested
> would get round the problem, but on testing I get an
> incomparable types: int and <nulltype> on the line
> below.
>
> if { b.getG() == null) {
If b.getG() returns an int, then it can't be null. Only references can be null, primitives (like ints) always have a value. You can check if the int has a value like b.getG() == 50 or something, but not null.
pbrockway gave excellent instructions on how to track down and fix the problem, follow those and come back if you can find it.
I'm trying for the first time to create a small example of the general problem I'm still having hopefully it encapsulates it in a reconisible form:
Value class is where the int array to store and do calculations on an image would have been. In this case it has been simplified to print the value of the scroll bar to screen.
class Value{
Button button = null;
double a = 0.01*button.getA(); //Null pointer error on this line
System.out.println(a)
}
public class Button implements ActionListener {
private int a;
//Where main is the name of the class containing the scrollbar in question
Main main = null;
public Button (Main mainIn) {
main = mainIn;
}
public void actionPerformed (ActionEvent e) {
int a = main.scrollBar.getValue();
}
public int getA(){
return a;
}
}
Perhaps it is the way I am creating objects of classes that is the problem? If the example makes no sense then please let me know and I'll try and improve it.
Perhaps I would be better saying what I want to achieve. I want the Value class, which would have already created an image to use int a of the Button Class in order to alter the image dependent on the value of int a.
What causes the image to need altering?
If it is a button click then the button needs to have a reference to the Value
object. The action listener should call the Value object's method passing it
the int a.
If it is something else that calls the Value object's method, then the Value
object will have to have a reference to the button. In this case you can't have:Button button = null;
double a = 0.01 * button.getA();
(For obvious reasons.) Instead the Value object has to be given a reference
eg when it is constructed. Perhaps something like this:class Value {
private Button but;
public Value(Button b) {
but = b;
}
/**
* Changes the image based on the value remembered
* by the button.
* Called by whatever knows the image should be changed.
*/
public changeImage() {
double a = 0.01 * but.getA();
System.out.println(a);
}
}
Perhaps this is something to do with the problem. They're a simplified version of snippets that are causing the trouble:
class Main {
public Scrollbar a;
a = new Scrollbar (Scrollbar.HORIZONTAL, 0, 1, 1, 10);
a.setSize(100,50);
a.setValue(5);
public int getB {
int b = a.getValue();
return b;
}
}
class Other {
Main main = new Main();
int c = main.getB(); // I get a null pointer exception here in my code.
}
You really need to post code that compiles.If main.getB() produces a null pointer exception, that's because main is nullor a is null at that time. But it's impossible to see when variables are beinginitialised without code that compiles and has a main method.
I'm afraid I can't replicate the problem so I'm going to post some of the code, which should compile, but doesn't have a main. The problem is still getting the values from the Button Listener to the Map class. I've tried to pass values over, but haven't been successful. Can anyone spot what I've done wrong or whether its possible?
import java.awt.*;
import java.awt.event.*;
public class ButList implements ActionListener {
//Site is the main class which sets up the Gui.
//The geologySlider etc. are scroll bars.
Site s = null;
public ButList(Site siteIn) {
s = siteIn;
}
public void actionPerformed (ActionEvent e) {
Map map = new Map();
int geoWeight = map.getGW(s.geologySlider.getValue());
int mwayWeight = map.getMW(s.mwaySlider.getValue());
int popWeight = map.getPW(s.popSlider.getValue());
s.paint();
}
}
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import java.io.*;
public class Map {
int width = 335;
int height = 530;
int geoW;
int mwaW;
int popW;
public int getGW(int geoW){
return geoW;
}
public int getMW(int mwaW){
return mwaW;
}
public int getPW(int popW){
return popW;
}
public int [] getMap() {
//This is where I need to get the values from ButList. Have tried a whole
//host of combinations, but failed miserably.
double gW = 0.01*getGW(geoW);
double mW = 0.01*mwaW;
double pW = 0.01*popW;
// This uses the code from the ReaderThing.java file.
File geology = null;
ReaderThing r = null; // Code to read integer arrays.
geology = new File("geology.txt");
// Makes an object of the class ReaderThing
r = new ReaderThing(geology, true);
// Calls the method to assign the value of the int to the rgb value.
int[][] pixelsGeo = r.getTwoDintArray();
File mway = null;
mway = new File("mway.txt");
// Makes an object of the class ReaderThing
r = new ReaderThing(mway, true);
// Calls the method to assign the value of the int to the rgb value.
int[][] pixelsMway = r.getTwoDintArray();
File pop = null;
pop = new File("pop.txt");
// Makes an object of the class ReaderThing
r = new ReaderThing(pop, true);
// Calls the method to assign the value of the int to the rgb value.
int[][] pixelsPop = r.getTwoDintArray();
//Merge the images by looping through an array that adds the respective
//numbers of each position and returns an averaged number, which
//represents the new rbg colour.
int[][] pixels = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
pixels[i][j] = (int)(pixelsGeo[i][j]*gW + pixelsMway[i][j]*mW + pixelsPop[i][j]*pW)/3;
}
}
int [] maps = new int[width * height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int temp = pixels[i][j];
Color tempColor = new Color(temp,temp,temp);
maps [(j*width) + i] = tempColor.getRGB();
}
}
return maps;
}
}
How do I pass the values from the listener to the map class. Is there a simple example out there? I'm not having much luck with google.
Ok forget the title of the thread.
What I'm now looking to achieve is on clicking the button the value of the scrollbars is got (I've tested with a System.out.println() and it does indeed get the values when clicked). This value is then used by another class (the Map class which uses the value to create and image). How do I 'get' the value from the action listener into the Map class?