简体   繁体   中英

drawing multiple shapes using bufferimage java swing

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

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:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM