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(); }
protected void invalidate() { // Retrieve current bounds and set local vars Rectangle2D tmp = graph.getCellBounds(vertex.getCell()); if (tmp != null) { tmp = (Rectangle2D) tmp.clone(); graph.toScreen(tmp); int handlesize = graph.getHandleSize(); int s2 = 2 * handlesize; double left = tmp.getX() - handlesize; double top = tmp.getY() - handlesize; double w2 = tmp.getX() + (tmp.getWidth() / 2) - handlesize; double h2 = tmp.getY() + (tmp.getHeight() / 2) - handlesize; double right = tmp.getX() + tmp.getWidth() - handlesize; double bottom = tmp.getY() + tmp.getHeight() - handlesize; // Update control point positions r[0].setFrame(left, top, s2, s2); r[1].setFrame(w2, top, s2, s2); r[2].setFrame(right, top, s2, s2); r[3].setFrame(left, h2, s2, s2); r[4].setFrame(right, h2, s2, s2); r[5].setFrame(left, bottom, s2, s2); r[6].setFrame(w2, bottom, s2, s2); r[7].setFrame(right, bottom, s2, s2); } }
/** * Creates a <code>VertexView</code> for the given cell, which is expected to be for a vertex in * the graph. If the cell is a type we are expecting and it holds a user object that we know how * to handle, we determine if a custom renderer has been registered with us for that cell type. If * no custom view is found, we fall back on the superclass version of this method. * * @return An instance of <code>VertexView</code> (or a subclass thereof) for the given cell. * @see org.jgraph.graph.VertexView * @see org.jgraph.graph.DefaultCellViewFactory#createVertexView(Object) */ protected VertexView createVertexView(Object cell) { VertexView view = null; // Right now, we expect that vertex cells are instances of // DefaultGraphCell (or some subclass thereof) and that they contain a // user object of type ConfigElementHolder (or some subclass thereof). // This is not inifinitely flexible, but considering the purpose of the // devicegraph package, it is a reasonable assumption. if (cell instanceof DefaultGraphCell && ((DefaultGraphCell) cell).getUserObject() instanceof ConfigElementHolder) { // Extract the user object which we know to be an instance of // ConfigElementHolder. ConfigElementHolder holder = (ConfigElementHolder) ((DefaultGraphCell) cell).getUserObject(); // Look up the config definition for the held ConfigElement and check // to see if a VertexView was registered with us for that definition. ConfigElement elt = holder.getElement(); ConfigDefinition def = elt.getDefinition(); Class view_class = (Class) mCreatorMap.get(def); // If a VertexView for the cell's config definition was registered // with us, try to instantiate and use that view for the given // cell. if (null != view_class) { try { view = (VertexView) view_class.newInstance(); view.setCell(cell); } // If we catch an exception trying to instantiate the custom // VertexView type, ignore it and leave view set to null. catch (Exception e) { e.printStackTrace(); } } } // If we have no custom view at this point, use the JGraph version of // createVertexView() to get a default view for the given cell. if (null == view) { view = super.createVertexView(cell); } return view; }
// 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 pressed event. */ public void mousePressed(MouseEvent event) { if (!graph.isSizeable()) return; for (int i = 0; i < r.length; i++) { if (r[i].contains(event.getPoint()) && cursors[i] != 0) { Set set = new HashSet(); set.add(vertex.getCell()); contextViews = context.createTemporaryContextViews(set); Object[] all = AbstractCellView.getDescendantViews(new CellView[] {vertex}); if (all.length >= org.jgraph.plaf.basic.BasicGraphUI.MAXHANDLES) cachedBounds = (Rectangle2D) initialBounds.clone(); event.consume(); index = i; return; } } }
protected Rectangle2D computeBounds(MouseEvent event) { double left = initialBounds.getX(); double right = initialBounds.getX() + initialBounds.getWidth() - 1; double top = initialBounds.getY(); double bottom = initialBounds.getY() + initialBounds.getHeight() - 1; Point2D p = graph.fromScreen(graph.snap((Point2D) event.getPoint().clone())); // Not into negative coordinates p.setLocation(Math.max(0, p.getX()), Math.max(0, p.getY())); // Bottom row if (index > 4) bottom = p.getY(); // Top row else if (index < 3) top = p.getY(); // Left col if (index == 0 || index == 3 || index == 5) left = p.getX(); // Right col else if (index == 2 || index == 4 || index == 7) right = p.getX(); double width = right - left; double height = bottom - top; if (isConstrainedSizeEvent(event) || GraphConstants.isConstrained(vertex.getAllAttributes())) { if (index == 3 || index == 4 || index == 5) height = width; else if (index == 1 || index == 6 || index == 2 || index == 7) width = height; else { height = width; top = bottom - height; } } if (width < 0) { // Flip over left side left += width; width = Math.abs(width); } if (height < 0) { // Flip over top side top += height; height = Math.abs(height); } return new Rectangle2D.Double(left, top, width + 1, height + 1); }
/** 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()); } } }