Select and drag component Swing

1

I made an application that draws rectangles, points, lines, etc. I wanted that when the user clicks the mouse over a drawn polygon, you select the polygon and drag it to wherever you want on the screen, How to achieve that goal?     

asked by anonymous 29.01.2014 / 13:23

4 answers

0

If you want to do it in the hand ... it's been a while since I've worked with Java, but I'll try to give some tips.

Whenever a user draws a polygon, keep in mind the coordinates of that polygon. It's good to also keep a sort of "Z-index" to be able to have polygons one over the other (if you want to allow this)

private Vector<Poligono> poligonos;
public Vector<Poligono> getPoligonos() { return this.poligonos; }
public void setPoligonos(Vector<Poligono> poligonos) { this.poligonos = poligonos; }

public void desenharPoligono(int startX, int startY, int endX, int endY) {
    this.getPoligonos().push(new Poligono(startX, startY, endX, endY));
}

When the user makes a quick click (do not click and drag), scan your list of polygons to see if they click on a coordinate that belongs to a polygon ... If yes, bang, select your polygon! / p>

public void verificarCoordenadas(int x, int y) {
    for (Poligono poligono : this.getPoligonos()) {
        if (poligono.contemCoordenada(x, y)) {
            poligono.selecionar();
            return;
        }
    }
}

If I give more tips I take your challenge to learn alone. Your next steps would be to create the Poligono class and implement its methods ( contemCoordenada , selecionar , mover related) ...

It gave me a bit of a miss for Java now.

    
29.01.2014 / 14:31
1

I do not know exactly how you are creating the polygons.

But if it's a java.awt.Component I think this will solve:

import java.awt.*;
import java.awt.event.*;
import javax.swing.SwingUtilities;

public class Mover extends MouseAdapter {

  private Dimension snapSize = new Dimension( 1, 1 );
  private Component source;
  private Point pressed;
  private boolean potentialDrag;
  private static Mover instance;
  private Point locationBeforeMove;

  private Mover() {
  }

  public void deregisterComponent( Component... components ) {
    for ( Component component : components ) {
      component.removeMouseListener( this );
    }
  }

  public void registerComponent( Component... components ) {
    for ( Component component : components ) {
      component.addMouseListener( this );
    }
  }

  public Dimension getSnapSize() {
    return snapSize;
  }

  public void setSnapSize( Dimension snapSize ) {
    if ( snapSize.width < 1
        || snapSize.height < 1 ) {
      throw new IllegalArgumentException( "snapSize deve ser maior que 0" );
    }

    this.snapSize = snapSize;
  }

  @Override
  public void mousePressed( MouseEvent e ) {
    if ( !SwingUtilities.isLeftMouseButton( e ) ) {
      return;
    }
    if ( e.isConsumed() ) {
      return;
    }

    setupForDragging( e );
  }

  private void setupForDragging( MouseEvent e ) {
    source = e.getComponent();
    source.addMouseMotionListener( this );
    potentialDrag = true;

    pressed = e.getLocationOnScreen();

    locationBeforeMove = source.getLocation();
  }

  /**
   * Move the component to its new location. The dragged Point must be in the destination coordinates.
   */
  @Override
  public void mouseDragged( MouseEvent e ) {
    if ( !SwingUtilities.isLeftMouseButton( e ) ) {
      return;
    }
    if ( e.isConsumed() ) {
      return;
    }
    Point dragged = e.getLocationOnScreen();
    int dragX = getDragDistance( dragged.x, pressed.x, snapSize.width );
    int dragY = getDragDistance( dragged.y, pressed.y, snapSize.height );

    Component source = e.getComponent();

    Point location = locationBeforeMove;
    if ( location == null ) {
      return;
    }

    int locationX = location.x + dragX;
    int locationY = location.y + dragY;

    while ( locationX < 0 ) {
      locationX += snapSize.width;
    }

    while ( locationY < 0 ) {
      locationY += snapSize.height;
    }

    Dimension d = getBoundingSize( source );

    while ( locationX + source.getSize().width > d.width ) {
      locationX -= snapSize.width;
    }

    while ( locationY + source.getSize().height > d.height ) {
      locationY -= snapSize.height;
    }

    source.setLocation( locationX, locationY );
  }


  private int getDragDistance( int larger, int smaller, int snapSize ) {
    int halfway = snapSize / 2;
    int drag = larger - smaller;
    drag += (drag < 0) ? -halfway : halfway;
    drag = (drag / snapSize) * snapSize;

    return drag;
  }

  private Dimension getBoundingSize( Component source ) {
    if ( source instanceof Window ) {
      GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
      Rectangle bounds = env.getMaximumWindowBounds();
      return new Dimension( bounds.width, bounds.height );
    }
    else {
      return source.getParent().getSize();
    }
  }

  @Override
  public void mouseReleased( MouseEvent e ) {
    if ( !SwingUtilities.isLeftMouseButton( e ) ) {
      return;
    }
    if ( !potentialDrag ) {
      return;
    }

    source.removeMouseMotionListener( this );
    potentialDrag = false;
  }

  public static Mover getInstance() {
    if ( instance == null ) {
      instance = new Mover();
    }
    return instance;
  }
}

To use the class:

Poligono poligono = new Poligono();
Mover.getInstance().registerComponent( poligono );
    
29.01.2014 / 15:32
0

First of all I think I have to revise Swing because it will not be continued, I suggest using Java FX, which is very cool, easy to use and has cool components.

On the problem you would have to use some drag & drop , which will work with the positions of the image. Something like that.

    
29.01.2014 / 13:29
0

Depending on the purpose of this, it would have to do "in the arm": Detecting where the guy clicked, identifying which polygon is, and repainting the polygon on the screen by moving it and so on ... It depends on how you are drawing the polygon

    
29.01.2014 / 13:57