0

I am trying to draw some shapes(line, circle, rectangle) in a jpanel by using bufferdimage. so i tried the belove code.it works on buffering shapes but the problem is by dragging mouse it draws the shape like every single frame.

https://i.stack.imgur.com/s7usN.jpg

here is the code `

public class PanelClass extends JPanel {
BufferedImage img;
int x1,y1,x2,y2,StarterX,StarterY, h,w;
static int flag;
Graphics2D g2d ;

public PanelClass() {   

    MouseHandler handler = new MouseHandler();
    this.addMouseListener(handler);
    this.addMouseMotionListener(handler);

i made an object of bufferdimage here

    img = new BufferedImage(600, 600, BufferedImage.TYPE_INT_RGB);
    g2d = (Graphics2D) img.getGraphics();
}

these parts are just because of getting the Coordinates of starting point of mouse events

public void starter(int oldX,int oldY){
    x1 = oldX;
    y1 = oldY;


}


public void finisher(int currentX,int currentY){
    x2 = currentX;
    y2 = currentY;
    if(x1 > x2){
        StarterX = x2;

    }
    else if(x2 > x1){
        StarterX = x1;

    }

    if(y1 > y2){
        StarterY = y2;

    }
    else if(y2 > y1){
        StarterY = y1;
    }
}    

   public int Diameter(int oldX,int oldY,int currentX,int currentY){


    return  (int) Math.sqrt (  (Math.pow(currentX - oldX, 2)) + (Math.pow(currentY - oldY, 2) ) ) ; 
}

this method gets the coordinates and orders to paint.(this is just for making code a bit clear i use this method on paintComponent() )

public void painter(){


    if(flag ==1){

      g2d.setColor(Color.ORANGE);
      g2d.setStroke(new BasicStroke(3.0f));
      g2d.drawOval(StarterX ,StarterY,Diameter(x1, y1, x2, y2),Diameter(x1, y1, x2, y2));
      g2d.setBackground(Color.YELLOW);

    }
    else if(flag == 2){
        //fill oval;
        g2d.setColor(Color.ORANGE);
        g2d.setBackground(Color.YELLOW);    
        g2d.fillOval(StarterX ,StarterY,Diameter(x1, y1, x2, y2),Diameter(x1, y1, x2, y2) );
    }
    else if (flag == 3){


         g2d.setColor(Color.ORANGE);
         g2d.setStroke(new BasicStroke(3.0f));
         g2d.drawRect(StarterX, StarterY,Math.abs(x2-x1) ,Math.abs(y2-y1));
         g2d.setBackground(Color.YELLOW);

    }
    else if (flag == 4){


         g2d.setColor(Color.ORANGE);
         g2d.fillRect(StarterX, StarterY,Math.abs(x2-x1) ,Math.abs(y2-y1));
         g2d.setBackground(Color.YELLOW);

    }
    else if (flag == 5){


         g2d.setColor(Color.ORANGE);
         g2d.setStroke(new BasicStroke(5.0f)); 
         g2d.drawLine(x1, y1,x2,y2);
         g2d.setBackground(Color.YELLOW);


    }


}


public void flagSetter(int flag){

    this.flag = flag;
}



at this method i used g.drawImage()

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g); 
    painter();
    g.drawImage(img, 0,0, null);

}











class MouseHandler implements MouseListener,MouseMotionListener{







    @Override
    public void mousePressed(MouseEvent e) {
         starter(e.getX(),e.getY());


    }

    @Override
    public void mouseReleased(MouseEvent e) {

        finisher(e.getX(),e.getY());
        g2d.drawImage(img,0,0 ,null);
        repaint();


        if(flag == 1){




        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {

    } 

    @Override
    public void mouseExited(MouseEvent e) {


    }

    @Override
    public void mouseDragged(MouseEvent e) {

        finisher(e.getX(),e.getY() );
       // System.out.printf("%d   %d      ",currentX,currentY);
        repaint();


    }

    @Override
    public void mouseMoved(MouseEvent e) {

    }

    @Override
    public void mouseClicked(MouseEvent e) {

    }
}

}`

actully i have no idea why it acts like that

camickr
  • 321,443
  • 19
  • 166
  • 288
  • 2
    You should only be drawing the shape to the BufferedImage when the mouse is released. The painting done when you drag the mouse should be done using the Graphics object of the paintComponent() method (so this painting is cleared every time the paintComponent() method is called). See the `DrawOnImage` example from [Custom Painting Approaches](https://tips4java.wordpress.com/2009/05/08/custom-painting-approaches/) for a working example. – camickr Jun 12 '18 at 20:57

1 Answers1

1

So, the primary issue is the use of the BufferedImage, basically, you have to think of a BufferedImage like a real world canvas, once you paint something to it, it will remain (until you paint over it or clear it).

Overall, a better solution would be to follow a custom painting route and store the information you want painted in some kind of model.

This way, you update to the model, schedule a paint pass and when paintComponent is called, you paint the current state of the model.

For example:

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366