/** * Paints the icon. * * @param c the component on which it is painted * @param _g the graphics context * @param x the x coordinate of the icon * @param y the y coordinate of the icon */ public void paintIcon(Component c, Graphics _g, int x, int y) { Graphics2D g = (Graphics2D) _g; AffineTransform at = AffineTransform.getTranslateInstance(x + offsetX, y + offsetY); // save current graphics paint and clip Paint gPaint = g.getPaint(); Shape gClip = g.getClip(); // render shape(s) g.setPaint(color); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.clipRect(x, y, w, h); // paint shape, if any if (shape != null) { g.fill(at.createTransformedShape(shape)); } // paint decoration, if any if (decoration != null) { g.setPaint(decoColor); g.fill(at.createTransformedShape(decoration)); } // restore graphics paint and clip g.setPaint(gPaint); g.setClip(gClip); }
/** * This implementation calls <code>super.hitTest</code> and returns the result if non-null (this * should be a HitInfo.Point), then returns a HitInfo.Interior if the mouse-click occured inside * the text bound (as defined by text layout) * * @return a HitInfo corresponding to the given mouse-event */ public HitInfo hitTest(PEMouseEvent e) { // from Bitmap: if (image != null) { if (getBounds().contains(e.getPicPoint())) { return new HitInfo.Interior((PicText) element, e); } return null; } // from TextLayout: if (!getBounds().contains(e.getPicPoint())) return null; PicText te = (PicText) element; // recompute textlayout b-box, but store it in a temporary field ! Rectangle2D tb = textLayout.getBounds(); Shape text_bounds = text2ModelTr.createTransformedShape(tb); if (text_bounds.contains(e.getPicPoint())) { // [SR:pending] for the hitInfo to be reliable, getPicPoint() should first be transformed by // inverse text2ModelTr ! (especially when rotationAngle != 0) TextHitInfo thi = textLayout.hitTestChar( (float) (e.getPicPoint().x - strx), (float) (e.getPicPoint().y - stry)); // guaranteed to return a non-null thi return new HitInfo.Text((PicText) element, thi, e); } // test hit on textlayout's bounding rectangle : // else if (bounds.contains(e.getPicPoint())) return new HitInfo.Interior(element,e); return null; }
/** * Gets the mark for the specified panel. * * @param trackerPanel the tracker panel * @return the mark */ protected Mark getMark(TrackerPanel trackerPanel) { Mark mark = marks.get(trackerPanel); TPoint selection = null; if (mark == null) { selection = trackerPanel.getSelectedPoint(); Point p = null; valid = true; // assume true for (int n = 0; n < points.length; n++) { if (!valid) continue; // determine if point is valid (ie not NaN) valid = valid && !Double.isNaN(points[n].getX()) && !Double.isNaN(points[n].getY()); screenPoints[n] = points[n].getScreenPosition(trackerPanel); if (valid && selection == points[n]) p = screenPoints[n]; } mark = footprint.getMark(screenPoints); if (p != null) { // point is selected, so draw selection shape transform.setToTranslation(p.x, p.y); int scale = FontSizer.getIntegerFactor(); if (scale > 1) { transform.scale(scale, scale); } final Color color = footprint.getColor(); final Mark stepMark = mark; final Shape selectedShape = transform.createTransformedShape(selectionShape); mark = new Mark() { public void draw(Graphics2D g, boolean highlighted) { stepMark.draw(g, false); Paint gpaint = g.getPaint(); g.setPaint(color); g.fill(selectedShape); g.setPaint(gpaint); } public Rectangle getBounds(boolean highlighted) { Rectangle bounds = selectedShape.getBounds(); bounds.add(stepMark.getBounds(false)); return bounds; } }; } final Mark theMark = mark; mark = new Mark() { public void draw(Graphics2D g, boolean highlighted) { if (!valid) return; theMark.draw(g, false); } public Rectangle getBounds(boolean highlighted) { return theMark.getBounds(highlighted); } }; marks.put(trackerPanel, mark); } return mark; }
/** Synchronizes bounding box with the model ; */ protected void syncBounds() { PicText te = (PicText) element; // [pending] Il faut tenir compte de la rotation ! Rectangle2D latexBB = null; // BB relative to latex dimensions (including rotation) (without frame) Rectangle2D textLayoutBB = null; // BB relative to textLayout dimensions (including rotation) (without frame) Rectangle2D textBB = null; // BB of the text (including rotation), without frame if (areDimensionsComputed) { // compute latexBB Rectangle2D nonRotated = new Rectangle2D.Double( te.getLeftX(), te.getBottomY(), te.getWidth(), te.getHeight() + te.getDepth()); AffineTransform tr = new AffineTransform(); // maps Image coordinates to Model coordinates (see paint) tr.setToIdentity(); // reset PicPoint anchor = te.getCtrlPt(TextEditable.P_ANCHOR, ptBuf); tr.rotate(getRotation(), anchor.x, anchor.y); // rotate along P_ANCHOR ! latexBB = tr.createTransformedShape(nonRotated).getBounds2D(); } if (image == null) { // compute textLayoutBB Rectangle2D nonRotated = textLayout.getBounds(); textLayoutBB = text2ModelTr.createTransformedShape(nonRotated).getBounds2D(); } // use textLayoutBB or latexBB or their union if (image != null) textBB = latexBB; else { if (!areDimensionsComputed) textBB = textLayoutBB; else { textBB = latexBB.createUnion(textLayoutBB); } } // union with frame BB if (te.isFramed()) { super.syncBounds(); // update bounds of the frame if necessary Rectangle2D.union(super.bounds, textBB, this.bounds); } else this.bounds = textBB; }
/** * synchronize frame shape and location (TextLayout only) ; this is called by syncShape(), so that * subclasser might override easily when only rectangular shapes are availables. */ protected void syncFrame() { PicText te = (PicText) element; if (!te.isFramed()) { return; } AffineTransform tr = new AffineTransform(); // maps Image coordinates to Model coordinates (see paint) tr.setToIdentity(); // reset PicPoint anchor = te.getCtrlPt(TextEditable.P_ANCHOR, ptBuf); tr.rotate(getRotation(), anchor.x, anchor.y); // rotate along P_ANCHOR ! shape = tr.createTransformedShape(te.getShapeOfFrame()); }
void draw(Graphics2D g) { // toX/toY is tip of arrow and fx/fy is a point on the line - // fx/fy is used to determine direction & angle AffineTransform at = AffineTransform.getTranslateInstance(toX, toY); int b = 9; double theta = Math.toRadians(20); // The idea of using a GeneralPath is so we can // create the (three lines that make up the) arrow // (only) one time and then use AffineTransform to // place it anywhere we want. GeneralPath path = new GeneralPath(); // distance between line and the arrow mark <** not ** // Start a new line segment from the position of (0,0). path.moveTo(0, 0); // Create one of the two arrow head lines. int x = (int) (-b * Math.cos(theta)); int y = (int) (b * Math.sin(theta)); path.lineTo(x, y); // distance between line and the arrow mark <** not ** // Make the other arrow head line. int x2 = (int) (-b * Math.cos(-theta)); int y2 = (int) (b * Math.sin(-theta)); // path.moveTo(0,0); path.lineTo(x2, y2); path.closePath(); // theta is in radians double s, t; s = toY - fy; // calculate slopes. t = toX - fx; if (t != 0) { s = s / t; theta = Math.atan(s); if (t < 0) theta += Math.PI; } else if (s < 0) theta = -(Math.PI / 2); else theta = Math.PI / 2; at.rotate(theta); // at.rotate(theta,toX,toY); Shape shape = at.createTransformedShape(path); if (checkStatus == Status.UNCHECKED) g.setColor(Color.BLACK); else if (checkStatus == Status.COMPATIBLE) g.setColor(FOREST_GREEN); else g.setColor(ORANGE_RED); g.fill(shape); g.draw(shape); }
private Shape getTextShape() { if (cachedTextShape == null) { String text = getText(); if (text == null || text.length() == 0) { text = " "; } FontRenderContext frc = getFontRenderContext(); HashMap<TextAttribute, Object> textAttributes = new HashMap<TextAttribute, Object>(); textAttributes.put(TextAttribute.FONT, getFont()); if (FONT_UNDERLINE.get(this)) { textAttributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); } TextLayout textLayout = new TextLayout(text, textAttributes, frc); AffineTransform tx = new AffineTransform(); tx.translate(coordinates[0].x, coordinates[0].y); switch (TEXT_ANCHOR.get(this)) { case END: tx.translate(-textLayout.getAdvance(), 0); break; case MIDDLE: tx.translate(-textLayout.getAdvance() / 2d, 0); break; case START: break; } tx.rotate(rotates[0]); /* if (TRANSFORM.get(this) != null) { tx.preConcatenate(TRANSFORM.get(this)); }*/ cachedTextShape = tx.createTransformedShape(textLayout.getOutline(tx)); cachedTextShape = textLayout.getOutline(tx); } return cachedTextShape; }
@Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2 = (Graphics2D) g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.translate(x, y); g2.setStroke(new BasicStroke(BORDER_WIDTH)); g2.setPaint(LINE_COLOR); g2.draw(BORDER); g2.setStroke(new BasicStroke(SLIT_WIDTH)); g2.setColor(UIManager.getColor("Panel.background")); int n = SLIT_NUM + 1; int v = ICON_SIZE / n; int m = n * v; for (int i = 1; i < n; i++) { int a = i * v; g2.drawLine(a, 0, a, m); g2.drawLine(0, a, m, a); } // g2.drawLine(1 * v, 0 * v, 1 * v, 4 * v); // g2.drawLine(2 * v, 0 * v, 2 * v, 4 * v); // g2.drawLine(3 * v, 0 * v, 3 * v, 4 * v); // g2.drawLine(0 * v, 1 * v, 4 * v, 1 * v); // g2.drawLine(0 * v, 2 * v, 4 * v, 2 * v); // g2.drawLine(0 * v, 3 * v, 4 * v, 3 * v); g2.setPaint(LINE_COLOR); Rectangle2D b = ARROW.getBounds(); Point2D p = new Point2D.Double(b.getX() + b.getWidth() / 2d, b.getY() + b.getHeight() / 2d); AffineTransform toCenterAT = AffineTransform.getTranslateInstance(ICON_SIZE / 2d - p.getX(), ICON_SIZE / 2d - p.getY()); g2.fill(toCenterAT.createTransformedShape(ARROW)); g2.dispose(); }
public Shape getShape() { int R = Integer.parseInt(hexcolor.substring(0, 2), 16); int G = Integer.parseInt(hexcolor.substring(2, 4), 16); int B = Integer.parseInt(hexcolor.substring(4, 6), 16); color = new Color(R, G, B); Shape geom; if (shape.equals("circle")) { geom = new Ellipse2D.Float(-0.05f * size, -0.05f * size, 1.1f * size, 1.1f * size); center = new Point2D.Float(size / 2, size / 2); } else if (shape.equals("square")) { geom = new Rectangle2D.Float(0, 0, size, size); center = new Point2D.Float(size / 2, size / 2); } else if (shape.equals("roundsquare")) { geom = new RoundRectangle2D.Float(0, 0, size, size, size / 2, size / 2); center = new Point2D.Float(size / 2, size / 2); } else if (shape.equals("triangle")) { GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 2); float height = (float) (Math.sqrt(3) * size / 2); path.moveTo(size / 2, size - height); path.lineTo(size, size); path.lineTo(0, size); path.closePath(); geom = path; center = new Point2D.Float(size / 2, size - height / 2); } else if (shape.equals("star")) { GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 2); path.moveTo(size / 2, 0); path.lineTo(7 * size / 10, 3 * size / 10); path.lineTo(size, size / 2); path.lineTo(7 * size / 10, 7 * size / 10); path.lineTo(size / 2, size); path.lineTo(3 * size / 10, 7 * size / 10); path.lineTo(0, size / 2); path.lineTo(3 * size / 10, 3 * size / 10); path.closePath(); AffineTransform trans = AffineTransform.getRotateInstance(Math.PI / 4, size / 2, size / 2); Shape shape = trans.createTransformedShape(path); Area area = new Area(path); area.add(new Area(shape)); trans = AffineTransform.getScaleInstance(1.2, 1.2); shape = trans.createTransformedShape(area); trans = AffineTransform.getTranslateInstance(-0.1 * size, -0.1 * size); shape = trans.createTransformedShape(shape); geom = shape; center = new Point2D.Float(size / 2, size / 2); } else if (shape.equals("octagon")) { GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 2); path.moveTo(size / 4, 0); path.lineTo(3 * size / 4, 0); path.lineTo(size, size / 4); path.lineTo(size, 3 * size / 4); path.lineTo(3 * size / 4, size); path.lineTo(size / 4, size); path.lineTo(0, 3 * size / 4); path.lineTo(0, size / 4); path.closePath(); geom = path; path.closePath(); geom = path; center = new Point2D.Float(size / 2, size / 2); } else if (shape.equals("ellipse")) { geom = new Ellipse2D.Float(0, 0, 3 * size / 4, size); center = new Point2D.Float(3 * size / 8, size / 2); } else if (shape.equals("cross")) { GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 2); path.moveTo(size / 4, 0); path.lineTo(3 * size / 4, 0); path.lineTo(3 * size / 4, size / 4); path.lineTo(size, size / 4); path.lineTo(size, 3 * size / 4); path.lineTo(3 * size / 4, 3 * size / 4); path.lineTo(3 * size / 4, size); path.lineTo(size / 4, size); path.lineTo(size / 4, 3 * size / 4); path.lineTo(0, 3 * size / 4); path.lineTo(0, size / 4); path.lineTo(size / 4, size / 4); path.closePath(); geom = path; center = new Point2D.Float(size / 2, size / 2); } else if (shape.equals("pentagon")) { GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 2); path.moveTo(size / 2, size); float x, y, a; for (int i = 1; i < 5; i++) { a = (float) ((2 * Math.PI / 5) * i); x = (float) (size / 2 + size / 2 * Math.sin(a)); y = (float) (size / 2 + size / 2 * Math.cos(a)); path.lineTo(x, y); } path.closePath(); AffineTransform trans = AffineTransform.getScaleInstance(1.1, 1.1); Shape shape = trans.createTransformedShape(path); trans = AffineTransform.getTranslateInstance(-0.05 * size, -0.05 * size); shape = trans.createTransformedShape(shape); geom = shape; center = new Point2D.Float(size / 2, size / 2); } else if (shape.equals("hexagon")) { GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 2); path.moveTo(size / 2, size); float x, y, a; for (int i = 1; i < 6; i++) { a = (float) ((2 * Math.PI / 6) * i); x = (float) (size / 2 + size / 2 * Math.sin(a)); y = (float) (size / 2 + size / 2 * Math.cos(a)); path.lineTo(x, y); } path.closePath(); geom = path; center = new Point2D.Float(size / 2, size / 2); } else { geom = new Ellipse2D.Float(0, 0, size, size); center = new Point2D.Float(size / 2, size / 2); } return geom; }