通过 Mousedragged 绘制时的多个形状

Multiple shapes when drawing via Mousedragged

我需要一些有关使用 java 图形绘制形状的帮助...,我正在尝试创建绘画应用程序,当我使用鼠标拖动时,它会绘制多个形状(从小到大);像这样: http://i.stack.imgur.com/0oQmv.png

谁能解决这个问题? 感谢大家..

This is DrawingArea class :

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.RenderingHints;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseMotionListener;
    import java.awt.image.RenderedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JColorChooser;
    import javax.swing.JComponent;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JSlider;
    import say.swing.JFontChooser;
    public class DrawingArea extends JComponent implements MouseListener,MouseMotionListener {

    /**
     * 
     */
    Shapers shape;//IMPORTED FROM SHAPERS CLASS TO USE THE ENUMS.
    private Font myFont; 
    private Image image;
    private Graphics2D g2;
    private static final long serialVersionUID = 1L;
    private Color currentColor, initialColor = Color.BLACK;
    private int oldX, oldY, lastX, lastY, draggedX, draggedY, width, height, x, y, thickness = 3;

    public DrawingArea() { //ADDING LISTENERS FOR JCOMPONENTS.
        setDoubleBuffered(false);
        addMouseMotionListener(this);
        addMouseListener(this);
    }
    //PENCIL OR ERASER STROKE SETTED BY JSLIDER
    public void setStroke(JSlider slider) {thickness = slider.getValue();}
    //FOR CHOOSING COLOR FROM COLOR CHOOSER
    public void ChooseColor() { currentColor = JColorChooser.showDialog(this, "Choose Your Color", initialColor);}
    //CHOOSING FONT FROM FONTCHOOSER (EXTERNAL LIBRARY).
    public void ChooseFont() {

        JFontChooser chooseFont = new JFontChooser();
        int results = chooseFont.showDialog(this);
        if (results == JFontChooser.OK_OPTION) {
            myFont = chooseFont.getSelectedFont();
        }
    }
    @Override//GETTING FIRST (STARTING) COORDINATE WHEN THE MOUSE PRESSED
    public void mousePressed(MouseEvent e) {
        oldX = e.getX();
        oldY = e.getY();
        repaint();
    if(shape == Shapers.TEXT){ //DRAWING TEXT (FONT,SIZE AND COLOR ENABLED).
            String str = JOptionPane.showInputDialog("Write Your Text Here : ");
            g2.setFont(myFont);
            g2.setColor(currentColor);
            g2.drawString(str, oldX, oldY);
        }
    }

    @Override//GETTING RELEASED COORDINATE TO DRAW LINE.
    public void mouseReleased(MouseEvent e) {
        lastX = e.getX();
        lastY = e.getY();
    }
    //GETTING COORDINATE TO DRAW FILLEDRECT,FILLEDOVAL,OVAL,RECT.
    public void mouseDragged(MouseEvent e) {
        draggedX = e.getX();
        draggedY = e.getY();
        repaint();
        width = Math.abs(oldX - draggedX);
        height = Math.abs(oldY - draggedY);
        x = Math.min(draggedX, oldX);
        y = Math.min(draggedY, oldY);
    }

    public void mouseMoved(MouseEvent e) {}

    public void mouseClicked(MouseEvent e) {}

    public void mouseEntered(MouseEvent e) {}

    public void mouseExited(MouseEvent e) {}
    //CLEAR THE ALL SHAPES DRAWED ON DRAW AREA.
    public void clear() {
        g2.setColor(Color.WHITE);
        g2.fillRect(0, 0, (int) this.getWidth() + 55, (int) this.getHeight() + 55);
        super.repaint();
    }
    //FIRST DRAWING WHITE IMAGE TO ABLE SAVE DRAWED SHAPES ON DRAWING AREA.
    //AFTER THAT DRAWING WHEN FIRE BUTTONS ACTIONLISTENER (FROM CODER_PAINT CLASS) SELECTING SHAPES WITH IF & ELSE.
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (image == null) {
            image = createImage((int) this.getWidth(), (int) this.getHeight());
            g2 = (Graphics2D) image.getGraphics();
            g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            clear();
        }
        g.drawImage(image, 0, 0, this);
        g2.setColor(initialColor);

        if(shape == Shapers.PENCIL){
            g2.setColor(currentColor);
            g2.fillOval(draggedX, draggedY, thickness, thickness);
            repaint();
        }
        else if(shape == Shapers.OVAL){
            g2.setColor(currentColor);
            g2.drawOval(oldX, oldY, draggedX, draggedX);
            repaint();
        }
        else if(shape == Shapers.FILLEDOVAL){
            g2.setColor(currentColor);
            g2.fillOval(oldX, oldY, draggedX, draggedY);
            repaint();
        }
        else if(shape == Shapers.RECT){
            g2.setColor(currentColor);
            g2.drawRect(x, y, width, height);
            repaint();
        }
        else if(shape == Shapers.FILLEDRECT){
            g2.setColor(currentColor);
            g2.fillRect(x, y, width, height);
            repaint();
        }
        else if(shape == Shapers.LINE){
            g2.setColor(currentColor);
            g2.drawLine(oldX, oldY, lastX, lastY);
            oldX = lastX;//SETTING FIRST COORDINATE TO LAST COORDINATE BECAUSE ABLE TO CONTINUE DRAWING LINE.
            oldY = lastY;
            repaint();
        }
        else if(shape == Shapers.ERASER){
            g2.setColor(Color.WHITE);
            g2.fillRect(draggedX, draggedY, thickness, thickness);
            repaint();
        }
        else{

        }
    }
    //AFTER DRAWING IF THE USER WANTED SAVE THE DRAWED WE CAN USE THIS METHOD.
    public void SaveImage() {
        try {
            String fileName = JOptionPane.showInputDialog(null, "Please enter file name...");
            String fileType = JOptionPane.showInputDialog(null, "Please enter file type...");

            if (fileName != null && fileType != null && fileName.length() > 0 && fileType.length() > 0) {

                ImageIO.write((RenderedImage) image, fileType.toUpperCase(),//WRITING NEW FILE DATAS GETTED FROM DRAW AREA IMAGE.
                        new File("/Users/MacbookPro/Desktop/" + fileName + "." + fileType.toUpperCase()));
                JOptionPane.showMessageDialog(null, "Your image saved.");
            } else {
                JOptionPane.showMessageDialog(null, "Please try re saving and dont't forget filling the blanks!");
                return;
            }
        } catch (IOException e2) {System.out.println("CanNot save the image!");}
    }
    //CHANGING CHOOSED COLOR PANEL TO USER CAN KNOW WHICH COLOR CHOOSED NOW
    public void changeColor(JPanel panel) {panel.setBackground(currentColor);}
    //THIS METHOD USING TO IMPORT IMAGE FROM COMPUTER.
    public void PrintImage(Image img) {
        g2.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
        super.paint(g2);
        repaint();
    }
    //CALLING UPDATE METHOD FOR WHAT I'M ALSO DON'T KNOW :)
    public void update(Graphics g) {super.repaint();}

}

经过一番折腾终于解决了:) 并且有一些示例代码:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    if (image != null) {
        g2D = (Graphics2D) image.getGraphics();
        g2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.drawImage(image, 0, 0, AREA_WIDTH, AREA_HEIGHT, null);
    }

    //SETTING STROKE FOR SHAPES
    BasicStroke basicStroke = new BasicStroke(thickness);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setStroke(basicStroke);
    g2d.setPaint(currentColor);

    if(g2d != null) {
// ENUMROPE = IS ENUM CLASS USED LIKE BRIDGE BETWEEN MAIN CLASS AND DRAWING AREA
        if (figures == EnumRope.RECT && rectangle != null) {

                g2d.draw(rectangle);

        }else if(figures == EnumRope.FILLEDRECT && rectangle != null){

                g2d.fill(rectangle);

        }else if (figures == EnumRope.OVAL && ellipse2d != null) {

                g2d.draw(ellipse2d);

        }else if (figures == EnumRope.FILLEDOVAL && ellipse2d != null){

                g2d.fill(ellipse2d);

        }else if (figures == EnumRope.LINE && line2d != null) {

                g2d.draw(line2d);

        }else if(figures == EnumRope.PENCIL && ErasRect != null){

                g2d.fill(ErasRect);

        }else if(figures == EnumRope.ERASER && ErasRect != null){

                g2d.fill(ErasRect);

        }

    }

}


public void clear()
{   //INVOKING CLEARAREA METHOD
    clearArea();
    repaint();
}

public void clearArea() {
   //THERE CREATED NEW IMAGE TO CLEAN DRAW AREA & ERASE ALL DRAWN SHAPES
    image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB);
}
public void addRectangle(Rectangle rectangle, Color color, int tickness)
{
    //  DRAW THE RECTANGLE ONTO THE BUFFEREDIMAGE
    BasicStroke basicStroke = new BasicStroke(tickness);
    Graphics2D g2d = (Graphics2D)image.getGraphics();
    g2d.setStroke(basicStroke);
    g2d.setColor( currentColor );
    if(figures==EnumRope.FILLEDRECT){
        g2d.fill( rectangle );
    }else {
        g2d.draw( rectangle );
    }
        repaint();
}
public void addEllipse(Ellipse2D.Float ellipse2D, Color color, int tickness)
{
    //  DRAW THE OVAL(circle) ONTO THE BUFFEREDIMAGE
    BasicStroke basicStroke = new BasicStroke(tickness);
    Graphics2D g2d = (Graphics2D)image.getGraphics();
    g2d.setStroke(basicStroke);
    g2d.setColor( currentColor );
    if(figures == EnumRope.FILLEDOVAL) {
        g2d.fill( ellipse2D );
    }else {
        g2d.draw( ellipse2D );
    }
        repaint();
}
public void addLine(Line2D.Float line2D, Color color, int tickness)
{
    //  DRAW THE LINE ONTO THE BUFFEREDIMAGE
    BasicStroke basicStroke = new BasicStroke(tickness);
    Graphics2D g2d = (Graphics2D)image.getGraphics();
    g2d.setStroke(basicStroke);
    g2d.setColor( currentColor );
    g2d.draw( line2D );
    repaint();
}
public void addEraser(Rectangle2D.Float erasRect, Color color, int tickness)
{
   //  DRAW THE ERASER(WHITE,CONSTANT RECTANGLE) ONTO THE BUFFEREDIMAGE
    BasicStroke basicStroke = new BasicStroke(tickness);
    Graphics2D g2d = (Graphics2D)image.getGraphics();
    g2d.setStroke(basicStroke);
    g2d.setColor(Color.WHITE);
    g2d.fill(erasRect);
    repaint();
}
public void addPencil(Rectangle2D.Float erasRect, Color color, int tickness)
{
    // DRAW THE PENCIL(COLORED,CONSTANT RECTANGLE) ONTO THE BUFFEREDIMAGE
    BasicStroke basicStroke = new BasicStroke(tickness);
    Graphics2D g2d = (Graphics2D)image.getGraphics();
    g2d.setStroke(basicStroke);
    g2d.setColor(currentColor);
    g2d.fill(erasRect);
    repaint();
}
//NEW INNER CLASS FOR MOUSEADAPTER
class MyMouseListener extends MouseInputAdapter{

private Point startpoint;

@Override
public void mousePressed(MouseEvent e) 
{
    startpoint = e.getPoint();
    rectangle = new Rectangle();
    oldX = e.getX();
    oldY = e.getY();
    repaint();

if(figures == EnumRope.TEXT){

        text = JOptionPane.showInputDialog("Write Your Text Here : ");
        g2D.setFont(myFont);
        g2D.setColor(currentColor);
        g2D.drawString(text, oldX, oldY);
        repaint();

    }
}

@Override
public void mouseDragged(MouseEvent e) {
    currentX = e.getX();
    currentY = e.getY();
    int x = Math.min(startpoint.x, e.getX());
    int y = Math.min(startpoint.y, e.getY());
    int width = Math.abs(startpoint.x - e.getX());
    int height = Math.abs(startpoint.y - e.getY());

    rectangle.setBounds(x, y, width, height);
    repaint();
    ellipse2d = new Ellipse2D.Float(x, y, width, height);
    repaint();
    line2d = new Line2D.Float(oldX, oldY, currentX, currentY);
    repaint();
    ErasRect = new Rectangle2D.Float(currentX, currentY, thickness, thickness);
    repaint();

  // WE NEED ADD THIS TWO SHAPE HERE BECAUSE SHAPE DARWING WITH MOUSEDRAG !
        if (figures == EnumRope.ERASER) {
            addEraser(ErasRect, Color.WHITE, thickness);
            ErasRect = null;
        }else if (figures == EnumRope.PENCIL) {
            addPencil(ErasRect, currentColor, thickness);
            ErasRect = null;
        }
}

// GETTING RELEASED COORDINATE TO DRAW SHAPES BECAUSE SOME SHAPES GETTED 
//COORDINATES FROM MOUSEDRAGGED, IF YOU ADD THE SHAPE TO IMAGE IN MOUSEDRAGGED 
//SHAPE WILL BE NESTED( more nested shapes from small to big). SO ADD ALL 
//COORDINATES WHEN MOUSE RELEASED.

@Override 
public void mouseReleased(MouseEvent e) {

 if (figures == EnumRope.OVAL) {
        addEllipse(ellipse2d, currentColor, thickness);
        ellipse2d = null;
    } else if (figures == EnumRope.FILLEDOVAL) {
        addEllipse(ellipse2d, currentColor, thickness);
        ellipse2d = null;
    } else if (figures == EnumRope.RECT) {
        addRectangle(rectangle, currentColor, thickness);
        rectangle = null;
    } else if (figures == EnumRope.FILLEDRECT) {
        addRectangle(rectangle, currentColor, thickness);
        rectangle = null;
    } else if (figures == EnumRope.LINE) {
        addLine(line2d, currentColor, thickness);
        line2d = null;
    }

    }
}

希望这个回答对其他人有所帮助。