Priidu Kull
Priidu Kull

Reputation: 107

Java 6: how to drag/move a line?

I have this piece of code, which is supposed to move some pixels on release of mousebutton:

if (selected != -1) {
    Point to = e.getPoint();
    int dx = start.x - to.x;
    int dy = start.y - to.y;
    for (Point p: store.get(selected)) {
        int px = (int) p.getX();
        int py = (int) p.getY();
        p.move(px - dx, py - dy);
    }

    validate();

Use of debugger shows that Point p's indeed get a new value, but visuals don't get updated. Please help me out.

Below is the whole code of my program.

public class Pisi extends JFrame implements MouseMotionListener, MouseListener {
ArrayList<ArrayList<Point>> store = new ArrayList<ArrayList<Point>>();
ArrayList<Point> pts = new ArrayList<Point>();
Point start;
static int xsize = 450;
static int ysize = 300;
int listNumber = 0;
int selected = -1;



public static void main(String[] args) {
    Pisi d = new Pisi();
    d.setSize(xsize, ysize);
    d.setLocationRelativeTo(null);
    d.addMouseMotionListener(d);
    d.addMouseListener(d);
    d.setResizable(false);
    d.setVisible(true);
}

@Override
public void update(Graphics g) {
    paint(g);
}
@Override
public void paint(Graphics g) {
    Point last = null;

    for (Point p : pts) {

        if (last == null) {
            last = p;
            continue;
        }
        g.drawLine(last.x, last.y, p.x, p.y);
        last = p;
    }
}

@Override
public void mouseDragged(MouseEvent e) {

    if (e.getButton() == MouseEvent.BUTTON1) {
        pts.add(e.getPoint());
        repaint();
    }

}

@Override
public void mouseMoved(MouseEvent e) {
    //To change body of implemented methods use File | Settings | File Templates.
}

@Override
public void mouseClicked(MouseEvent e) {
    //To change body of implemented methods use File | Settings | File Templates.
}

@Override
public void mousePressed(MouseEvent e) {
    Point point = e.getPoint();
    start = null;
    selected = -1;
    for (ArrayList<Point> points: store) {
        for (Point p : points) {
            double dist = point.distanceSq(p);
            if (dist < 10) {
                selected = store.indexOf(points);
            }
        }
    }
    if (selected != -1) {
        start = e.getPoint();
    }
    System.out.println(selected);
}


@Override
public void mouseReleased(MouseEvent e) {
    if (selected != -1) {
        Point to = e.getPoint();
        int dx = start.x - to.x;
        int dy = start.y - to.y;
        for (Point p: store.get(selected)) {
            int px = (int) p.getX();
            int py = (int) p.getY();
            p.move(px - dx, py - dy);
        }

        validate();
    } else if (e.getButton() == MouseEvent.BUTTON1 && pts.size() != 0) {
        store.add(new ArrayList<Point>(listNumber));
        for (int i = 0; i < pts.size(); i++) {
            store.get(listNumber).add(pts.get(i));
        }
        listNumber++;
    }
    pts.clear();

}

@Override
public void mouseEntered(MouseEvent e) {
    //To change body of implemented methods use File | Settings | File Templates.
}

@Override
public void mouseExited(MouseEvent mouseEvent) {
    //To change body of implemented methods use File | Settings | File Templates.
}
}

Upvotes: 1

Views: 3148

Answers (2)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

I would recommend:

  • First that you draw in the paintComponent(...) method of a JPanel, not directly in the paint(...) method of a JFrame. This will give you access to Swing's automatic double buffering and will prevent you from messing up the graphics of any children or borders of the JFrame.
  • That rather than use an ArrayList<Point> and an ArrayList<ArrayList<Point>> that you instead use a Path2D and an ArrayList<Path2D>.
  • That you cast your `paintComponent's Graphics object to a Graphics2D object
  • That you use this Graphics2D object to draw your Path2D objects using the draw(Shape s) method for this.
  • That you use the Path2D contains(...) method to see if the mouse press is occurring on a Path2D object that is held by your List<Path2D>
  • That if a Path2D is selected you move it via the transform method using an AffineTransform.

Edit:
Nope, contains(...) won't work since this is true if the mouse is pressed in the concave region outlined by the Path2D. Looking into this further...

Edit 2:
One way around this is to use a PathIterator to iterate through your Path2D's to see if your mousePress is near any of the line segments that constitute the Path2D.

Upvotes: 4

Joseph Farrugia
Joseph Farrugia

Reputation: 327

I recommend you to try validate() method first (method of the Container class)

Note: information on validate() method

If validate() method won't work try to use:

update() method (calls paint() method) or repaint() method.

Upvotes: 0

Related Questions