-2

I faced a null pointer exception when I tried to retrieve an object from a normal array. First I initialize the array with 10 Line objects and then set the values of each object inside the array. But when I retrieve the values of any objects, I found it to be 0's. Why does that happen?

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class LineArrayLimt extends Applet
    implements MouseListener, MouseMotionListener {

    int width, height;
    int x, y, lineCounter;    // the coordinates of the upper-left corner of the box
    int mx, my;  // the most recently recorded mouse coordinates
    int new_mx;
    int new_my;
    Thread th;
    boolean isMouseDragging = false, isStored;
    Line[] lines = new Line[10];

    class Line {

        Line() {
        }

        Line(int x1, int y1, int x2, int y2) {
            this.x1 = x1;
            this.y1 = y1;
            this.x2 = x2;
            this.y2 = y2;
        }
        private int x1, y1, x2, y2;

        public void setX1(int x) {
            this.x1 = x;
        }

        public void setY1(int y) {
            this.y1 = y;
        }

        public void setX2(int x) {
            this.x2 = x;
        }

        public void setY2(int y) {
            this.y2 = y;
        }

        public int getX1() {
            return x1;
        }

        public int getY1() {
            return y1;
        }

        public int getX2() {
            return x2;
        }

        public int getY2() {
            return y2;
        }
    }

    public void init() {
        width = getSize().width;
        height = getSize().height;
        setBackground(Color.black);
        addMouseListener(this);
        addMouseMotionListener(this);
        for (int i = 0; i < lines.length; i++) {
            lines[i] = new Line();
        }

    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
        System.out.println("-----------------Mouse Pressed------------------------");
        mx = e.getX();
        my = e.getY();



    }

    public void mouseReleased(MouseEvent e) {
        System.out.println("-----------------Mouse Released------------------------");
        if (isMouseDragging) {
            if (lineCounter != lines.length - 1) {
                lines[lineCounter].setX1(mx);
                lines[lineCounter].setY1(my);
                lines[lineCounter].setX2(new_mx);
                lines[lineCounter].setY2(new_my);
                lineCounter++;
                if (lines[lineCounter] != null) {
                    System.out.println("-----------------First Object------------------------" + lines[lineCounter].getX1() + " " + lines[lineCounter].getY1() + " " + lines[lineCounter].getX2() + " " + lines[lineCounter].getY1());
                }


            }

        }
        isMouseDragging = false;

    }

    public void mouseMoved(MouseEvent e) {
    }

    public void mouseDragged(MouseEvent e) {
        System.out.println("-----------------Mouse Dragged------------------------");
        isMouseDragging = true;
        new_mx = e.getX();
        new_my = e.getY();
        if (new_mx <= 35) {
            new_mx = 35;
        }
        if (new_mx > width - 40) {
            new_mx = width - 40;
        }
        if (new_my > height - 40) {
            new_my = height - 40;
        }
        if (new_my < 35) {
            new_my = 35;
        }
        repaint();

    }

    public void paint(Graphics g) {
        System.out.println("-----------------Line No." + lineCounter + " is inside paint------------------------");
        g.setColor(Color.RED);
        if (isMouseDragging) {
            System.out.println("-----------------Paint while dragging------------------------");
            g.drawLine(mx, my, new_mx, new_my);
            if (lineCounter != lines.length - 1) {
                //if(lines[lineCounter]!=null){
                g.drawLine(lines[lineCounter].getX1(), lines[lineCounter].getY1(), lines[lineCounter].getX2(), lines[lineCounter].getX2());
                System.out.println("*************" + lines[lineCounter].getX1() + lines[lineCounter].getY1() + lines[lineCounter].getX2() + lines[lineCounter].getX2());
                //}
            }
        }
    }
}
das-g
  • 9,718
  • 4
  • 38
  • 80
Eslam Hamdy
  • 7,126
  • 27
  • 105
  • 165
  • try to use trycatch function at the marked line – goravine Dec 28 '12 at 09:14
  • 4
    @goravine: Absolutely not. You should almost *never* catch NullPointerException deliberately. – Jon Skeet Dec 28 '12 at 09:14
  • 2
    It's very hard to read your code because it's so badly formatted. Please put more effort into writing your question in a way which is as easy to read as possible. (I'm sure you could also cut the example down significantly.) – Jon Skeet Dec 28 '12 at 09:15
  • Here is some insight for you to navigate over NPE [article1](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception), [article2](http://javaeesupportpatterns.blogspot.sg/2012/01/javalangnullpointerexception-how-to.html?m=1) – bonCodigo Dec 28 '12 at 09:21
  • See http://stackoverflow.com/questions/1922677/nullpointerexception-when-creating-an-array-of-object for a "minimal test case" of similar NPE behavior (I would use a List as suggested by Jon, however.) –  Dec 28 '12 at 09:22

3 Answers3

2

The problem is that in init you're initializing lines to an array of 10 null references:

lines = new Line[10];

Then in paint you're using that null reference:

if (lineCounter != lines.length - 1) {
    g.drawLine(lines[lineCounter].getX1(),
               lines[lineCounter].getY1(),
               lines[lineCounter].getX2(),
               lines[lineCounter].getY2());
}

lines.length will always be 10 - it isn't the number of non-null references in the array. It's not the number of lines you've added, or anything like that. (It's not clear what your if condition is trying to achieve, to be honest.)

You'd be better off using a List<Line> instead. Then in paint you could just use:

for (Line line : lines) {
    ...
}

... and in mouseReleased you'd just use:

lines.add(new Line(...));

Also note that there's no reason for Line to be an inner class. Either make it a static nested class, or a top-level (non-nested) class.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • or explicitly initialize it in a loop. [lines[i] = new Line();] (i varies from 0 to 9) – TJ- Dec 28 '12 at 09:22
  • @TJ-: I can't see how that would work usefully, as before the user has drawn any lines, there just aren't any which should be drawn... – Jon Skeet Dec 28 '12 at 09:23
  • oh, my bad. I didn't read the question, I was just referring to making use of lines = new Line[10]; – TJ- Dec 28 '12 at 09:25
  • ok, but what's the problem in initializing the array with 10 elements of type Line in init method, in mouseReleased i added elements to the array so why it still holds NULLS? i edit the code, i think that the problem is that paint is accessing a null reference only in the first time the applet started, so i add an extra condition to paint in order to access the array elements – Eslam Hamdy Dec 28 '12 at 09:38
  • @Eslam: In `init()` you're **not** initializing the array with 10 `Line` references. You're creating an array which initially holds 10 `null` references. You *could* create 10 `Line` objects, but you don't really want to draw any lines, so it wouldn't make sense to do so. Fundamentally I think you need to revisit array creation behaviour - but I'd also strongly suggest using a list instead anyway... – Jon Skeet Dec 28 '12 at 10:51
  • @Jon Skeet so how to initialize the array with 10 line objects instead of these null references? – Eslam Hamdy Dec 28 '12 at 11:20
  • @Eslam: You'd call `new Line(...)` and assign a value to each element of the array. But as I keep saying, you shouldn't do that. I'm not sure why you're not taking my advice to use a `List` instead, and only add lines when you need to... – Jon Skeet Dec 28 '12 at 12:33
  • ok, i already do that but all the objects inside the array still contains 0's, i tried it before with array list and i want to do it alos with the normal array to notice the difference, please check above code i will update it in a minute – Eslam Hamdy Dec 28 '12 at 12:37
  • @Eslam: Do *not* just change the code in your question, as otherwise all the existing answer won't make sense. But yes, if you create new `Line` objects with 0 co-ordinates, of course they'll contain 0 co-ordinates. What did you expect to happen? It sounds like you need to take a step back and work out what you actually want the array to contain. – Jon Skeet Dec 28 '12 at 12:39
0

Have you checked if the line is indeed added to the array in mouseReleased?

András Kerekes
  • 1,001
  • 7
  • 13
  • What I meant is that if for some reason the conditions are always false in the method, than the elements of the array will stay null. Just a very basic sanity check. – András Kerekes Dec 29 '12 at 14:22
0

The problem is you are filling the array only in mouseReleased() function and paint method doesn't wait for mouse to release. So when the mouse is not released, paint() method tries to draw line.

you just uncomment your check if(lines[lineCounter]!=null) and try, it should work.

If you want to achieve anything else, let us know

vishal_aim
  • 7,636
  • 1
  • 20
  • 23