Skip to content Skip to navigation Skip to collection information

OpenStax_CNX

You are here: Home » Content » Object-Oriented Programming (OOP) with ActionScript » Dragging Objects between Containers

Navigation

Recently Viewed

This feature requires Javascript to be enabled.
 

Dragging Objects between Containers

Module by: R.G. (Dick) Baldwin. E-mail the author

Summary: Learn how to drag objects between containers while giving each container the ability to either accept or reject the drop based on the type of object being dropped.

Note:

Click DragAndDrop04 to run this ActionScript program. (Click the "Back" button in your browser to return to this page.)

Preface

General

Note:

All references to ActionScript in this lesson are references to version 3 or later.

This tutorial lesson is part of a series of lessons dedicated to object-oriented programming (OOP) with ActionScript.

Several ways to create and launch ActionScript programs

There are several ways to create and launch programs written in the ActionScript programming language. Most of the lessons in this series will use Adobe Flex as the launch pad for the sample ActionScript programs.

An earlier lesson titled The Default Application Container provided information on how to get started programming with Adobe's Flex Builder 3. (See Baldwin's Flex programming website .) You should study that lesson before embarking on the lessons in this series.

Some understanding of Flex MXML will be required

I also recommend that you study all of the lessons on Baldwin's Flex programming website in parallel with your study of these ActionScript lessons. Eventually you will probably need to understand both ActionScript and Flex and the relationships that exist between them in order to become a successful ActionScript programmer.

Will emphasize ActionScript code

It is often possible to use either ActionScript code or Flex MXML code to achieve the same result. Insofar as this series of lessons is concerned, the emphasis will be on ActionScript code even in those cases where Flex MXML code may be a suitable alternative.

Viewing tip

I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the figures and listings while you are reading about them.

Figures

Listings

  • Listing 1 . The MXML code.
  • Listing 2 . Beginning of the Driver class.
  • Listing 3 . Beginning of the creationComplete event handler.
  • Listing 4 . Register a mouseDown event listener on each draggable object.
  • Listing 5 . The beginning of the mouseDown event handler.
  • Listing 6 . Get the name of the class from which the drag initiator was instantiated.
  • Listing 7 . Populate a new DragSource object with the drag initiator and a format string.
  • Listing 8 . Initiate the drag and drop operation.
  • Listing 9 . Register a different dragEnter event handler on each Canvas object.
  • Listing 10 . Register the same dragDrop event handler on all three Canvas objects.
  • Listing 11 . A dragEnter event handler for the top Canvas object.
  • Listing 12 . The dragDrop event handler.
  • Listing 13 . The MXML code for the program named DragAndDrop04.
  • Listing 14 . The ActionScript code for the program named DragAndDrop04.

Supplemental material

I recommend that you also study the other lessons in my extensive collection of online programming tutorials. You will find a consolidated index at www.DickBaldwin.com .

General background information

In the earlier lesson titled Drag and Drop Basics , you learned the basics of writing ActionScript 3 code to provide a drag and drop capability. In this lesson, you will expand on that knowledge by learning how to drag objects from one container to another container while giving each container the ability to either accept or reject the drop based on the type of object being dropped.

Functions, classes, methods, and events

The sample program that I will explain in this lesson will use the following functions, classes, methods, and events plus others as well:

  • flash.utils.getQualifiedClassName top level function
  • MouseEvent class
    • MouseDown event
  • DragEvent class
    • dragDrop event
    • dragEnter event
  • DragManager class
    • acceptDragDrop method
    • doDrag method
  • DragSource class
    • addData method
    • hasFormat method

Preview

In this lesson, I will explain how to drag and drop components from one container into another container while giving the receiving container the ability to accept or reject the drop on the basis of the type of object being dragged.

Program output at startup

Figure 1 shows the program output at startup.

Figure 1: Program output at startup.
Program output at startup.
Missing Image

Three Canvas objects in a VBox object

The program places three Canvas objects in a VBox object as shown in Figure 1. It places two Image objects in one of the Canvas objects. The Image objects are populated with the contents of the following two image files, which are shown in the project file structure in Figure 2.

  • butterfly.jpg
  • frog.jpg
Figure 2: Project file structure.
Project file structure.
Missing Image

The image of the project file structure shown in Figure 2 was taken from the Flex Builder 3 Navigator pane.

The program also places a Button object in the middle Canvas object shown in Figure 1, and places a TextArea object in the bottom Canvas object.

Draggable objects

The two Image objects as well as the Button object and the TextArea object are all draggable.

The Canvas objects are labeled

The program places a Label object at the top of each Canvas object. The labels are for information purposes and are not draggable.

Allowable drop zones

Each of the four draggable objects can be dragged and dropped within two of the three Canvas objects so long as the mouse pointer is inside the Canvas object when the drop occurs.

None of the draggable objects can be dropped in all three of the Canvas objects. The label at the top of each Canvas object tells which types of objects can be dropped into that particular Canvas object.

Protection on the left and top

An object may not be dropped in such a way that it protrudes outside the left edge or the top of a Canvas object. If an attempt is made to do so when an object is being dragged to a new location within the same Canvas object, it simply returns to its original position.

If this happens when the object is being dragged into a different Canvas object, it assumes the same relative position in the new Canvas object that it previously occupied in the Canvas object from which it was dragged.

Scrollbars magically appear

If the object is dropped such that it protrudes outside the right side or the bottom of the Canvas object, scroll bars automatically appear on the Canvas object.

Allowable object types in the different Canvas objects

The following list shows the types of draggable objects that can be dropped into each of the Canvas objects:

  • Top canvas: images and buttons only.
  • Middle canvas: buttons and text areas only.
  • Bottom canvas: text areas and images only.

Results of dragging objects

Figure 3 shows the results of dragging the button into the top Canvas object and dragging an image into the bottom Canvas object. You cannot drop the TextArea object into the top canvas, an image into the middle canvas, or the button into the bottom canvas.

Figure 3: Results of dragging objects.
Results of dragging objects.
Missing Image

Figure 4 shows the result of dropping the TextArea object into the middle Canvas object.

Figure 4: Result of droping the TextArea into the middle Canvas.
Result of droping the TextArea into the middle Canvas.
Missing image

Discussion and sample code

Will explain in fragments

I will explain the code for this program in fragments. Complete listings of the MXML code and the ActionScript code are provided in Listing 13 and Listing 14 near the end of the lesson.

The MXML code

The MXML code is shown in Listing 1 and also in Listing 13 for your convenience.

Listing 1: The MXML code.

<?xml version="1.0" encoding="utf-8"?>
<!--DragAndDrop04
-->

<mx:Application 
  xmlns:mx="http://www.adobe.com/2006/mxml" 
  xmlns:cc="CustomClasses.*">
  <cc:Driver/>

</mx:Application>

As is often the case in this series of tutorial lessons, the MXML file is very simple because the program was coded almost entirely in ActionScript. The MXML code simply instantiates an object of the Driver class. From that point forward, the behavior of the program is controlled by ActionScript code.

The ActionScript code

The beginning of the Driver class

The Driver class begins in Listing 2.

Listing 2: Beginning of the Driver class.

package CustomClasses{
  import flash.events.MouseEvent;
  import flash.utils.getQualifiedClassName;
  
  import mx.containers.Canvas;
  import mx.containers.VBox;
  import mx.controls.Button;
  import mx.controls.Image;
  import mx.controls.Label;
  import mx.controls.TextArea;
  import mx.core.DragSource;
  import mx.core.UIComponent;
  import mx.events.DragEvent;
  import mx.events.FlexEvent;
  import mx.managers.DragManager;

  //====================================================//
  
  public class Driver extends VBox {
    private var button:Button = new Button();
    private var butterfly:Image = new Image();
    private var frog:Image = new Image();
    private var textArea:TextArea = new TextArea();
    private var canvasA:Canvas = new Canvas();
    private var canvasB:Canvas = new Canvas();
    private var canvasC:Canvas = new Canvas();
    private var labelA:Label = new Label();
    private var labelB:Label = new Label();
    private var labelC:Label = new Label();
    private var localX:Number;
    private var localY:Number;
    
    public function Driver(){//constructor

      //Put a label at the top of each Canvas object.
      labelA.text = "Images and buttons only";
      labelB.text = "Buttons and text areas only.";
      labelC.text = "Text areas and imges only";
      canvasA.addChild(labelA);
      canvasB.addChild(labelB);
      canvasC.addChild(labelC);
      
      //Add the Canvas objects to the VBox object
      addChild(canvasA);
      addChild(canvasB);
      addChild(canvasC);

      //Embed the image files in the SWF file.
      [Embed("butterfly.jpg")]
      var butterflyA:Class;
      
      [Embed("frog.jpg")]
      var frogA:Class;
      
      //Load the images from the embedded image files
      // into the Image objects.
      butterfly.load(butterflyA);
      frog.load(frogA);
      
      //Put some text on the button and in the TextArea.
      button.label = "button";
      textArea.text = "textArea";
      
      //Add the components to the Canvas objects.
      canvasA.addChild(butterfly);
      canvasA.addChild(frog);
      canvasB.addChild(button);
      canvasC.addChild(textArea);

      //Register an event handler that will be executed
      // whcn the canvas and its children are fully 
      // constructed.
      this.addEventListener(FlexEvent.CREATION_COMPLETE,
                                        completeHandler);
    } //end constructor

Nothing new here

There is nothing new in Listing 2 that you haven't learned about in previous lessons.

A creationComplete event handler

The last statement in Listing 2 registers a CREATION_COMPLETE event handler on the VBox object. The code in the handler is executed when the VBox object and all of its children have been fully created. The event handler begins in Listing 3.

Listing 3: Beginning of the creationComplete event handler.


    private function completeHandler(
                          event:mx.events.FlexEvent):void{
      //Make the Canvas objects visible.
      canvasA.setStyle("backgroundColor",0x00FFFF);
      canvasB.setStyle("backgroundColor",0x00FFFF);
      canvasC.setStyle("backgroundColor",0x00FFFF);
      
      //Set the width and height of the canvas objects
      // based on the dimensions of butterfly.
      canvasA.width = 1.6*butterfly.width;
      canvasA.height = 1.6*butterfly.height;
      canvasB.width = 1.6*butterfly.width;
      canvasB.height = 1.6*butterfly.height;
      canvasC.width = 1.6*butterfly.width;
      canvasC.height = 1.6*butterfly.height;
      
      //Reduce the width of the textArea to less than 
      // its default width.
      textArea.width = butterfly.width;
      
      //Move the images, the button, and the text area
      // below the label
      butterfly.y = labelA.height;
      frog.y = labelA.height + butterfly.height;
      button.y = labelB.height;
      textArea.y = labelC.height;

Straightforward code

The code in Listing 3 is straightforward and you shouldn't have any difficulty understanding it based on what you have learned in previous lessons.

Register a mouseDown event listener on each draggable object

Listing 4 registers the same MOUSE_DOWN event listener on each draggable object. This is the beginning of the process that causes the two Image objects, the Button object, and the TextArea object to be draggable.

Listing 4: Register a mouseDown event listener on each draggable object.

      butterfly.addEventListener(MouseEvent.MOUSE_DOWN,
                                        mouseDownHandler);
      frog.addEventListener(MouseEvent.MOUSE_DOWN,
                                        mouseDownHandler);
      button.addEventListener(MouseEvent.MOUSE_DOWN,
                                        mouseDownHandler);
      textArea.addEventListener(MouseEvent.MOUSE_DOWN,
                                        mouseDownHandler);

There is nothing new or unique about the registration code in Listing 4. You have seen code like that in almost every lesson. The material that is unique to the drag and drop process is the code in the mouseDown event handler method that I will discuss next.

The beginning of the mouseDown event handler

I will put the explanation of the creationComplete event handler on hold while I explain the mouseDown event handler. I will return to the creationComplete event handler later.

The mouseDown event handler that is registered on the four draggable objects begins in Listing 5. This method is executed whenever any one of those objects dispatches a mouseDown event, and that is the beginning of the drag and drop process.

Listing 5: The beginning of the mouseDown event handler.


    private function mouseDownHandler(
                                   event:MouseEvent):void{
      this.localX = event.localX;
      this.localY = event.localY;
        

Listing 5 begins by getting and saving the coordinates of the mouse pointer, relative to the upper-left corner of the object that dispatches the mouseDown event. As you saw in the earlier lesson titled Drag and Drop Basics , this information will be used later to properly position the dropped image in the Canvas object.

Get the name of the class from which the drag initiator was instantiated

The code in Listing 6 is completely new to this lesson.

Listing 6: Get the name of the class from which the drag initiator was instantiated.

      var className:String = getQualifiedClassName(
                                            event.target);

The Adobe documentation refers to the object that dispatches the mouseDown event to start the drag and drop process as the drag initiator .

Call the standalone getQualifiedClassName function

Listing 6 calls the function named getQualifiedClassName to get a string containing the name of the class from which the drag initiator object was instantiated. Note that this is a stand-alone function in the flash.utils package.

Non-unique strings

Different classes return different strings but the strings are not unique. In other words, two or more classes may return the same string. For example, several different Flex components return the same string as the string returned by the Button component.

The three draggable component types used in this program return the following strings :

  • Image returns "mx.controls::Image"
  • Button returns "mx.controls::Button"
  • TextArea returns "mx.core::UITextField"

Save the string

The string returned by the object that dispatched the mouseDown event is saved in the variable named className in Listing 6. This string value will be used later to identify the type of component that dispatched the mouseDown event.

Some of the steps in the process...

When the object being dragged enters one of the Canvas objects, the Canvas object dispatches a dragEnter event, which is a subtype of the class DragEvent . The dragEnter event handler receives an object of type DragEvent , which encapsulates an object of the class DragSource .

The DragSource object

The DragSource object encapsulates a reference to the drag initiator object (the object that dispatched the mouseDown event) . It also encapsulates a format string that can be used to identify the drag initiator object. In this program, that string is used by a particular Canvas object to determine if it will accept a drop by the drag initiator object.

Populate a new DragSource object with the drag initiator and a format string

Listing 7 instantiates a new DragSource object and populates it with the drag initiator and a format string that identifies the type of the drag initiator. The format string is based on the class from which the drag initiator was instantiated using the information in the className variable from Listing 6 in the conditional clause.

Listing 7: Populate a new DragSource object with the drag initiator and a format string.

      var dragSource:DragSource = new DragSource();

      if(className == "mx.controls::Image"){
        dragSource.addData(UIComponent(
                         event.currentTarget),"imageObj");
      }else if(className == "mx.controls::Button"){
        dragSource.addData(UIComponent(
                        event.currentTarget),"buttonObj");
      }else if(className == "mx.core::UITextField"){
        dragSource.addData(UIComponent(
                      event.currentTarget),"textAreaObj");
      } //end else if
        

Can the drag initiator object be dropped?

A Canvas object that examines the format string from the DragSource object later in the program will use the format string to determine if it is willing to allow the drag initiator object to be dropped on it.

Cast the current target to type UIComponent

The term event.currentTarget is a reference to the object that dispatched the mouseDown event, which is the drag initiator. However, when the currentTarget is extracted from the MouseEvent object, it is returned as type Object . In order for it to be suitable for use as the drag initiator, it must be cast to type UIComponent .

Relationships among the strings

I could have simply used the strings from the above list as the format strings, but I decided to create new strings to show that they are really independent of one another.

The relationships that I created between the strings in the above list and the format strings is shown below:

  • Image returns "mx.controls::Image" -- "imageObj"
  • Button returns "mx.controls::Button" -- "buttonObj"
  • TextArea returns "mx.core::UITextField" -- "textAreaObj"

Initiate the drag and drop operation

Listing 8 calls the static method named doDrag of the DragManager class to initiate the drag and drop operation.

Listing 8: Initiate the drag and drop operation.

      DragManager.doDrag(UIComponent(event.currentTarget),
                                        dragSource,event);
    }//end mouseDownHandler

I explained the use of this method in the previous lesson titled Drag and Drop Basics so I will refer you back to that lesson for a detailed explanation.

Register a different dragEnter event handler on each Canvas object

Returning to the discussion of the creationComplete event handler, Listing 9 registers a different dragEnter event handler on each Canvas object.

Listing 9: Register a different dragEnter event handler on each Canvas object.

      //Register a different dragEnter event handler on
      // each Canvas object to make it possible for each
      // Canvas object to accept only two of the three
      // types of components for dropping.
      canvasA.addEventListener(DragEvent.DRAG_ENTER,
                                           enterHandlerA);
      canvasB.addEventListener(DragEvent.DRAG_ENTER,
                                           enterHandlerB);
      canvasC.addEventListener(DragEvent.DRAG_ENTER,
                                           enterHandlerC);

Dispatching dragEnter events

As you learned in the earlier lesson titled Drag and Drop Basics , when the user moves the drag proxy over another component, that component dispatches a dragEnter event.

If a dragEnter event handler has been registered on that component, the handler method is executed. If the code in the event handler accepts the drag, it becomes the drop target and receives dragOver , dragExit , and dragDrop events.

I will explain the code in the dragEnter event handlers later. Right now, let's look at the remainder of the creationComplete event handler.

Register the same dragDrop event handler on all three Canvas objects

Listing 10 registers the same dragDrop event handler on each of the three Canvas objects

Listing 10: Register the same dragDrop event handler on all three Canvas objects.

      //Register the same dragDrop event handler on all
      // three Canvas objects.
      canvasA.addEventListener(DragEvent.DRAG_DROP,
                                             dropHandler);
      canvasB.addEventListener(DragEvent.DRAG_DROP,
                                             dropHandler);
      canvasC.addEventListener(DragEvent.DRAG_DROP,
                                             dropHandler);

    } //end completeHandler

The code in Listing 10 will cause another event handler to be called on a Canvas object after it dispatches a dragEnter event and accepts the drag.

Listing 10 also signals the end of the creationComplete event handler.

The dragEnter event handlers

A different dragEnter event handler was registered on each Canvas object in Listing 9.

Each of the dragEnter event handlers is executed when the dragged component enters the Canvas object on which the handler is registered. The event handlers decide whether or not to accept a drop on the basis of the format string associated with the type of object being dragged. Note that each Canvas object will accept two of the three types of objects.

Will only explain one of the dragEnter event handlers

Because of the similarity of the three event handlers, I will explain only one of them. You can view the code for all three in Listing 14 near the end of the lesson. Listing 11 shows a dragEnter event handler for the top Canvas object shown in Figure 1.

Listing 11: A dragEnter event handler for the top Canvas object.

    //This dragEnter event handler causes the canvas to
    // accept images and buttons.
    private function enterHandlerA(event:DragEvent):void{
      if ((event.dragSource.hasFormat("imageObj")) || 
               (event.dragSource.hasFormat("buttonObj"))){
        
          DragManager.acceptDragDrop(
                             Canvas(event.currentTarget));
      } //end if
    } //end enterHandler

Confirm the correct format string

The event handler shown in Listing 11 causes the Canvas object to accept only images and buttons. The only difference between the code in Listing 11 and similar code in the earlier lesson titled Drag and Drop Basics is the use of the logical-or (||) operator in Listing 11 to accept either of the two string instead of just one.

The code in Listing 11 checks to confirm that the format string in the DragSource object matches either "imageObj" or "buttonObj" (see Listing 7) . If so, it calls the static acceptDragDrop method on the DragManager class, passing a reference to itself as a parameter in the method call.

Accept the dragged object

The call to the acceptDragDrop method notifies the DragManager that the Canvas object is willing to accept the contents of the DragSource object being dropped onto itself.

The dragDrop event handler

The dragDrop event handler was registered on all three Canvas objects in Listing 10. This method is executed after a Canvas object accepts the drag and the user releases the mouse button while the drag proxy is over the Canvas .

The dragDrop event handler method is shown in its entirety in Listing 12.

Listing 12: The dragDrop event handler.

    //Execute the dragDrop event handler to drop the
    // object in its new location. Compensate for the
    // fact that the mouse pointer is not at the
    // upper-left corner of the object when the drag is
    // initiated. Don't allow the image to be dragged off
    // the left side of the canvas or off the top of the
    // canvas. See more information about this in the
    // comments at the top.
    private function dropHandler(event:DragEvent):void{

      //Add the drag initiator to the new container. 
      // Note that it is not necessary to first remove it
      // from its old container.
      //Also note that the z-axis index is lost in this
      // operation. When an object is dropped on top of
      // another object in the new container, it stays on
      // top regardless of the original z-order of the
      // two objects.
      //The original z-order has no meaning when you drag
      // objects into a canvas from several othr Canvas
      //
      event.currentTarget.addChild(event.dragInitiator);

      //Position the dragInitiator in the Canvas object
      // based on the mouse coordinates at the drop and
      // the mouse coordinates relative to the upper-
      // left corner of the drag initiator at the 
      // start of the drag.
      //Compute the correct position for the upper-left
      // corner of the dropped object.
      //If you attempt to drop an object so that it
      // protrudes out of the left side or the top of 
      // the canvas, the drag and drop operation is
      // simply aborted.
      var cornerX:Number = (Canvas(event.currentTarget).
                                         mouseX) - localX;
      var cornerY:Number = (Canvas(event.currentTarget).
                                         mouseY) - localY;
      if((cornerX > 0.0) && (cornerY > 0.0)){
        event.dragInitiator.x = cornerX;
        event.dragInitiator.y = cornerY
      } //end if
    } //end dropHandler
    //--------------------------------------------------//
      
  } //end class
} //end package

The new code

The only real difference between the code in Listing 12 and the similar event handler in the earlier lesson titled Drag and Drop Basics is the first statement in Listing 12 that adds the dragged object as a child of the Canvas object.

What you learned in the earlier lesson in conjunction with the comments in Listing 12 should suffice and no further explanation of this method should be necessary.

The end of the program

Listing 12 also signals the end of the Driver class, the end of the package, and the end of the program.

Run the program

I encourage you to run this program from the web. Then copy the code from Listing 13 and Listing 14. Use that code to create a Flex project. Compile and run the project. Experiment with the code, making changes, and observing the results of your changes. Make certain that you can explain why your changes behave as they do.

Resources

I will publish a list containing links to ActionScript resources as a separate document. Search for ActionScript Resources in the Connexions search box.

Complete program listings

Complete listings of the MXML code and the ActionScript code are provided below.

Listing 13: The MXML code for the program named DragAndDrop04.

<?xml version="1.0" encoding="utf-8"?>
<!--DragAndDrop04
-->

<mx:Application 
  xmlns:mx="http://www.adobe.com/2006/mxml" 
  xmlns:cc="CustomClasses.*">
  <cc:Driver/>

</mx:Application>

Listing 14: The ActionScript code for the program named DragAndDrop04.

/*DragAndDrop04

Illustrates how to drag components from one container
to another while giving the receiving container the
ability to accept or reject the drop on the basis of the
type of object being dragged.

Places three Canvas objects in a VBox object.

Places two images in one of the Canvas objects:
butterfly.jpg
frog.jpg

Places a Button object in a second Canvas object.

Places a TextArea object in the third Canvas object.

All four of above objects are draggable.

Places a label at the top of each Canvas object, but the
labels are not draggable.

Any of the four draggable objects can be dragged and
dropped anywhere within two of the three Canvas objects
so long as the mouse pointer is inside the Canvas object.

None of the objects can be dropped in all three of the
Canvas objects.

If an object is dropped so that it protrudes outside the
left edge or the top of the Canvas object when being 
dragged to a new location within the same Canvas object, 
it simply returns to its original position. If this
happens when the object is being dragged into a different
Canvas object, it assumes the same relative position in
the new Canvas object that it previously occupied in the
Canvas object from which it was dragged.

If the dragged object is dropped such that it protrudes
outside the right side or the bottom of the Canvas
object, scroll bars automatically appear on the Canvas
object.

The size of the canvas is based on the size of the
butterfly image so that other images can be substituted 
for my images when the program is recompiled so long as 
the file names and paths are correct.
*********************************************************/
package CustomClasses{
  import flash.events.MouseEvent;
  import flash.utils.getQualifiedClassName;
  
  import mx.containers.Canvas;
  import mx.containers.VBox;
  import mx.controls.Button;
  import mx.controls.Image;
  import mx.controls.Label;
  import mx.controls.TextArea;
  import mx.core.DragSource;
  import mx.core.UIComponent;
  import mx.events.DragEvent;
  import mx.events.FlexEvent;
  import mx.managers.DragManager;

  //====================================================//
  
  public class Driver extends VBox {
    private var button:Button = new Button();
    private var butterfly:Image = new Image();
    private var frog:Image = new Image();
    private var textArea:TextArea = new TextArea();
    private var canvasA:Canvas = new Canvas();
    private var canvasB:Canvas = new Canvas();
    private var canvasC:Canvas = new Canvas();
    private var labelA:Label = new Label();
    private var labelB:Label = new Label();
    private var labelC:Label = new Label();
    private var localX:Number;
    private var localY:Number;
    
    public function Driver(){//constructor

      //Put a label at the top of each Canvas object.
      labelA.text = "Images and buttons only";
      labelB.text = "Buttons and text areas only.";
      labelC.text = "Text areas and imges only";
      canvasA.addChild(labelA);
      canvasB.addChild(labelB);
      canvasC.addChild(labelC);
      
      //Add the Canvas objects to the VBox object
      addChild(canvasA);
      addChild(canvasB);
      addChild(canvasC);

      //Embed the image files in the SWF file.
      [Embed("butterfly.jpg")]
      var butterflyA:Class;
      
      [Embed("frog.jpg")]
      var frogA:Class;
      
      //Load the images from the embedded image files
      // into the Image objects.
      butterfly.load(butterflyA);
      frog.load(frogA);
      
      //Put some text on the button and in the text area.
      button.label = "button";
      textArea.text = "textArea";
      
      //Add the components to the Canvas objects.
      canvasA.addChild(butterfly);
      canvasA.addChild(frog);
      canvasB.addChild(button);
      canvasC.addChild(textArea);

      //Register an event handler that will be executed
      // whcn the canvas and its children are fully 
      // constructed.
      this.addEventListener(FlexEvent.CREATION_COMPLETE,
                                         completeHandler);
    } //end constructor
    //--------------------------------------------------//

    //This handler method is executed when the Canvas and
    // its children have been fully created.
    private function completeHandler(
                          event:mx.events.FlexEvent):void{
      //Make the Canvas objects visible.
      canvasA.setStyle("backgroundColor",0x00FFFF);
      canvasB.setStyle("backgroundColor",0x00FFFF);
      canvasC.setStyle("backgroundColor",0x00FFFF);
      
      //Set the width and height of the canvas objects
      // based on the dimensions of butterfly.
      canvasA.width = 1.6*butterfly.width;
      canvasA.height = 1.6*butterfly.height;
      canvasB.width = 1.6*butterfly.width;
      canvasB.height = 1.6*butterfly.height;
      canvasC.width = 1.6*butterfly.width;
      canvasC.height = 1.6*butterfly.height;
      
      //Reduce the width of the textArea to less than 
      // its default width.
      textArea.width = butterfly.width;
      
      //Move the images, the button, and the text area
      // below the label
      butterfly.y = labelA.height;
      frog.y = labelA.height + butterfly.height;
      button.y = labelB.height;
      textArea.y = labelC.height;
      
      //Register event listeners to support drag and drop 
      // operations on both images, the button, and the
      // text area with the canvas as the drag target.
      butterfly.addEventListener(MouseEvent.MOUSE_DOWN,
                                        mouseDownHandler);
      frog.addEventListener(MouseEvent.MOUSE_DOWN,
                                        mouseDownHandler);
      button.addEventListener(MouseEvent.MOUSE_DOWN,
                                        mouseDownHandler);
      textArea.addEventListener(MouseEvent.MOUSE_DOWN,
                                        mouseDownHandler);

      //Register a different dragEnter event handler on
      // each Canvas object to make it possible for each
      // Canvas object to accept only two of the three
      // types of components for dropping.
      canvasA.addEventListener(DragEvent.DRAG_ENTER,
                                           enterHandlerA);
      canvasB.addEventListener(DragEvent.DRAG_ENTER,
                                           enterHandlerB);
      canvasC.addEventListener(DragEvent.DRAG_ENTER,
                                           enterHandlerC);

      //Register the same dragDrop event handler on all
      // three Canvas objects.
      canvasA.addEventListener(DragEvent.DRAG_DROP,
                                             dropHandler);
      canvasB.addEventListener(DragEvent.DRAG_DROP,
                                             dropHandler);
      canvasC.addEventListener(DragEvent.DRAG_DROP,
                                             dropHandler);

    } //end completeHandler
    //--------------------------------------------------//
    
    // This event handler initiates the drag-and-drop \
    // operation for the image that dispatches the 
    // mouseDown event.
    private function mouseDownHandler(
                                   event:MouseEvent):void{

      //Save the location of the mouse within the object
      // being dragged. This information will be used
      // later to properly position the dropped image in
      // the drop target.
      this.localX = event.localX;
      this.localY = event.localY;

      //The drag initiator is the object that dispatched
      // this mouseDown event. Get a string containing
      // the name of the class from which that object was
      // instantiated. For the components used in this 
      // program, the possible strings are:
      // Image - "mx.controls::Image"
      // Button - "mx.controls::Button"
      // TextAra - "mx.core::UITextField"
      //Note, the following function is in the
      // flash.utils package.
      var className:String = getQualifiedClassName(
                                            event.target);

      //Populate a new DragSource object with the drag
      // initiator and a format string based on the class
      // from which the drag initiator was instantiated.
      //The format string will be used later to decide
      // if a particular Canvas object is willing to
      // allow a particular type of object to be dropped
      // on it.
      //Note that when the target of the mouseDown event
      // is used as the drag initiator, it must be cast
      // to type UIComponent.
      var dragSource:DragSource = new DragSource();
      if(className == "mx.controls::Image"){
        dragSource.addData(UIComponent(
                         event.currentTarget),"imageObj");
      }else if(className == "mx.controls::Button"){
        dragSource.addData(UIComponent(
                        event.currentTarget),"buttonObj");
      }else if(className == "mx.core::UITextField"){
        dragSource.addData(UIComponent(
                      event.currentTarget),"textAreaObj");
      } //end else if

      //Initiate the drag and drop operation.
      DragManager.doDrag(UIComponent(event.currentTarget),
                                        dragSource,event);
    }//end mouseDownHandler
    //--------------------------------------------------//
    
    //Each of the following dragEnter event handlers is
    // executed when the dragged omponent enters the
    // Canvas object on which the handlr is registered.
    // The event handlers decide whether or not to accept
    // a drop on the basis ofthe format string associated
    // with the type of object being dragged. Note that
    // each Canvas ovject will accept two of the three
    // types of objects.
    
    //This dragEnter event handler causes the canvas to
    // accept images and buttons.
    private function enterHandlerA(event:DragEvent):void{
      if ((event.dragSource.hasFormat("imageObj")) || 
               (event.dragSource.hasFormat("buttonObj"))){
        
          DragManager.acceptDragDrop(
                             Canvas(event.currentTarget));
      } //end if
    } //end enterHandler
    //--------------------------------------------------//
    
    //This dragEnter event handler causes the canvas to
    // accept textAreas and buttons.
    private function enterHandlerB(event:DragEvent):void{
      if ((event.dragSource.hasFormat("textAreaObj")) || 
               (event.dragSource.hasFormat("buttonObj"))){
                 
          DragManager.acceptDragDrop(
                             Canvas(event.currentTarget));
      } //end if
    } //end enterHandler
    //--------------------------------------------------//
    
    //This dragEnter event handler causes the canvas to
    // textAreas and images.
    private function enterHandlerC(event:DragEvent):void{
      if ((event.dragSource.hasFormat("textAreaObj")) || 
                (event.dragSource.hasFormat("imageObj"))){
                  
          DragManager.acceptDragDrop(
                             Canvas(event.currentTarget));
      } //end if
    } //end enterHandler
    //--------------------------------------------------//
    
    //Execute the dragDrop event handler to drop the
    // object in its new location. Compensate for the
    // fact that the mouse pointer is not at the
    // upper-left corner of the object when the drag is
    // initiated. Don't allow the image to be dragged off
    // the left side of the canvas or off the top of the
    // canvas. See more information about this in the
    // comments at the top.
    private function dropHandler(event:DragEvent):void{

      //Add the drag initiator to the new container. 
      // Note that it is not necessary to first remove it
      // from its old container.
      //Also note that the z-axis index is lost in this
      // operation. When an object is dropped on top of
      // another object in the new container, it stays on
      // top regardless of the original z-order of the
      // two objects.
      //The original z-order has no meaning when you drag
      // objects into a canvas from several othr Canvas
      //
      event.currentTarget.addChild(event.dragInitiator);

      //Position the dragInitiator in the Canvas object
      // based on the mouse coordinates at the drop and
      // the mouse coordinates relative to the upper-
      // left corner of the drag initiator at the 
      // start of the drag.
      //Compute the correct position for the upper-left
      // corner of the dropped object.
      //If you attempt to drop an object so that it
      // protrudes out of the left side or the top of 
      // the canvas, the drag and drop operation is
      // simply aborted.
      var cornerX:Number = (Canvas(event.currentTarget).
                                         mouseX) - localX;
      var cornerY:Number = (Canvas(event.currentTarget).
                                         mouseY) - localY;
      if((cornerX > 0.0) && (cornerY > 0.0)){
        event.dragInitiator.x = cornerX;
        event.dragInitiator.y = cornerY
      } //end if
    } //end dropHandler
    //--------------------------------------------------//
      
  } //end class
} //end package

Miscellaneous

Note:

Housekeeping material
  • Module name: Dragging Objects between Containers
  • Files:
    • ActionScript0142\ActionScript0142.htm
    • ActionScript0142\Connexions\ActionScriptXhtml0142.htm

Note:

PDF disclaimer: Although the Connexions site makes it possible for you to download a PDF file for this module at no charge, and also makes it possible for you to purchase a pre-printed version of the PDF file, you should be aware that some of the HTML elements in this module may not translate well into PDF.

-end-

Collection Navigation

Content actions

Download:

Collection as:

PDF | EPUB (?)

What is an EPUB file?

EPUB is an electronic book format that can be read on a variety of mobile devices.

Downloading to a reading device

For detailed instructions on how to download this content's EPUB to your specific device, click the "(?)" link.

| More downloads ...

Module as:

PDF | EPUB (?)

What is an EPUB file?

EPUB is an electronic book format that can be read on a variety of mobile devices.

Downloading to a reading device

For detailed instructions on how to download this content's EPUB to your specific device, click the "(?)" link.

| More downloads ...

Add:

Collection to:

My Favorites (?)

'My Favorites' is a special kind of lens which you can use to bookmark modules and collections. 'My Favorites' can only be seen by you, and collections saved in 'My Favorites' can remember the last module you were on. You need an account to use 'My Favorites'.

| A lens I own (?)

Definition of a lens

Lenses

A lens is a custom view of the content in the repository. You can think of it as a fancy kind of list that will let you see content through the eyes of organizations and people you trust.

What is in a lens?

Lens makers point to materials (modules and collections), creating a guide that includes their own comments and descriptive tags about the content.

Who can create a lens?

Any individual member, a community, or a respected organization.

What are tags? tag icon

Tags are descriptors added by lens makers to help label content, attaching a vocabulary that is meaningful in the context of the lens.

| External bookmarks

Module to:

My Favorites (?)

'My Favorites' is a special kind of lens which you can use to bookmark modules and collections. 'My Favorites' can only be seen by you, and collections saved in 'My Favorites' can remember the last module you were on. You need an account to use 'My Favorites'.

| A lens I own (?)

Definition of a lens

Lenses

A lens is a custom view of the content in the repository. You can think of it as a fancy kind of list that will let you see content through the eyes of organizations and people you trust.

What is in a lens?

Lens makers point to materials (modules and collections), creating a guide that includes their own comments and descriptive tags about the content.

Who can create a lens?

Any individual member, a community, or a respected organization.

What are tags? tag icon

Tags are descriptors added by lens makers to help label content, attaching a vocabulary that is meaningful in the context of the lens.

| External bookmarks