thefreebird777
thefreebird777

Reputation: 99

I don't know why my object is becoming null. Also, why does repaint() not always call paintComponent()?

I'm trying to let a user draw a rectangle with their mouse.

I'm having two problems which I think may be related. Firstly, the third class I posted here, Colors.java, needs to use the same rectangle object from the mouse listener, which is the second class I provided (Mouse.java).

I tried to use getters and setters with this, when I went through the program in debug mode it had the correct rectangle object in the color() method, but once it went to paintComponent() I now have a null rectangle object. I don't know why this is.

Another problem I've been having is that the repaint() method does not always call the paintComponent() method. I think this could be because of the rectangle object being null but I'm not sure.

I tried to shorten up the code and replaced some code with comments. I also didn't think including the rectangle class was necessary since most of the class is filled with other functions totally unrelated to the this problem.

Any help to lead me in the right direction would be appreciated, I'm pretty stuck right now. Thanks!

public class JavaSwing extends JFrame implements ItemListener {

//Checkbox objects here

Colors colors = new Colors();

public void createGui() {
    intersection = new JCheckBox("Draw Intersections");
    intersection.setMnemonic(KeyEvent.VK_C);
    intersection.setSelected(false);
    //checkbox objects assigned like above

    //checkbox listeners

    JFrame frame = new JFrame("Rectangles");
    frame.setSize(600, 600);
    frame.setVisible(true);

    Mouse mouse = new Mouse();


    colors.setLayout(new BoxLayout(colors, BoxLayout.PAGE_AXIS));

    colors.addMouseListener(mouse);
    colors.addMouseMotionListener(mouse);
    colors.add(Box.createRigidArea(new Dimension(0, 5)));
    colors.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));


    JButton button = new JButton("Clear Image");

    JPanel panel = new JPanel();

    panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
    panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
    panel.add(Box.createHorizontalGlue());
    panel.add(intersection);
    panel.add(Box.createRigidArea(new Dimension(10, 0)));
    panel.add(union);
    panel.add(Box.createRigidArea(new Dimension(10, 0)));
    panel.add(commonArea);
    panel.add(Box.createRigidArea(new Dimension(10, 0)));
    panel.add(button);


    frame.add(colors, BorderLayout.CENTER);
    frame.add(panel, BorderLayout.PAGE_END);

}

@Override
public void itemStateChanged(ItemEvent e) {
  //for checkboxes
}


public static void main(String args[]) {
    JavaSwing javaSwing = new JavaSwing();
    javaSwing.createGui();

}
}

Second Class:

public class Mouse extends MouseInputAdapter implements MouseListener{
Rectangle rectangleOne = new Rectangle(0, 0, 0, 0);

Colors colors = new Colors();

public void mousePressed(MouseEvent e) {
    rectangleOne.setX(e.getX());
    rectangleOne.setY(e.getY());
    rectangleToDraw = new Rectangle(rectangleOne.getX(), rectangleOne.getY(),
            rectangleOne.getWidth(), rectangleOne.getHeight());
    colors.setRectangle(rectangleToDraw);
    colors.color();
}

public void mouseReleased(MouseEvent e) {
    int x2 = e.getX();
    int y2 = e.getY();
    rectangleOne.setWidth(x2 - rectangleOne.getX());
    rectangleOne.setHeight(y2 - rectangleOne.getY());
    rectangleToDraw = new Rectangle(rectangleOne.getX(), rectangleOne.getY(),
            rectangleOne.getWidth(), rectangleOne.getHeight());
    colors.setRectangle(rectangleToDraw);
    colors.color();
}

Third Class:

public class Colors extends JPanel {
Rectangle rectangle;

public void setRectangle(Rectangle rectangle)
{
    this.rectangle = rectangle;
}

public Rectangle getRectangle() {
    return rectangle;
}

public void color() {
    repaint();
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);

    g.setColor(Color.GREEN);
   if (getRectangle() != null) {
       g.fillRect(getRectangle().getX(), getRectangle().getY(), getRectangle().getWidth(), getRectangle().getHeight());
  }
}
}

Upvotes: 1

Views: 47

Answers (1)

resueman
resueman

Reputation: 10613

The reason rectangle is null when you reach paintComponent is because the colors in Mouse is not the same as the colors in JavaSwing. In both classes you do Colors colors = new Colors(). That means you have two separate, unrelated, instances of the class. That's also the reason you aren't seeing a repaint happen when you call repaint() - you're calling it on a component that's not part of the actual component hierarchy being displayed.

If you change things so that you use the same Colors instance in both cases, it will work correctly. So change your Mouse code to this:

public class Mouse extends MouseInputAdapter implements MouseListener{
    Rectangle rectangleOne = new Rectangle(0, 0, 0, 0);
    Colors colors;

    public Mouse(Colors colors){
        this.colors = colors;
    }
    /* The rest of your methods here */
}

And then create your Mouse instance like this:

Mouse mouse = new Mouse(colors);

Also, although I don't think this is what you're talking about, I think I should mention that repaint() does not always result in paintComponent being called, even when you do it on the correct object. What it does is make a request that the component be repainted when the Event Dispatch Thread is next able to. Usually it will cause paintComponent to be called, but not always (for example if the component isn't visible, or if you call it multiple times before it can be repainted, which will result in it only being painted once).

Upvotes: 3

Related Questions