javagraphicspaintgraphics2dmousemotionlistener

Multiple shapes when drawing via Mousedragged


I need to some help about drawing shapes with java graphics...,I'm trying to create paint application and when I using mousedragged its drawing multiple shapes (from small to large);like this : https://i.sstatic.net/0oQmv.png

Anyone can solve this issue ? THANKS FOR ALL..

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

}

Solution

  • Finally after a lot struggle I solved it :) and there is some example code :

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

    I hope to this answer benefit to others.