/** The mouse was dragged - either draw a marquee or move some classes. */
  public void mouseDragged(MouseEvent evt) {
    if (isButtonOne(evt)) {
      if (marquee.isActive()) {
        Rectangle oldRect = marquee.getRectangle();
        marquee.move(evt.getX(), evt.getY());
        Rectangle newRect = (Rectangle) marquee.getRectangle().clone();
        if (oldRect != null) {
          newRect.add(oldRect);
        }
        newRect.width++;
        newRect.height++;
        graphEditor.repaint(newRect);
      } else if (rubberBand != null) {
        rubberBand.setEnd(evt.getX(), evt.getY());
        graphEditor.repaint();
      } else {
        if (!selection.isEmpty()) {
          int deltaX = snapToGrid(evt.getX() - dragStartX);
          int deltaY = snapToGrid(evt.getY() - dragStartY);

          if (resizing) {
            selection.resize(deltaX, deltaY);
          } else if (moving) {
            selection.move(deltaX, deltaY);
          }
        }
        graphEditor.repaint();
      }
    }
  }
 /** A key was released. Check whether a key-based move or resize operation has ended. */
 public void keyReleased(KeyEvent evt) {
   if (moving && (!evt.isShiftDown())) { // key-based moving stopped
     selection.moveStopped();
     moving = false;
   } else if (resizing && (!evt.isControlDown())) { // key-based moving stopped
     selection.moveStopped();
     resizing = false;
   }
   graphEditor.repaint();
 }
  /** A key was pressed in the graph editor. */
  public void keyPressed(KeyEvent evt) {
    boolean handled = true; // assume for a start that we are handling the
    // key here

    if (isArrowKey(evt)) {
      if (evt.isControlDown()) { // resizing
        if (!resizing) startKeyboardResize();
        setKeyDelta(evt);
        selection.resize(keyDeltaX, keyDeltaY);
      } else if (evt.isShiftDown()) { // moving targets
        if (!moving) startKeyboardMove();
        setKeyDelta(evt);
        selection.move(keyDeltaX, keyDeltaY);
      } else { // navigate the diagram
        navigate(evt);
      }
    } else if (isPlusOrMinusKey(evt)) {
      resizeWithFixedRatio(evt);
    }

    // dependency selection
    else if (evt.getKeyCode() == KeyEvent.VK_PAGE_UP || evt.getKeyCode() == KeyEvent.VK_PAGE_DOWN) {
      selectDependency(evt);
    }

    // post context menu
    else if (evt.getKeyCode() == KeyEvent.VK_SPACE || evt.getKeyCode() == KeyEvent.VK_ENTER) {
      postMenu();
    }

    // 'A' (with any or no modifiers) selects all
    else if (evt.getKeyCode() == KeyEvent.VK_A) {
      selectAll();
    }

    // Escape removes selections
    else if (evt.getKeyCode() == KeyEvent.VK_ESCAPE) {
      if (moving || resizing) {
        endMove();
      }
      clearSelection();
    } else {
      handled = false;
    }

    if (handled) evt.consume();

    graphEditor.repaint();
  }
 /**
  * A mouse-clicked event. This is only interesting if it was a double click. If so, inform every
  * element in the current selection.
  */
 public void mouseClicked(MouseEvent evt) {
   if (isButtonOne(evt)) {
     if (evt.getClickCount() > 1) {
       selection.doubleClick(evt);
     }
   }
 }
  private Vertex findSingleVertex() {
    Vertex vertex = selection.getAnyVertex();

    // if there is no selection we select an existing vertex
    if (vertex == null) {
      vertex = (Vertex) graph.getVertices().next();
    }
    return vertex;
  }
  /** A mouse-pressed event. Analyse what we should do with it. */
  public void mousePressed(MouseEvent evt) {
    graphEditor.requestFocus();
    int clickX = evt.getX();
    int clickY = evt.getY();

    SelectableGraphElement clickedElement = graph.findGraphElement(clickX, clickY);
    notifyPackage(clickedElement);

    if (clickedElement == null) { // nothing hit
      if (!isMultiselectionKeyDown(evt)) {
        selection.clear();
      }
      if (isButtonOne(evt)) marquee.start(clickX, clickY);
    } else if (isButtonOne(evt)) { // clicked on something
      if (isMultiselectionKeyDown(evt)) {
        // a class was clicked, while multiselectionKey was down.
        if (clickedElement.isSelected()) {
          selection.remove(clickedElement);
        } else {
          selection.add(clickedElement);
        }
      } else {
        // a class was clicked without multiselection
        if (!clickedElement.isSelected()) {
          selection.selectOnly(clickedElement);
        }
      }

      if (isDrawingDependency()) {
        if (clickedElement instanceof Target)
          rubberBand = new RubberBand(clickX, clickY, clickX, clickY);
      } else {
        dragStartX = clickX;
        dragStartY = clickY;

        if (clickedElement.isHandle(clickX, clickY)) {
          resizing = true;
        } else {
          moving = true;
        }
      }
    }
  }
 /**
  * Post the context menu of one selected element of the current selection. If any dependencies are
  * selected, show the menu for one of those. Otherwise show the menu for a randomly chosen target.
  */
 private void postMenu() {
   // first check whether we have selected edges
   Dependency dependency = (Dependency) selection.getAnyEdge();
   if (dependency != null) {
     Point p =
         ((GraphPainterStdImpl) GraphPainterStdImpl.getInstance())
             .getDependencyPainter(dependency)
             .getPopupMenuPosition(dependency);
     postMenu(dependency, p.x, p.y);
   } else {
     // if not, choose a target
     Vertex vertex = selection.getAnyVertex();
     if (vertex != null) {
       selection.selectOnly(vertex);
       int x = vertex.getX() + vertex.getWidth() - 20;
       int y = vertex.getY() + 20;
       postMenu(vertex, x, y);
     }
   }
 }
  private void selectDependency(KeyEvent evt) {
    Vertex vertex = selection.getAnyVertex();
    if (vertex != null && vertex instanceof DependentTarget) {
      selection.selectOnly(vertex);
      List<Dependency> dependencies = ((DependentTarget) vertex).dependentsAsList();

      Dependency currentDependency = dependencies.get(currentDependencyIndex);
      if (currentDependency != null) {
        selection.remove(currentDependency);
      }
      currentDependencyIndex += (evt.getKeyCode() == KeyEvent.VK_PAGE_UP ? 1 : -1);
      currentDependencyIndex %= dependencies.size();
      if (currentDependencyIndex < 0) { // % is not a real modulo
        currentDependencyIndex = dependencies.size() - 1;
      }
      currentDependency = (Dependency) dependencies.get(currentDependencyIndex);
      if (currentDependency != null) {
        selection.add(currentDependency);
      }
    }
  }
  /** A menu popup trigger has been detected. Handle it. */
  public void handlePopupTrigger(MouseEvent evt) {
    int clickX = evt.getX();
    int clickY = evt.getY();

    SelectableGraphElement clickedElement = graph.findGraphElement(clickX, clickY);
    if (clickedElement != null) {
      selection.selectOnly(clickedElement);
      postMenu(clickedElement, clickX, clickY);
    } else {
      postMenu(clickX, clickY);
    }
  }
  /** The mouse was released. */
  public void mouseReleased(MouseEvent evt) {
    if (isDrawingDependency()) {
      SelectableGraphElement selectedElement = graph.findGraphElement(evt.getX(), evt.getY());
      notifyPackage(selectedElement);
      graphEditor.repaint();
    }
    rubberBand = null;

    SelectionSet newSelection = marquee.stop(); // may or may not have had a marquee...
    if (newSelection != null) {
      selection.addAll(newSelection);
      graphEditor.repaint();
    }

    if (moving || resizing) {
      endMove();
      graphEditor.revalidate();
      graphEditor.repaint();
    }
  }
 /**
  * Add to the current selection
  *
  * @param element
  */
 public void addToSelection(SelectableGraphElement element) {
   selection.add(element);
 }
 /** Clear the current selection. */
 public void removeFromSelection(SelectableGraphElement element) {
   selection.remove(element);
 }
 /** Select all graph vertices. */
 private void selectAll() {
   for (Iterator<? extends Vertex> i = graph.getVertices(); i.hasNext(); ) {
     selection.add(i.next());
   }
 }
 /** Clear the current selection. */
 public void clearSelection() {
   selection.clear();
 }
 /**
  * Move the current selection to another selected class, depending on current selection and the
  * key pressed.
  */
 private void navigate(KeyEvent evt) {
   Vertex currentTarget = findSingleVertex();
   currentTarget = traverseStragegiImpl.findNextVertex(graph, currentTarget, evt.getKeyCode());
   selection.selectOnly(currentTarget);
 }
 /** End a move or resize gesture. */
 private void endMove() {
   selection.moveStopped();
   moving = false;
   resizing = false;
 }
 private void resizeWithFixedRatio(KeyEvent evt) {
   int delta = (evt.getKeyChar() == '+' ? GraphEditor.GRID_SIZE : -GraphEditor.GRID_SIZE);
   selection.resize(delta, delta);
   selection.moveStopped();
 }