package com.vci.client.workflow.editor; import java.awt.Color; import java.awt.Point; import java.awt.Rectangle; import java.awt.image.BufferedImage; import com.mxgraph.canvas.mxGraphics2DCanvas; import com.mxgraph.canvas.mxICanvas; import com.mxgraph.canvas.mxImageCanvas; import com.mxgraph.util.mxPoint; import com.mxgraph.util.mxRectangle; import com.mxgraph.view.mxGraph; import com.mxgraph.view.mxGraphView; import com.mxgraph.view.mxTemporaryCellStates; public class FlowCellRenderer { // static class, 参照 mxCellRenderer class /** * Draws the given cells using a Graphics2D canvas and returns the buffered image * that represents the cells. * * @param graph Graph to be painted onto the canvas. * @return Returns the image that represents the canvas. */ public static mxICanvas drawCells(mxGraph graph, Object[] cells, double scale, CanvasFactory factory) { mxICanvas canvas = null; if (cells == null) { cells = new Object[] { graph.getModel().getRoot() }; } // Gets the current state of the view mxGraphView view = graph.getView(); // Keeps the existing translation as the cells might // be aligned to the grid in a different way in a graph // that has a translation other than zero boolean eventsEnabled = view.isEventsEnabled(); // Disables firing of scale events so that there is no // repaint or update of the original graph view.setEventsEnabled(false); // Uses the view to create temporary cell states for each cell mxTemporaryCellStates temp = new mxTemporaryCellStates(view, scale, cells); try { mxRectangle clip = graph.getPaintBounds(cells); //将clip扩展到左上角(0, 0) clip.setWidth(clip.getWidth() + clip.getX()); clip.setHeight(clip.getHeight() + clip.getY()); clip.setX(0); clip.setY(0); if (clip != null && clip.getWidth() > 0 && clip.getHeight() > 0) { Rectangle rect = clip.getRectangle(); canvas = factory.createCanvas(rect.width + 4, rect.height + 4);//增加一点富裕空间 if (canvas != null) { double previousScale = canvas.getScale(); //mxPoint previousTranslate = canvas.getTranslate(); Point previousTranslate = canvas.getTranslate(); try { // canvas.setTranslate(-rect.x, -rect.y); canvas.setScale(view.getScale()); for (int i = 0; i < cells.length; i++) { graph.drawCell(canvas, cells[i]); } } finally { canvas.setScale(previousScale); canvas.setTranslate(previousTranslate.x, previousTranslate.y); } } } } finally { temp.destroy(); view.setEventsEnabled(eventsEnabled); } return canvas; } /** * */ public static BufferedImage createBufferedImage(mxGraph graph, Object[] cells, double scale, final Color background, final boolean antiAlias, final mxGraphics2DCanvas graphicsCanvas) { mxImageCanvas canvas = (mxImageCanvas) drawCells(graph, cells, scale, new CanvasFactory() { public mxICanvas createCanvas(int width, int height) { return new mxImageCanvas(graphicsCanvas, width, height, background, antiAlias); } }); return (canvas != null) ? canvas.destroy() : null; } /** * */ public static abstract class CanvasFactory { /** * Separates the creation of the canvas from its initialization, when the * size of the required graphics buffer / document / container is known. */ public abstract mxICanvas createCanvas(int width, int height); } }