public void flipHandleIfNeeded(boolean flipX, boolean flipY) {
    PBoundsLocator l = (PBoundsLocator) getLocator();

    if (flipX || flipY) {
      switch (l.getSide()) {
        case SwingConstants.NORTH:
          {
            if (flipY) {
              l.setSide(SwingConstants.SOUTH);
            }
            break;
          }

        case SwingConstants.SOUTH:
          {
            if (flipY) {
              l.setSide(SwingConstants.NORTH);
            }
            break;
          }

        case SwingConstants.EAST:
          {
            if (flipX) {
              l.setSide(SwingConstants.WEST);
            }
            break;
          }

        case SwingConstants.WEST:
          {
            if (flipX) {
              l.setSide(SwingConstants.EAST);
            }
            break;
          }

        case SwingConstants.NORTH_WEST:
          {
            if (flipX && flipY) {
              l.setSide(SwingConstants.SOUTH_EAST);
            } else if (flipX) {
              l.setSide(SwingConstants.NORTH_EAST);
            } else if (flipY) {
              l.setSide(SwingConstants.SOUTH_WEST);
            }

            break;
          }

        case SwingConstants.SOUTH_WEST:
          {
            if (flipX && flipY) {
              l.setSide(SwingConstants.NORTH_EAST);
            } else if (flipX) {
              l.setSide(SwingConstants.SOUTH_EAST);
            } else if (flipY) {
              l.setSide(SwingConstants.NORTH_WEST);
            }
            break;
          }

        case SwingConstants.NORTH_EAST:
          {
            if (flipX && flipY) {
              l.setSide(SwingConstants.SOUTH_WEST);
            } else if (flipX) {
              l.setSide(SwingConstants.NORTH_WEST);
            } else if (flipY) {
              l.setSide(SwingConstants.SOUTH_EAST);
            }
            break;
          }

        case SwingConstants.SOUTH_EAST:
          {
            if (flipX && flipY) {
              l.setSide(SwingConstants.NORTH_WEST);
            } else if (flipX) {
              l.setSide(SwingConstants.SOUTH_WEST);
            } else if (flipY) {
              l.setSide(SwingConstants.NORTH_EAST);
            }
            break;
          }
      }
    }

    // reset locator to update layout
    setLocator(l);
  }
  public void dragHandle(PDimension aLocalDimension, PInputEvent aEvent) {
    PBoundsLocator l = (PBoundsLocator) getLocator();

    PNode n = l.getNode();
    PBounds b = n.getBounds();

    PNode parent = getParent();
    if (parent != n && parent instanceof PCamera) {
      ((PCamera) parent).localToView(aLocalDimension);
    }

    localToGlobal(aLocalDimension);
    n.globalToLocal(aLocalDimension);

    double dx = aLocalDimension.getWidth();
    double dy = aLocalDimension.getHeight();

    switch (l.getSide()) {
      case SwingConstants.NORTH:
        b.setRect(b.x, b.y + dy, b.width, b.height - dy);
        break;

      case SwingConstants.SOUTH:
        b.setRect(b.x, b.y, b.width, b.height + dy);
        break;

      case SwingConstants.EAST:
        b.setRect(b.x, b.y, b.width + dx, b.height);
        break;

      case SwingConstants.WEST:
        b.setRect(b.x + dx, b.y, b.width - dx, b.height);
        break;

      case SwingConstants.NORTH_WEST:
        b.setRect(b.x + dx, b.y + dy, b.width - dx, b.height - dy);
        break;

      case SwingConstants.SOUTH_WEST:
        b.setRect(b.x + dx, b.y, b.width - dx, b.height + dy);
        break;

      case SwingConstants.NORTH_EAST:
        b.setRect(b.x, b.y + dy, b.width + dx, b.height - dy);
        break;

      case SwingConstants.SOUTH_EAST:
        b.setRect(b.x, b.y, b.width + dx, b.height + dy);
        break;
    }

    boolean flipX = false;
    boolean flipY = false;

    if (b.width < 0) {
      flipX = true;
      b.width = -b.width;
      b.x -= b.width;
    }

    if (b.height < 0) {
      flipY = true;
      b.height = -b.height;
      b.y -= b.height;
    }

    if (flipX || flipY) {
      flipSiblingBoundsHandles(flipX, flipY);
    }

    n.setBounds(b);
  }