// Dispatch the edit event
 public void mouseReleased(MouseEvent e) {
   if (index != -1) {
     cachedBounds = computeBounds(e);
     vertex.setBounds(cachedBounds);
     CellView[] views = AbstractCellView.getDescendantViews(new CellView[] {vertex});
     Map attributes = GraphConstants.createAttributes(views, null);
     graph.getGraphLayoutCache().edit(attributes, null, null, null);
   }
   e.consume();
   cachedBounds = null;
   initialBounds = null;
   firstDrag = true;
 }
 /** Process mouse dragged event. */
 public void mouseDragged(MouseEvent event) {
   if (firstDrag && graph.isDoubleBuffered() && cachedBounds == null) {
     initOffscreen();
     firstDrag = false;
   }
   Rectangle2D dirty = null;
   Graphics g = (offgraphics != null) ? offgraphics : graph.getGraphics();
   if (index == -1) return;
   if (offgraphics != null || !graph.isXorEnabled()) {
     dirty = graph.toScreen((Rectangle2D) vertex.getBounds().clone());
     Rectangle2D t = graph.toScreen(AbstractCellView.getBounds(contextViews));
     if (t != null) dirty.add(t);
   }
   Rectangle2D newBounds = computeBounds(event);
   if (graph.isXorEnabled()) {
     g.setColor(graph.getForeground());
     g.setXORMode(graph.getBackground().darker());
     overlay(g);
   } else {
     firstOverlayInvocation = false;
   }
   if (cachedBounds != null) cachedBounds = newBounds;
   else {
     // Reset old Bounds
     CellView[] all = AbstractCellView.getDescendantViews(new CellView[] {vertex});
     for (int i = 0; i < all.length; i++) {
       CellView orig = graph.getGraphLayoutCache().getMapping(all[i].getCell(), false);
       if (orig != null) {
         AttributeMap origAttr = (AttributeMap) orig.getAllAttributes().clone();
         all[i].changeAttributes(graph.getGraphLayoutCache(), origAttr);
         all[i].refresh(graph.getGraphLayoutCache(), context, false);
       }
     }
     vertex.setBounds(newBounds);
     if (vertex != null) graph.getGraphLayoutCache().update(vertex);
     if (contextViews != null) graph.getGraphLayoutCache().update(contextViews);
   }
   if (graph.isXorEnabled()) {
     overlay(g);
   }
   if (offgraphics != null || !graph.isXorEnabled()) {
     dirty.add(graph.toScreen((Rectangle2D) vertex.getBounds().clone()));
     Rectangle2D t = graph.toScreen(AbstractCellView.getBounds(contextViews));
     if (t != null) dirty.add(t);
     int border = PortView.SIZE + 10;
     if (graph.isPortsScaled()) border = (int) (graph.getScale() * border);
     int border2 = border / 2;
     dirty.setFrame(
         dirty.getX() - border2,
         dirty.getY() - border2,
         dirty.getWidth() + border,
         dirty.getHeight() + border);
     double sx1 = Math.max(0, dirty.getX());
     double sy1 = Math.max(0, dirty.getY());
     double sx2 = sx1 + dirty.getWidth();
     double sy2 = sy1 + dirty.getHeight();
     if (offgraphics != null) {
       graph.drawImage(
           (int) sx1, (int) sy1, (int) sx2, (int) sy2, (int) sx1, (int) sy1, (int) sx2,
           (int) sy2);
     } else {
       graph.repaint(
           (int) dirty.getX(),
           (int) dirty.getY(),
           (int) dirty.getWidth(),
           (int) dirty.getHeight());
     }
   }
 }