private static void addSprites(Compositor sh) throws IOException, QTException {
    File matchFile =
        QTFactory.findAbsolutePath("images/Ship01.pct"); // this file must exist in the directory!!!
    ImageDataSequence isp = ImageUtil.createSequence(matchFile);
    ImageDataSequence seq = ImageUtil.makeTransparent(isp, QDColor.blue);

    // Build Sprites
    Matrix matrix1 = new Matrix();
    matrix1.setTx(20);
    matrix1.setTy(20);
    matrix1.setSx(0.8F);
    matrix1.setSy(0.8F);
    TwoDSprite s1 = new TwoDSprite(seq, 4, matrix1, true, 1);
    sh.addMember(s1);

    Matrix matrix2 = new Matrix();
    matrix2.setTx(4);
    matrix2.setTy(4);
    TwoDSprite s2 = new TwoDSprite(seq, 1, matrix2, true, 10);
    sh.addMember(s2);

    // This needs to be a 32bit QDGraphics so the blend mode will
    // be applied correctly to this sprite
    File shipFile = QTFactory.findAbsolutePath("images/Ship10.pct");
    GraphicsImporterDrawer ip = new GraphicsImporterDrawer(new QTFile(shipFile));
    QDRect r = new QDRect(ip.getDescription().getWidth(), ip.getDescription().getHeight());
    ImageSpec si =
        ImageUtil.makeTransparent(
            ip, QDColor.blue, new QDGraphics(QDGraphics.kDefaultPixelFormat, r));
    Matrix matrix3 = new Matrix();
    matrix3.setTx(50);
    matrix3.setTy(50);
    TwoDSprite s3 =
        new TwoDSprite(si, matrix3, true, 8, new GraphicsMode(QDConstants.blend, QDColor.green));
    sh.addMember(s3);

    // Add Dragger (DEPRECATED CODE)
    /*		Dragger dragger = new Dragger (InputEvent.SHIFT_MASK);
    SWController controller = new SWController (dragger, true);
    sh.addController (controller);*/

    QTMouseTargetController shipController = new QTMouseTargetController(true);
    shipController.addQTMouseListener(
        new DragAction(new TranslateMatrix()) {
          // only activates when the shift modifier is pressed
          public boolean matchModifierFilter(int mods) {
            if ((mods & 0xF) == QTConstants.kJavaShiftMask) return true;
            return false;
          }
        });
    sh.addController(shipController);

    // Add Controllers
    // Build ActionList
    SimpleActionList al = new SimpleActionList();
    ImageSequencer is = new ImageSequencer(seq);
    is.setLooping(ImageSequencer.kLoopForwards);
    al.addMember(new NextImageAction(10, 1, is, s1));
    al.addMember(new BounceAction(5, 1, sh, s1, 3, 2));
    ImageSequencer is2 = new ImageSequencer(seq);
    is2.setLooping(ImageSequencer.kLoopForwards);
    al.addMember(new NextImageAction(20, 1, is2, s2));
    al.addMember(new BounceAction(20, 1, sh, s2, 4, 3));
    sh.addController(al);
  }
  GroupDrawing(String title) throws Exception {
    super(title);

    QTCanvas myQTCanvas = new QTCanvas(QTCanvas.kAspectResize, 0, 0);
    add("Center", myQTCanvas);

    addWindowListener(
        new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            QTSession.close();
            dispose();
          }

          public void windowClosed(WindowEvent e) {
            System.exit(0);
          }
        });

    // setupGroup
    int kWidth = 300, kHeight = 300;
    DirectGroup drawer = new DirectGroup(new QDDimension(kWidth, kHeight), QDColor.gray);

    QTPlayer qtPlayer = makePlayer(new QTFile(QTFactory.findAbsolutePath("jumps.mov")));
    drawer.addMember(qtPlayer, 1, 0.1F, 0.2F);

    Compositor shipAnimation =
        new Compositor(new QDGraphics(new QDRect(200, 200)), QDColor.lightGray, 20, 1);
    addSprites(shipAnimation);
    shipAnimation.setLocation(kWidth - 160, kHeight - 160);
    drawer.addMember(shipAnimation, 2);

    QTFile imageFile = new QTFile(QTFactory.findAbsolutePath("pics/house.jpg"));
    GraphicsImporterDrawer gid1 = new GraphicsImporterDrawer(imageFile);
    gid1.setDisplayBounds(new QDRect(kWidth, kHeight));
    // we use an ImagePresenter for this member as the dragging is much quicker
    ImagePresenter ip = ImagePresenter.fromGraphicsImporterDrawer(gid1);
    drawer.addMember(ip, 3);

    /*Dragger dragger = new Dragger (MouseResponder.kNoModifiersMask);
    dragger.setConstrained(Dragger.kConstrainNone);
    GroupController controller1 = new GroupController (dragger, false);
    controller1.addMember (qtPlayer);
    controller1.addMember (shipAnimation);
    //drawer.addController (controller1);
    */

    QTMouseTargetController qtmc = new QTMouseTargetController(false);
    qtmc.addMember(qtPlayer);
    qtmc.addMember(shipAnimation);
    drawer.addController(qtmc);
    TransformMatrix transMatrix = new TranslateMatrix();
    transMatrix.setConstraint(TransformMatrix.kConstraintSpecifiedAll);
    qtmc.addQTMouseListener(
        new DragAction(transMatrix) {

          // only activates when NO modifiers are pressed
          public boolean matchModifierFilter(int mods) {
            if ((mods & 0xF) == 0) return true;
            return false;
          }

          public void mouseDragged(QTMouseEvent event) {
            super.mouseDragged(event);
          }
        });

    /*Dragger dragger2 = new Dragger (MouseResponder.kNoModifiersMask);
    GroupController controller2 = new GroupController (dragger2, false);
    controller2.addMember (ip);
    drawer.addController (controller2);*/

    QTMouseTargetController qtmc2 = new QTMouseTargetController(false);
    qtmc2.addMember(ip);
    drawer.addController(qtmc2);
    qtmc2.addQTMouseListener(
        new DragAction(new TranslateMatrix()) {
          // only activates when NO modifiers are pressed
          public boolean matchModifierFilter(int mods) {
            if ((mods & 0xF) == 0) return true;
            return false;
          }

          public void mouseDragged(QTMouseEvent event) {
            super.mouseDragged(event);
          }
        });

    /*	LayerChanger mouseTargetCntrl = new LayerChanger (InputEvent.ALT_MASK);
    GroupController controller3 = new GroupController (mouseTargetCntrl, true);
    drawer.addController (controller3);*/

    mouseTargetCntrl = new QTMouseTargetController(true);
    drawer.addController(mouseTargetCntrl);
    mouseTargetCntrl.addQTMouseListener(
        new DragAction(new TranslateMatrix()) {

          // only activates when kJavaAltMask modifiers are pressed
          public boolean matchModifierFilter(int mods) {
            if ((mods & 0xF) == QTConstants.kJavaAltMask) return true;
            return false;
          }

          public void mouseClicked(QTMouseEvent event) {
            super.mouseClicked(event);

            Object target = event.getTarget();
            Object source = event.getSource();
            GroupDrawable groupdrawer = (GroupDrawable) mouseTargetCntrl.getSpace();
            int layer = groupdrawer.getBackLayer();

            if (source instanceof DirectGroup
                && target instanceof QTDrawable
                && // make sure source and target are correct types
                ((DirectGroup) source).isAppropriate(target)) {
              try {
                ((DirectGroup) source).setMemberLayer((QTDrawable) target, layer + 1);
              } catch (QTException e) {
                QTRuntimeException.handleOrThrow(new QTRuntimeException(e), this, "mousePressed");
              }
            }
          }
        });

    myQTCanvas.setClient(drawer, true);

    shipAnimation.getTimer().setRate(1);
    drawer.getTimer().setRate(1);
  }
 private static ImagePresenter makeImagePresenter(QTFile file, QDRect size) throws Exception {
   GraphicsImporterDrawer gid = new GraphicsImporterDrawer(file);
   gid.setDisplayBounds(size);
   return ImagePresenter.fromGraphicsImporterDrawer(gid);
 }