Skip to main content

Drag and drop Java2D shapes from one window another

1 reply [Last post]
ocicat
Offline
Joined: 2012-04-12
Points: 0

I would like to draw a Java2D shape on a canvas(JPanel) and drag a copy of it to another canvas that IS IN ANOTHER WINDOW.

Below is my current code experiment. When dragging, I see mouse cursor to be DragSource.DefaultCopyDrop, which is fine.

How can I make a copy of the original shape and move it on canvas while dragging?

I guess I could create a custom cursor (with .gif image of the original shape) and use it instead of the default copy cursor. That is a little complicated if I have several different source shapes (ellipses, rectangles, small and big, different colors.. ).

This is quite a challenging problem for me. Could you fellows give a helping hand, thanks in advance..

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;


public class dndexample {

public dndexample(){
}

public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override public void run() {
                createAndShowGUI();
            }

private void createAndShowGUI() {
try{
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }catch(Exception e) {
            e.printStackTrace();
        }

JFrame sourceFrame = new JFrame("Source");
JFrame targetFrame = new JFrame("Target");

SourceCanvas sCanvas = new SourceCanvas();
TargetCanvas tCanvas = new TargetCanvas();

new MyDropTargetListener(tCanvas);

JLabel nameA = new JLabel();
nameA.setText("gray rectangle");
nameA.setName("gray");
nameA.setBounds(25, 45, nameA.getPreferredSize().width, nameA.getPreferredSize().height);
       
        MyDragGestureListener dlistener = new MyDragGestureListener();
        DragSource ds1 = new DragSource();
        ds1.createDefaultDragGestureRecognizer(nameA,
            DnDConstants.ACTION_COPY, dlistener);
       
        JLabel nameB = new JLabel();
nameB.setText("green rectangle");
nameB.setName("green");
nameB.setBounds(70, 120, nameB.getPreferredSize().width, nameB.getPreferredSize().height);
       
        DragSource ds2 = new DragSource();
        ds2.createDefaultDragGestureRecognizer(nameB,
            DnDConstants.ACTION_COPY, dlistener);
       
        sCanvas.add(nameA);
        sCanvas.add(nameB);
       
sourceFrame.getContentPane().add(sCanvas);
sourceFrame.setLocationRelativeTo(null);
sourceFrame.setPreferredSize(sCanvas.getPreferredSize());
sourceFrame.pack();
        sourceFrame.setVisible(true);

               
        targetFrame.setLocationRelativeTo(null);
        targetFrame.setLayout(new BorderLayout());
        targetFrame.getContentPane().add(tCanvas, BorderLayout.CENTER);
        targetFrame.setPreferredSize(tCanvas.getPreferredSize());
        targetFrame.pack();
        targetFrame.setVisible(true);
       
}
        });
    }
}


class SourceCanvas extends JPanel{

public SourceCanvas(){

this.setLayout(null);

}

@Override public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g; //enables more advanced drawing features
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(2));
Rectangle2D rectangleA = new Rectangle2D.Double(20,20,120,50);
Rectangle2D rectangleB = new Rectangle2D.Double(60,90,120,50);
g2d.setColor(Color.gray);
g2d.draw(rectangleA);
g2d.setColor(Color.green);
g2d.draw(rectangleB);
}

@Override
public Dimension getPreferredSize(){
return new Dimension(200,200);
}


}

class TargetCanvas extends JPanel{

public TargetCanvas(){
this.setLayout(null);
}

@Override public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g; //enables more advanced drawing features
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(2));

}
@Override
public Dimension getPreferredSize(){
return new Dimension(200,200);
}


}

class MyRectangle{
private Rectangle2D shape;
private Color color;
public MyRectangle(Rectangle2D _shape, Color _color){
this.shape = _shape;
this.color = _color;
}

public Rectangle2D getShape(){
return shape;
}
public Color getColor(){
return color;
}

}

class MyDropTargetListener extends DropTargetAdapter{

private DropTarget dropTarget;

public MyDropTargetListener(TargetCanvas panel){

dropTarget = new DropTarget(panel, DnDConstants.ACTION_COPY,
            this, true, null);

}
public void drop(DropTargetDropEvent event) {
        try {
        
          DropTarget test  = (DropTarget)event.getSource();
          TargetCanvas ca = (TargetCanvas)test.getComponent();
         
          Point dropPoint = ca.getMousePosition();
        
          Transferable tr = event.getTransferable();
         
          if (event.isDataFlavorSupported(TransferableShapeInfo.shapeFlavor)) {
              MyRectangle myShape = (MyRectangle)tr.getTransferData(TransferableShapeInfo.shapeFlavor);
              if(myShape != null){
              event.acceptDrop(DnDConstants.ACTION_COPY);
              Graphics2D g2d = (Graphics2D)ca.getGraphics();
             
              g2d.setColor(myShape.getColor());
              g2d.draw(myShape.getShape());
               
              event.dropComplete(true);
              }
             
          }
          else
              event.rejectDrop();
        } catch (Exception e) {
          e.printStackTrace();
          event.rejectDrop();
        }
      }
}



class TransferableShapeInfo implements Transferable{
protected static DataFlavor shapeFlavor =
        new DataFlavor(MyRectangle.class, "A rectangle object");

        protected static DataFlavor[] supportedFlavors = {
           
            DataFlavor.stringFlavor, shapeFlavor
        };

        String iconName;
        MyRectangle myrectangle;

        public TransferableShapeInfo(MyRectangle _myrectangle){
        this.myrectangle = _myrectangle;
        }
       
        public TransferableShapeInfo(String text) { this.iconName = text; }

        public DataFlavor[] getTransferDataFlavors() { return supportedFlavors; }

        public boolean isDataFlavorSupported(DataFlavor flavor) {
        if (flavor.equals(flavor.equals(shapeFlavor)))
        return true;
        return false;
      }


       public Object getTransferData(DataFlavor flavor)
            throws UnsupportedFlavorException
       {
        
         if(flavor.equals(shapeFlavor))
        return myrectangle;
         else
        throw new UnsupportedFlavorException(flavor);
       }


}

class MyDragGestureListener implements DragGestureListener{

private MyRectangle grayrectangle = new MyRectangle(new Rectangle2D.Double(0,0,50,50), Color.gray);
private MyRectangle greenrectangle = new MyRectangle(new Rectangle2D.Double(0,0,50,50), Color.green);
private MyRectangle rectangleToDrag;

public MyDragGestureListener(){

}

@Override
public void dragGestureRecognized(DragGestureEvent event) {
Cursor cursor = null;



        JLabel label = (JLabel)event.getComponent();
        String text = label.getName();
        if(text.equals("gray"))
        rectangleToDrag = grayrectangle;
        if(text.equals("green"))
        rectangleToDrag = greenrectangle;
       
        if (event.getDragAction() == DnDConstants.ACTION_COPY) {
            cursor = DragSource.DefaultCopyDrop;
           
        }
        else
        cursor = DragSource.DefaultCopyNoDrop;

        event.startDrag(cursor, new TransferableShapeInfo(rectangleToDrag));

}

}

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
cobrien
Offline
Joined: 2004-06-09
Points: 0

We tried something like this. We ran into a system-dependent (i.e. different
between windows and linux) maximum cursor size that was pretty small.