使用bufferimage java swing绘制多个形状

时间:2018-06-12 20:03:19

标签: java swing drawing

我试图通过使用bufferdimage在jpanel中绘制一些形状(线,圆,矩形)。所以我尝试了belove code.it工作缓冲形状,但问题是通过拖动鼠标它绘制形状像每一帧。

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

这里是代码`

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);

我在这里制作了一个bufferdimage对象

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

这些部分只是因为获得了鼠标事件起点的坐标

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) ) ) ; 
}

这个方法得到绘制的坐标和命令。(这只是为了使代码有点清楚我在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) {

    }
}

}`

实际上我不知道为什么它会像那样

1 个答案:

答案 0 :(得分:1)

所以,主要问题是BufferedImage的使用,基本上,你必须想象一个BufferedImage就像一个真实世界的画布,一旦你画了一些东西,它将保持不变(直到你画它或清除它)。

总的来说,更好的解决方案是遵循custom painting路线并将您想要绘制的信息存储在某种模型中。

这样,您可以更新模型,安排绘制过程,并在调用paintComponent时绘制模型的当前状态。

例如: