📄 mxgraphics2dcanvas.java
字号:
* @param pts List of points that define the line. */ protected void drawConnector(List pts, float penWidth, Color penColor, Object startMarker, float startSize, Object endMarker, float endSize, boolean dashed, boolean rounded) { g.setStroke(new BasicStroke((float) (penWidth * scale))); g.setColor(penColor); // Draws the start marker mxPoint p0 = (mxPoint) pts.get(0); mxPoint pt = (mxPoint) pts.get(1); mxPoint offset = null; if (startMarker != null) { offset = drawMarker(startMarker, pt, p0, startSize, penWidth); } else { double dx = pt.getX() - p0.getX(); double dy = pt.getY() - p0.getY(); double dist = Math.max(1, Math.sqrt(dx * dx + dy * dy)); double nx = dx * penWidth * scale / dist; double ny = dy * penWidth * scale / dist; offset = new mxPoint(nx / 2, ny / 2); } // Applies offset to the point if (offset != null) { p0 = (mxPoint) p0.clone(); p0.setX(p0.getX() + offset.getX()); p0.setY(p0.getY() + offset.getY()); offset = null; } // Draws the end marker mxPoint pe = (mxPoint) pts.get(pts.size() - 1); pt = (mxPoint) pts.get(pts.size() - 2); if (endMarker != null) { offset = drawMarker(endMarker, pt, pe, endSize, penWidth); } else { double dx = pt.getX() - p0.getX(); double dy = pt.getY() - p0.getY(); double dist = Math.max(1, Math.sqrt(dx * dx + dy * dy)); double nx = dx * penWidth * scale / dist; double ny = dy * penWidth * scale / dist; offset = new mxPoint(nx / 2, ny / 2); } // Applies offset to the point if (offset != null) { pe = (mxPoint) pe.clone(); pe.setX(pe.getX() + offset.getX()); pe.setY(pe.getY() + offset.getY()); offset = null; } if (dashed) { g.setStroke(new BasicStroke(penWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] { (float) (3 * scale), (float) (3 * scale) }, 0.0f)); } // Draws the line segments double arcSize = 10 * scale; pt = p0; for (int i = 1; i < pts.size() - 1; i++) { mxPoint tmp = (mxPoint) pts.get(i); double dx = pt.getX() - tmp.getX(); double dy = pt.getY() - tmp.getY(); if ((rounded && i < pts.size() - 1) && (dx != 0 || dy != 0) && scale > 0.05) { // Draws a line from the last point // to the current point with a spacing // of size off the current point into // direction of the last point double dist = Math.sqrt(dx * dx + dy * dy); double nx1 = dx * Math.min(arcSize, dist / 2) / dist; double ny1 = dy * Math.min(arcSize, dist / 2) / dist; drawLine((int) Math.round(pt.getX()), (int) Math.round(pt .getY()), (int) Math.round(tmp.getX() + nx1), (int) Math.round(tmp.getY() + ny1)); // Draws a curve from the last point // to the current point with a spacing // of size off the current point into // direction of the next point mxPoint next = (mxPoint) pts.get(i + 1); dx = next.getX() - tmp.getX(); dy = next.getY() - tmp.getY(); dist = Math.max(1, Math.sqrt(dx * dx + dy * dy)); double nx2 = dx * Math.min(arcSize, dist / 2) / dist; double ny2 = dy * Math.min(arcSize, dist / 2) / dist; QuadCurve2D.Float curve = new QuadCurve2D.Float((int) Math .round(tmp.getX() + nx1), (int) Math.round(tmp.getY() + ny1), (int) Math.round(tmp.getX()), (int) Math .round(tmp.getY()), (int) Math.round(tmp.getX() + nx2), (int) Math.round(tmp.getY() + ny2)); Rectangle bounds = curve.getBounds(); int sw = (int) Math.ceil(penWidth * scale); bounds.grow(sw, sw); if (g.getClipBounds() == null || g.getClipBounds().intersects(bounds)) { g.draw(curve); } tmp = new mxPoint(tmp.getX() + nx2, tmp.getY() + ny2); } else { drawLine((int) Math.round(pt.getX()), (int) Math.round(pt .getY()), (int) Math.round(tmp.getX()), (int) Math .round(tmp.getY())); } pt = tmp; } drawLine((int) Math.round(pt.getX()), (int) Math.round(pt.getY()), (int) Math.round(pe.getX()), (int) Math.round(pe.getY())); } /** * * @param fillColor * @param style * @return Returns the paint to be used for filling. */ protected Paint getFillPaint(Rectangle bounds, Color fillColor, Hashtable style) { Paint fillPaint = null; if (fillColor != null) { Color gradientColor = mxUtils.getColor(style, mxConstants.STYLE_GRADIENTCOLOR); if (gradientColor != null) { String gradientDirection = mxUtils.getString(style, mxConstants.STYLE_GRADIENT_DIRECTION); float x1 = bounds.x; float y1 = bounds.y; float x2 = bounds.x; float y2 = bounds.y; if (gradientDirection == null || gradientDirection .equals(mxConstants.DIRECTION_SOUTH)) { y2 = bounds.y + bounds.height; } else if (gradientDirection.equals(mxConstants.DIRECTION_EAST)) { x2 = bounds.x + bounds.width; } else if (gradientDirection.equals(mxConstants.DIRECTION_NORTH)) { y1 = bounds.y + bounds.height; } else if (gradientDirection.equals(mxConstants.DIRECTION_WEST)) { x1 = bounds.x + bounds.width; } fillPaint = new GradientPaint(x1, y1, fillColor, x2, y2, gradientColor, true); } } return fillPaint; } /** * Draws the given lines as segments between all points of the given list * of mxPoints. * * @param pts List of points that define the line. * @param style Style to be used for painting the line. */ public void drawLine(List pts, Hashtable style) { Color penColor = mxUtils.getColor(style, mxConstants.STYLE_STROKECOLOR, Color.black); float penWidth = mxUtils.getFloat(style, mxConstants.STYLE_STROKEWIDTH, 1); if (penColor != null && penWidth > 0) { // Draws the shape String shape = mxUtils .getString(style, mxConstants.STYLE_SHAPE, ""); if (shape.equals(mxConstants.SHAPE_ARROW)) { if (mxUtils.isTrue(style, mxConstants.STYLE_DASHED, false)) { g.setStroke(new BasicStroke((float) (penWidth * scale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] { (float) (3 * scale), (float) (3 * scale) }, 0.0f)); } else { g.setStroke(new BasicStroke((float) (penWidth * scale))); } // Base vector (between end points) mxPoint p0 = (mxPoint) pts.get(0); mxPoint pe = (mxPoint) pts.get(pts.size() - 1); Rectangle bounds = new Rectangle(p0.getPoint()); bounds.add(pe.getPoint()); Color fillColor = mxUtils.getColor(style, mxConstants.STYLE_FILLCOLOR); Paint fillPaint = getFillPaint(bounds, fillColor, style); boolean shadow = mxUtils.isTrue(style, mxConstants.STYLE_SHADOW, false); drawArrow(pts, fillColor, fillPaint, penColor, shadow); } else { Object startMarker = style.get(mxConstants.STYLE_STARTARROW); Object endMarker = style.get(mxConstants.STYLE_ENDARROW); float startSize = (float) (mxUtils.getFloat(style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_MARKERSIZE)); float endSize = (float) (mxUtils.getFloat(style, mxConstants.STYLE_ENDSIZE, mxConstants.DEFAULT_MARKERSIZE)); boolean rounded = mxUtils.isTrue(style, mxConstants.STYLE_ROUNDED, false); boolean dashed = mxUtils.isTrue(style, mxConstants.STYLE_DASHED, false); drawConnector(pts, penWidth, penColor, startMarker, startSize, endMarker, endSize, dashed, rounded); } } } /** * Draws the given line if the line is inside the clipping area. This * method assumes that the stroke on the graphics object is already set. */ public void drawLine(int x0, int y0, int x1, int y1) { Line2D line = new Line2D.Float(x0, y0, x1, y1); if (g.getClipBounds() == null || line.intersects(g.getClipBounds())) { g.draw(line); } } /** * Draws the given type of marker. * * @param type * @param p0 * @param pe * @param size * @param strokeWidth * @return Return the mxPoint that defines the offset. */ public mxPoint drawMarker(Object type, mxPoint p0, mxPoint pe, float size, float strokeWidth) { mxPoint offset = null; // Computes the norm and the inverse norm double dx = pe.getX() - p0.getX(); double dy = pe.getY() - p0.getY(); double dist = Math.max(1, Math.sqrt(dx * dx + dy * dy)); double absSize = size * scale; double nx = dx * absSize / dist; double ny = dy * absSize / dist; pe = (mxPoint) pe.clone(); pe.setX(pe.getX() - nx * strokeWidth / (2 * size)); pe.setY(pe.getY() - ny * strokeWidth / (2 * size)); nx *= 0.5 + strokeWidth / 2; ny *= 0.5 + strokeWidth / 2; if (type.equals(mxConstants.ARROW_CLASSIC) || type.equals(mxConstants.ARROW_BLOCK)) { Polygon poly = new Polygon(); poly.addPoint((int) Math.round(pe.getX()), (int) Math.round(pe .getY())); poly.addPoint((int) Math.round(pe.getX() - nx - ny / 2), (int) Math .round(pe.getY() - ny + nx / 2)); if (type.equals(mxConstants.ARROW_CLASSIC)) { poly.addPoint((int) Math.round(pe.getX() - nx * 3 / 4), (int) Math.round(pe.getY() - ny * 3 / 4)); } poly.addPoint((int) Math.round(pe.getX() + ny / 2 - nx), (int) Math .round(pe.getY() - ny - nx / 2)); if (g.getClipBounds() == null || g.getClipBounds().intersects(poly.getBounds())) { g.fillPolygon(poly); g.drawPolygon(poly); } offset = new mxPoint(-nx * 3 / 4, -ny * 3 / 4); } else if (type.equals(mxConstants.ARROW_OPEN)) { nx *= 1.2; ny *= 1.2; drawLine((int) Math.round(pe.getX() - nx - ny / 2), (int) Math .round(pe.getY() - ny + nx / 2), (int) Math.round(pe.getX() - nx / 6), (int) Math.round(pe.getY() - ny / 6)); drawLine((int) Math.round(pe.getX() - nx / 6), (int) Math.round(pe .getY() - ny / 6), (int) Math.round(pe.getX() + ny / 2 - nx), (int) Math.round(pe.getY() - ny - nx / 2)); offset = new mxPoint(-nx / 4, -ny / 4); } else if (type.equals(mxConstants.ARROW_OVAL)) { nx *= 1.2; ny *= 1.2; absSize *= 1.2; int cx = (int) Math.round(pe.getX() - nx / 2); int cy = (int) Math.round(pe.getY() - ny / 2); int a = (int) Math.round(absSize / 2); int a2 = (int) Math.round(absSize); if (g.hitClip(cx - a, cy - a, a2, a2)) { g.fillOval(cx - a, cy - a, a2, a2); g.drawOval(cx - a, cy - a, a2, a2); } offset = new mxPoint(-nx / 2, -ny / 2); } else if (type.equals(mxConstants.ARROW_DIAMOND)) { nx *= 1.2; ny *= 1.2; Polygon poly = new Polygon(); poly.addPoint((int) Math.round(pe.getX() + nx / 2), (int) Math .round(pe.getY() + ny / 2)); poly.addPoint((int) Math.round(pe.getX() - ny / 2), (int) Math .round(pe.getY() + nx / 2)); poly.addPoint((int) Math.round(pe.getX() - nx / 2), (int) Math .round(pe.getY() - ny / 2)); poly.addPoint((int) Math.round(pe.getX() + ny / 2), (int) Math .round(pe.getY() - nx / 2)); if (g.getClipBounds() == null || g.getClipBounds().intersects(poly.getBounds())) { g.fillPolygon(poly); g.drawPolygon(poly); } } return offset; } /** * Draws the specified HTML markup. * * @param text HTML markup to be painted. * @param x X-coordinate of the text. * @param y Y-coordinate of the text. * @param w Width of the text. * @param h Height of the text. * @param style Style to be used for painting the text. */ protected void drawHtmlText(String text, int x, int y, int w, int h, Hashtable style) { mxLightweightTextPane textRenderer = mxLightweightTextPane .getSharedInstance(); if (textRenderer != null && rendererPane != null) { boolean horizontal = mxUtils.isTrue(style, mxConstants.STYLE_HORIZONTAL, true); if (g.hitClip(x, y, w, h)) { AffineTransform at = g.getTransform(); if (!horizontal) { g.rotate(-Math.PI / 2, x + w / 2, y + h / 2); g.translate(w / 2 - h / 2, h / 2 - w / 2); int tmp = w; w = h; h = tmp; } // Renders the scaled text textRenderer.setStyledDocument(mxUtils .createHtmlDocument(style)); textRenderer.setText(text); g.scale(scale, scale); rendererPane.paintComponent(g, textRenderer, rendererPane, (int) (x / scale) + mxConstants.LABEL_INSET, (int) (y / scale) + mxConstants.LABEL_INSET, (int) (w / scale), (int) (h / scale), true); // Restores the previous transformation g.setTransform(at); } } } /** * Draws the specified string as plain text. * * @param text HTML markup to be painted. * @param x X-coordinate of the text. * @param y Y-coordinate of the text. * @param w Width of the text. * @param h Height of the text. * @param style Style to be used for painting the text. */ protected void drawPlainText(String text, int x, int y, int w, int h, Hashtable style) { if (g.hitClip(x, y, w, h)) { // Stores the original transform AffineTransform at = g.getTransform(); // Rotates the canvas if required boolean horizontal = mxUtils.isTrue(style, mxConstants.STYLE_HORIZONTAL, true); if (!horizontal) { g.rotate(-Math.PI / 2, x + w / 2, y + h / 2); g.translate(w / 2 - h / 2, h / 2 - w / 2); } // Shifts the y-coordinate down by the ascent plus a workaround // for the line not starting at the exact vertical location FontMetrics fm = g.getFontMetrics(); y += 2 * fm.getMaxAscent() - fm.getHeight() + mxConstants.LABEL_INSET * scale; // Gets the alignment settings Object align = mxUtils.getString(style, mxConstants.STYLE_ALIGN, mxConstants.ALIGN_CENTER); if (align.equals(mxConstants.ALIGN_LEFT)) { x += mxConstants.LABEL_INSET; } else if (align.equals(mxConstants.ALIGN_RIGHT)) { x -= mxConstants.LABEL_INSET; } // Sets the color Color fontColor = mxUtils.getColor(style, mxConstants.STYLE_FONTCOLOR, Color.black); g.setColor(fontColor); // Draws the text line by line String[] lines = text.split("\n"); for (int i = 0; i < lines.length; i++) { int dx = 0; if (align.equals(mxConstants.ALIGN_CENTER)) { int sw = fm.stringWidth(lines[i]); if (horizontal) { dx = (w - sw) / 2; } else { dx = (h - sw) / 2; } } else if (align.equals(mxConstants.ALIGN_RIGHT)) { int sw = fm.stringWidth(lines[i]); dx = ((horizontal) ? w : h) - sw; } g.drawString(lines[i], x + dx, y); y += fm.getHeight() + mxConstants.LINESPACING; } // Resets the transformation g.setTransform(at); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -