-1

I am trying to write a program that draws a line of circles with mouseDragged, like MS paint does. I have successfully gotten my program to draw a circle when I click. I have also been successful in getting my program to draw a circle when I drag the mouse; however, this doesn't leave a line of circles behind wherever I dragged. It simply drags the same circle around. I am trying to get my program to leave a trail of circles behind where I am dragging but I am pretty confused on why my program wont do so.

package assignment_11;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.*;


public class Canvas extends JComponent implements MouseListener, MouseMotionListener{

private int x, x1;
private int y, y1;

public Canvas() {
    addMouseMotionListener(this);
    addMouseListener(this);
}

public static void main(String[] args) {
    //creates new JFrame, sets Exit On Close, sets visible
    JFrame window = new JFrame();
    window.add(new Canvas());
    window.pack();
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);
}

public Dimension getPreferredSize() {
    return new Dimension(640,480);
}

@Override
public void mouseClicked(MouseEvent arg0) {
    System.out.println(arg0);
    x = arg0.getX();
    y = arg0.getY();
    repaint();

}

@Override
public void mouseEntered(MouseEvent arg0) {
    System.out.println(arg0);

}

@Override
public void mouseExited(MouseEvent arg0) {
    System.out.println(arg0);

}

@Override
public void mousePressed(MouseEvent arg0) {
    System.out.println(arg0);

}

@Override
public void mouseReleased(MouseEvent arg0) {
    System.out.println(arg0);

}

public void paintComponent(Graphics g) {
    g.fillOval(x, y, 10, 10);
    g.fillOval(x1, y1, 10, 10);
}

@Override
public void mouseDragged(MouseEvent arg0) {
    System.out.println(arg0);
    x1 = arg0.getX();
    y1 = arg0.getY();
    repaint();
}

@Override
public void mouseMoved(MouseEvent arg0) {
    System.out.println(arg0);
}


}

Any help is appreciated!

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
corbrrrrr
  • 13
  • 4
  • 1
    `"I also HAVE read many of the so called "duplicate" questions and in light of this still wanted help with MY code, as I have approached the problem differently (granted it may not be the best way to approach it)."` -- it's not that your way is "not the best way", it's the *wrong* way. Follow the advice given to you by MadProgrammer below and you won't go wrong. I have to admit to being surprised and dismayed that you re-asked the question without even leaving a comment to mad's answer about anything that confuses you, as if you didn't read it or care about it. – Hovercraft Full Of Eels Mar 12 '18 at 01:22
  • I'm simply approaching the problem with the tools I have been taught so far in my course. The course has not covered ArrayLists so I am confident there is a way to solve this problem in a different way than the solution provided here. I do not have time to teach myself ArrayLists, which is a completely new topic to me, and I do not want to simply copy his code. In addition, I was not "re-asking the question," I was asking a different question that is an extension of this one. I didn't respond because I solved the problem covered by this question on my own without using MP's techniques. – corbrrrrr Mar 12 '18 at 01:35
  • 1
    Regardless -- don't ignore the answers given, and then ask a new question. You've no comment to Mad's answer, none, and yet you re-asked the question, which looked to him and to all of us that you completely ignored all the effort that he put in to answering you, when you re-asked the question. Again, this will demotivate anyone from answering any future questions that you might ask, since no one wants their volunteer efforts totally ignored. At least up-vote and accept his answer. – Hovercraft Full Of Eels Mar 12 '18 at 01:36

1 Answers1

4

Painting is destructive. That is, every time paintComponent is called, you are expected to repaint the entire state of the component.

This raises the issue - you need some way to store the state you want to paint every time paintComponent is called.

For this, a simple ArrayList would do the job nicely. It would allow you to store all the points you're interested and allow you to repaint them each time paintComponent is called, for example...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class Canvas extends JComponent implements MouseListener, MouseMotionListener {

    private List<Point> points;

    public Canvas() {
        points = new ArrayList<>(25);
        addMouseMotionListener(this);
        addMouseListener(this);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater((new Runnable() {
            @Override
            public void run() {
                JFrame window = new JFrame();
                window.add(new Canvas());
                window.pack();
                window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                window.setVisible(true);
            }
        }));
    }

    public Dimension getPreferredSize() {
        return new Dimension(640, 480);
    }

    @Override
    public void mouseClicked(MouseEvent arg0) {
        System.out.println(arg0);
        points.add(arg0.getPoint());
        repaint();

    }

    @Override
    public void mouseEntered(MouseEvent arg0) {
        System.out.println(arg0);

    }

    @Override
    public void mouseExited(MouseEvent arg0) {
        System.out.println(arg0);

    }

    @Override
    public void mousePressed(MouseEvent arg0) {
        System.out.println(arg0);

    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
        System.out.println(arg0);

    }

    public void paintComponent(Graphics g) {
        for (Point p : points) {
            g.fillOval(p.x, p.y, 10, 10);
        }
    }

    @Override
    public void mouseDragged(MouseEvent arg0) {
        System.out.println(arg0);
        points.add(arg0.getPoint());
        repaint();
    }

    @Override
    public void mouseMoved(MouseEvent arg0) {
        System.out.println(arg0);
    }

}

Now, as the complexity of your problem grows, you could instead store "shapes" in the List which have some kind of notion of how to paint themselves, allowing to add in more complex shapes

You should also have a look at Painting in AWT and Swing to gain a better understand of how painting in Swing actually works

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366