public void overlay(Graphics g) {
   if (!firstOverlayInvocation) {
     if (cachedBounds != null) {
       g.setColor(Color.black);
       Rectangle2D tmp = graph.toScreen((Rectangle2D) cachedBounds.clone());
       g.drawRect(
           (int) tmp.getX(),
           (int) tmp.getY(),
           (int) tmp.getWidth() - 2,
           (int) tmp.getHeight() - 2);
     } else if (!initialBounds.equals(vertex.getBounds())) {
       Graphics2D g2 = (Graphics2D) g;
       AffineTransform oldTransform = g2.getTransform();
       g2.scale(graph.getScale(), graph.getScale());
       graph.getUI().paintCell(g, vertex, vertex.getBounds(), true);
       if (contextViews != null) {
         for (int i = 0; i < contextViews.length; i++) {
           graph.getUI().paintCell(g, contextViews[i], contextViews[i].getBounds(), true);
         }
       }
       if (!graph.isPortsScaled()) g2.setTransform(oldTransform);
       if (portViews != null && graph.isPortsVisible()) graph.getUI().paintPorts(g, portViews);
       g2.setTransform(oldTransform);
     }
   }
   firstOverlayInvocation = false;
 }
 public SizeHandle(VertexView vertexview, GraphContext ctx) {
   graph = ctx.getGraph();
   vertex = vertexview;
   editing = graph.getEditingCell() == vertex.getCell();
   int sizeableAxis = GraphConstants.getSizeableAxis(vertex.getAllAttributes());
   if (sizeableAxis == GraphConstants.X_AXIS) cursors = xCursors;
   else if (sizeableAxis == GraphConstants.Y_AXIS) cursors = yCursors;
   else cursors = defaultCursors;
   // PortView Preview
   portViews = ctx.createTemporaryPortViews();
   initialBounds = (Rectangle2D) vertex.getBounds().clone();
   context = ctx;
   for (int i = 0; i < r.length; i++) r[i] = new Rectangle2D.Double();
   invalidate();
 }
 /** 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());
     }
   }
 }