Domanda

I am creating a program that you can draw rectangles within a JPanel using MouseListener and MouseMotionListener however when I run the program I get a nullPointer exception that is caused by not inputing any parameters to draw the rectangle. The problem lies with how the program does not allow the user to draw the rectangle on the screen to give the parameters for the rectangle.

As of right now I am only trying to draw 1 rectangle but in the end the program will need to draw multiple rectangles so any help in that regard would be great.

Here is the code:

public class RectangleFrame extends JFrame implements ActionListener {


JPanel buttonPanel;
JButton saveImage;
JButton clearImage;
JCheckBox intersections;
JCheckBox union;
JPanel drawingArea;

public RectangleFrame()
{
    super();
    setTitle("Rectangles");
    setSize(600,600);
    setResizable(false);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    buttonPanel = new JPanel();
    buttonPanel.setBorder(BorderFactory.createLineBorder(Color.black));
    this.add(buttonPanel, BorderLayout.SOUTH);

    intersections = new JCheckBox("Draw Intersections");
    buttonPanel.add(intersections);

    union = new JCheckBox("Draw Union");
    buttonPanel.add(union);

    saveImage = new JButton("Save Image");
    saveImage.setMargin(new Insets(0,0,0,0));
    buttonPanel.add(saveImage);

    clearImage = new JButton("Clear Image");
    clearImage.setMargin(new Insets(0,0,0,0));
    buttonPanel.add(clearImage);

    drawingArea = new RectanglePanel();
    drawingArea.setBorder(BorderFactory.createLineBorder(Color.blue));
    this.add(drawingArea, BorderLayout.CENTER);
    drawingArea.setVisible(true);
    drawingArea.addMouseListener((MouseListener) drawingArea);
    drawingArea.addMouseMotionListener((MouseMotionListener) drawingArea);
}

    @Override
    public void actionPerformed(ActionEvent arg0) 
    {
        // TODO Auto-generated method stub

    }





}

class RectanglePanel extends JPanel implements MouseListener, MouseMotionListener {


Rectangle rectangle;
int x2, y2;

public RectanglePanel()
{
    super();
}   

@Override
public void mouseDragged(MouseEvent arg0) 
{

    // TODO Auto-generated method stub
}



@Override
public void mouseMoved(MouseEvent arg0) 
{
    // TODO Auto-generated method stub

}



@Override
public void mouseClicked(MouseEvent arg0)
{
    // TODO Auto-generated method stub

}



@Override
public void mouseEntered(MouseEvent arg0) 
{
    // TODO Auto-generated method stub

}



@Override
public void mouseExited(MouseEvent arg0)
{
    // TODO Auto-generated method stub

}



@Override
public void mousePressed(MouseEvent arg0) 
{
    rectangle.setX(arg0.getX());
    rectangle.setY(arg0.getY());

    repaint();

}



@Override
public void mouseReleased(MouseEvent arg0)
{
    x2 = arg0.getX();
    y2 = arg0.getY();

    rectangle.setWidth(Math.abs(rectangle.getX() - x2));
    rectangle.setHeight(Math.abs(rectangle.getY() - y2));   

    repaint();
}



@Override
public void paintComponent(Graphics g) 
{
    super.paintComponent(g);
    g.setColor(Color.BLUE);
    g.fillRect(rectangle.getX(), rectangle.getY(), rectangle.getWidth(), rectangle.getHeight());
}

}
È stato utile?

Soluzione

You need to create a new Rectangle object on mousePressed and then assign it to the rectangle variable. Then you can change its state in the mouseDragged method.

Or better, use Point objects that are set on mouse events:

i.e.

// variable declarations
Point initialPoint = null;
Rectangle rectangle = null;

@Override
public void mousePressed(MouseEvent mEvt) {
  initialPoint = mEvt.getPoint();
  rectangle = null;
  repaint();
}

mouseDragged(MouseEvent mEvt) {
  // use initialPoint, mEvt.getPoint(), 
  // Math.abs(...), Math.min(...), and Math.max(...)
  // to calculate x, y, w, and h
  rectangle = new Rectangle(x, y, w, h);
  repaint();
}

also in the paintComponent, only draw rectangle if it's not null.

@Override
public void paintComponent(Graphics g) {
  super.paintComponent(g);
  if (rectangle != null) {
    Graphics2D g2 = (Graphics2D) g;
    g2.setColor(Color.BLUE);
    g2.fill(rectangle);
  }
}

As for,

As of right now I am only trying to draw 1 rectangle but in the end the program will need to draw multiple rectangles so any help in that regard would be great.

This is easy. Create an ArrayList<Rectangle>, and on mouseReleased place the created Rectangle object into the List. In the paintComponent method, iterate through the list with a for loop, drawing each Rectangle that it contains.

Altri suggerimenti

Check out Custom Painting Approaches for two solutions that allow you to draw Rectangles:

  1. Draw Rectangles from an List
  2. Draw Rectangles on a BufferedImage
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top