xmlgraphics-batik-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andres Toussaint <and...@onemileup.com>
Subject Re: Drag and drop
Date Thu, 13 May 2004 23:16:07 GMT
Hi,

Since i had invested quite some time with this issue and have finally 
done it, thanks to a wide variety of sources and help from other userĀ“s 
replies to the forums, i am submitting my solution to two options of 
DnD situations.

DnD options:

1. ) from a JComponent, (like a JTree) into a JSVGCanvas (to add a item 
into the canvas from a list, for example)
For this first option, you need to use typical Swing DnD, setting the 
JSVGCanvas as a DnDGestureRecognizer, to accept the drop. I implement 
it passing a XML object with the info that describes the added svg 
element, and you need to convert the coordinates of the mouse upon drop 
to the Canvas coordinates, so the drop is placed accurately.

2.) or In the same JSCGCanvas, to move around a SVGElement inside the 
JSVGCanvas.
In this option, you have to add EventListener to the SVG elements you 
want to track and or DnD.

I am attaching a brief of the code to do both items. All this code is 
in the same public class (in my case a JPanel).

/////////////////Start code for option 1 
//////////////////////////////////



     ///////////////////////////////////////////////////////
     // Methods for DnD from a Jcomponent to a JSVGCanvas

     // Your public class declaration needs to implement:
     // public class XXXXX extends XXXXX implements DropTargetListener
     //
     // With this, the component that holds the JSVGCanvas is now enabled
     // to receive Drops. It is up to you to decide how to handle the 
drop
     //
     // The sample code below has a generic Drop Flavor analizer, in 
case your flavor
     // coming from a diferent source.

     public void dragEnter(DropTargetDragEvent dtde) {
         //System.err.println( "DragEnter: " + dtde );
         dragOverAlready = false;
     }

     public void dragOver(DropTargetDragEvent dtde) {
         if( dragOverAlready )
             return;

         //System.err.println( "DragOver: " + dtde + " ... skipping 
more" );
         dragOverAlready = true;
     }

     public void dropActionChanged(DropTargetDragEvent dtde) {
         //System.err.println( "DropActionChanged: " + dtde );
     }

     public void dragExit(DropTargetEvent dte) {
         //System.err.println( "DragExit: " + dte );
     }

     public void drop(DropTargetDropEvent dtde) {
         //System.err.println( "Drop: " + dtde );

         try {
             dtde.acceptDrop( DnDConstants.ACTION_COPY_OR_MOVE );

             // On the PC, it looks like it is possible to invoke the
             // JOptionPane directly.
             // On Linux and Mac OSX, this produces a deadlock. 
Therefore,
             // the invokeLater().


             Transferable t = dtde.getTransferable();
             DataFlavor [] flavors = dtde.getCurrentDataFlavors();

             for( int i=0 ; i<flavors.length ; ++i ) {
                 try {
                     /*
                     System.err.println( "  found flavor " + i + ": " + 
flavors[i] );
                     System.err.println( "    human presentable name: " 
+ flavors[i].getHumanPresentableName() );
                     System.err.println( "    default representation 
class: " + flavors[i].getDefaultRepresentationClass() );
                     System.err.println( "    mime type: " + 
flavors[i].getMimeType() );
                     System.err.println( "    charset parameter: " + 
flavors[i].getParameter( "charset" ));
                     */
                     Object data = t.getTransferData( flavors[i] );
                     //System.err.println( "    value: " + data );
                     //System.err.print(   "    attempt at reading: " );
                     if( data instanceof String ) {
                         //System.err.println( "\"" + data + "\"" );
                     }
                     else if( data instanceof InputStream ) {
                         //System.err.print( "\"" );

                         String charset = flavors[i].getParameter( 
"charset" );
                         Reader r;
                         if( charset == null )
                             r = new InputStreamReader( (InputStream) 
data );
                         else
                             r = new InputStreamReader( (InputStream) 
data, charset );

                         int c;
                         while( ( c = r.read() ) > 0 )
                             //System.err.print( (char) c );
                         // this loop stops when 0 is read -- against 
the spec, but apparently as implemented
                         // do not use bulk reading as the 
InputStreamReader will read too far too ...
                         //System.err.println( "\"" );
                                                 logDebug("here is a 
InputStream");

                     }
                     else if( data instanceof Reader ) {
                         //System.err.print( "\"" );
                         Reader r = (Reader) data;
                         int c;
                         while( ( c = r.read() ) > 0 )
                             //System.err.print( (char) c );
                         // this loop stops when 0 is read -- against 
the spec, but apparently as implemented
                         // do not use bulk reading as the 
InputStreamReader will read too far too ...
                         //System.err.println( "\"" );

                                                 logDebug("here is a 
Reader");

                     }

                     //else
                         //System.err.println( "** can't print this **" 
);

                     //System.err.println();

                 } catch( Exception ex ) {
                    logError( "Exception: ", ex );
                 }
             }
         } finally {
             dtde.dropComplete( true );
             // it's important that dropComplete be called under all 
circumstances, otherwise the app will
             // likely hang, requiring a hard kill
         }
     }

////////////////////////END code for option 1 
///////////////////////////////




/////////////////Start code for option 2 
//////////////////////////////////


     public void createComponents() {

     	...
     	
         svgCanvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
         svgCanvas.setEnableRotateInteractor(false);
         svgCanvas.setEnableZoomInteractor(false);
         svgCanvas.setEnablePanInteractor(false);
         svgCanvas.setEnableImageZoomInteractor(false);

         svgCanvas.addSVGLoadEventDispatcherListener
         (new SVGLoadEventDispatcherAdapter() {
             public void svgLoadEventDispatchStarted
             (SVGLoadEventDispatcherEvent e) {
                 // At this time the document is available...
                 document = svgCanvas.getSVGDocument();  // SVGDocument 
document
                 // ...and the window object too.
                 window = svgCanvas.getUpdateManager().  // Window window
                 getScriptingEnvironment().createWindow();
                 // Registers the listeners on the document
                 // just before the SVGLoad event is
                 // dispatched.
                 registerListeners();
             }
         });

		...
		
     }


     public void registerListeners() {
         // Gets an element from the loaded document.
         elt = document.getElementById("imgGroup"); // 
org.w3c.dom.Element elt
         EventTarget t = (EventTarget)elt;

         // Adds  'mouseevent' listeners
         t.addEventListener("mousedown", new OnDownAction(), false);
         t.addEventListener("mousemove", new OnMoveAction(), false);
         t.addEventListener("mouseup", new OnUpAction(), false);
         t.addEventListener("mouseover", new OnOverAction(), false);
         t.addEventListener("click", new OnClickAction(), false);
     }

     public class OnClickAction implements EventListener {
         public void handleEvent(Event evt) {
             // do something
         }
     }

     public class OnDownAction implements EventListener {
         public void handleEvent(Event evt) {

         //Get the mouse event and obtain the screen coords of the event
         DOMMouseEvent elEvt = (DOMMouseEvent)evt;
         int nowToX = elEvt.getClientX();
         int nowToY = elEvt.getClientY();

         // get the first object of the canvas, to obtain a reference
         // of the AffineTransform to apply to the screen coords, since 
the
         // canvas is in a different scale than the screen.
         SVGLocatable thisNode = (SVGLocatable)elt.getFirstChild();
         SVGOMPoint pt = new SVGOMPoint(nowToX, nowToY);
         SVGMatrix mat = thisNode.getScreenCTM();  // elem -> screen
         mat = mat.inverse();                  // screen -> elem
         pt = (SVGOMPoint)pt.matrixTransform(mat);

         // pt holds the canvas coordinates of the mouse click

         // now do something, like start drag.

         // in case of a drag, you should set the dragActive variable 
with the
         // reference to the object dragged.

         }
     }

     public class OnUpAction implements EventListener {
         public void handleEvent(Event evt) {
			// Do something. Like finalize the drag operation.
         }
     }

     public class OnOverAction implements EventListener {
         public void handleEvent(Event evt) {
			// Usually nothing is done here, unless you want to transmit the 
cursor
			// coorfinates to a X, Y indicator, for instance.
         }
     }


     public class OnMoveAction implements EventListener {
         public void handleEvent(Event evt) {
            // Check if drag is in progress, and update the coordinates 
of the dragged
            // item to reflect the drag action on screen. Since the 
document
            // has been defined as ALWAYS_DINAMIC once this method is 
done, the
            // SVGCanvas runnableQueue will run reflecting your changes 
on screen.

            // Can be really slow if your SVG is complex, so a temp grey 
Bounding box
            // object can be shown instead.
         }
     }

     ///////////////////////////End code for option 2 
//////////////////////////



On May 13, 2004, at 4:54 PM, fransemail wrote:

> Hello , Has anyone seen a drag and drop implementation in SVG anywhere 
> ?
> Thanks
>
> --
> Email.it, the professional e-mail, gratis per te: http://www.email.it/f
> Sponsor:
> Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=&d=13-5
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: batik-users-help@xml.apache.org
>
>



---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org


Mime
View raw message