下面列出了java.awt.geom.Path2D#WIND_EVEN_ODD 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static void doPaint(final Graphics2D g, final float width, final float height, final float arc,
final float bw, final boolean inside) {
GraphicsContext context = GraphicsUtil.setupStrokePainting(g);
Shape outerRect;
Shape innerRect;
if (Scale.equalWithError(arc, 0)) {
outerRect = new Rectangle2D.Float(0, 0, width, height);
innerRect = new Rectangle2D.Float(bw, bw, width - 2 * bw, height - 2 * bw);
} else {
float outerArc = inside ? arc : arc + bw;
float innerArc = inside ? arc - bw : arc;
outerRect = new RoundRectangle2D.Float(0, 0, width, height, outerArc, outerArc);
innerRect = new RoundRectangle2D.Float(bw, bw, width - 2 * bw, height - 2 * bw, innerArc, innerArc);
}
Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD);
path.append(outerRect, false);
path.append(innerRect, false);
g.fill(path);
context.restore();
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
/*
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-rule="evenodd">
<path fill="#6E6E6E" d="M11,14 L11,11 L5,11 L5,14 L2,14 L2,2 L14,2 L14,14 L11,14 Z M4,4 L4,8 L12,8 L12,4 L4,4 Z"/>
<rect width="4" height="2" x="6" y="12" fill="#6E6E6E"/>
</g>
</svg>
*/
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( FlatUIUtils.createPath( 11,14, 11,11, 5,11, 5,14, 2,14, 2,2, 14,2, 14,14, 11,14 ), false );
path.append( FlatUIUtils.createPath( 4,4, 4,8, 12,8, 12,4, 4,4 ), false );
g.fill( path );
g.fillRect( 6, 12, 4, 2 );
}
/**
* Draws a sequence of connected lines defined by
* arrays of <i>x</i> and <i>y</i> coordinates.
* Each pair of (<i>x</i>, <i>y</i>) coordinates defines a point.
* The figure is not closed if the first point
* differs from the last point.
* @param xPoints an array of <i>x</i> points
* @param yPoints an array of <i>y</i> points
* @param nPoints the total number of points
* @see java.awt.Graphics#drawPolygon(int[], int[], int)
* @since 1.1
*/
public void drawPolyline(int xPoints[], int yPoints[],
int nPoints) {
if (nPoints == 2) {
draw(new Line2D.Float(xPoints[0], yPoints[0],
xPoints[1], yPoints[1]));
} else if (nPoints > 2) {
Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD, nPoints);
path.moveTo(xPoints[0], yPoints[0]);
for(int i = 1; i < nPoints; i++) {
path.lineTo(xPoints[i], yPoints[i]);
}
draw(path);
}
}
private void drawPolylineGOOD(Graphics2D g2d,
int[] x2Points, int[] y2Points) {
Path2D polyline =
new Path2D.Float(Path2D.WIND_EVEN_ODD, x2Points.length);
polyline.moveTo(x2Points[0], y2Points[0]);
for (int index = 1; index < x2Points.length; index++) {
polyline.lineTo(x2Points[index], y2Points[index]);
}
g2d.draw(polyline);
}
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
if( color == null )
return;
FlatUIUtils.setRenderingHints( (Graphics2D) g );
g.setColor( color );
float lineWidth = UIScale.scale( 1f );
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Rectangle2D.Float( x, y, width, height ), false );
path.append( new Rectangle2D.Float( x + lineWidth, y, width - (lineWidth * 2), height - lineWidth ), false );
((Graphics2D)g).fill( path );
}
public static void main(final String[] args) {
final Path2D path1 = new Path2D.Double(Path2D.WIND_EVEN_ODD, 0);
path1.moveTo(10, 10);
path1.lineTo(20, 20);
final Path2D path2 = new Path2D.Float(Path2D.WIND_EVEN_ODD, 0);
path2.moveTo(10, 10);
path2.lineTo(20, 20);
}
public static void main(final String[] args) {
final Path2D path1 = new Path2D.Double(Path2D.WIND_EVEN_ODD, 0);
path1.moveTo(10, 10);
path1.lineTo(20, 20);
final Path2D path2 = new Path2D.Float(Path2D.WIND_EVEN_ODD, 0);
path2.moveTo(10, 10);
path2.lineTo(20, 20);
}
/**
* Paints the border for the specified component with the
* specified position and size.
* @param c the component for which this border is being painted
* @param g the paint graphics
* @param x the x position of the painted border
* @param y the y position of the painted border
* @param width the width of the painted border
* @param height the height of the painted border
*/
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
if ((this.thickness > 0) && (g instanceof Graphics2D)) {
Graphics2D g2d = (Graphics2D) g;
Color oldColor = g2d.getColor();
g2d.setColor(this.lineColor);
Shape outer;
Shape inner;
int offs = this.thickness;
int size = offs + offs;
if (this.roundedCorners) {
int arc = offs + size;
outer = new RoundRectangle2D.Float(x, y, width, height, arc, arc);
inner = new RoundRectangle2D.Float(x + offs, y + offs, width - size, height - size, arc, arc);
}
else {
outer = new Rectangle2D.Float(x, y, width, height);
inner = new Rectangle2D.Float(x + offs, y + offs, width - size, height - size);
}
Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD);
path.append(outer, false);
path.append(inner, false);
g2d.fill(path);
g2d.setColor(oldColor);
}
}
public static void main(final String[] args) {
final Path2D path1 = new Path2D.Double(Path2D.WIND_EVEN_ODD, 0);
path1.moveTo(10, 10);
path1.lineTo(20, 20);
final Path2D path2 = new Path2D.Float(Path2D.WIND_EVEN_ODD, 0);
path2.moveTo(10, 10);
path2.lineTo(20, 20);
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
/*
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#6E6E6E" fill-rule="evenodd" d="M2,6 L14,6 L14,10 L2,10 L2,6 Z M12,8 L12,9 L13,9 L13,8 L12,8 Z M10,8 L10,9 L11,9 L11,8 L10,8 Z"/>
</svg>
*/
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Rectangle2D.Float( 2, 6, 12, 4 ), false );
path.append( new Rectangle2D.Float( 12, 8, 1, 1 ), false );
path.append( new Rectangle2D.Float( 10, 8, 1, 1 ), false );
g.fill( path );
}
/**
* Paints the border for the specified component with the
* specified position and size.
*
* @param c the component for which this border is being painted
* @param g the paint graphics
* @param x the x position of the painted border
* @param y the y position of the painted border
* @param width the width of the painted border
* @param height the height of the painted border
*/
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
if ((this.thickness > 0) && (g instanceof Graphics2D)) {
Graphics2D g2d = (Graphics2D) g;
Color oldColor = g2d.getColor();
g2d.setColor(this.lineColor);
Shape outer;
Shape inner;
int offs = this.thickness;
int size = offs + offs;
if (this.roundedCorners) {
float arc = .2f * offs;
outer = new RoundRectangle2D.Float(x, y, width, height, offs, offs);
inner = new RoundRectangle2D.Float(x + offs, y + offs, width - size, height - size, arc, arc);
}
else {
outer = new Rectangle2D.Float(x, y, width, height);
inner = new Rectangle2D.Float(x + offs, y + offs, width - size, height - size);
}
Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD);
path.append(outer, false);
path.append(inner, false);
g2d.fill(path);
g2d.setColor(oldColor);
}
}
@Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iwh = (int) (10 * scaleFactor);
int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2);
int ix2 = ix + iwh - 1;
int iy2 = iy + iwh - 1;
int thickness = (int) scaleFactor;
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Line2D.Float( ix, iy, ix2, iy2 ), false );
path.append( new Line2D.Float( ix, iy2, ix2, iy ), false );
g.setStroke( new BasicStroke( thickness ) );
g.draw( path );
}
/**
* Paints the border for the specified component with the
* specified position and size.
* @param c the component for which this border is being painted
* @param g the paint graphics
* @param x the x position of the painted border
* @param y the y position of the painted border
* @param width the width of the painted border
* @param height the height of the painted border
*/
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
if ((this.thickness > 0) && (g instanceof Graphics2D)) {
Graphics2D g2d = (Graphics2D) g;
Color oldColor = g2d.getColor();
g2d.setColor(this.lineColor);
Shape outer;
Shape inner;
int offs = this.thickness;
int size = offs + offs;
if (this.roundedCorners) {
float arc = .2f * offs;
outer = new RoundRectangle2D.Float(x, y, width, height, offs, offs);
inner = new RoundRectangle2D.Float(x + offs, y + offs, width - size, height - size, arc, arc);
}
else {
outer = new Rectangle2D.Float(x, y, width, height);
inner = new Rectangle2D.Float(x + offs, y + offs, width - size, height - size);
}
Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD);
path.append(outer, false);
path.append(inner, false);
g2d.fill(path);
g2d.setColor(oldColor);
}
}
public static void main(final String[] args) {
final Path2D path1 = new Path2D.Double(Path2D.WIND_EVEN_ODD, 0);
path1.moveTo(10, 10);
path1.lineTo(20, 20);
final Path2D path2 = new Path2D.Float(Path2D.WIND_EVEN_ODD, 0);
path2.moveTo(10, 10);
path2.lineTo(20, 20);
}
private void paintYPin(Graphics2D g, int number) {
double y = top;
for (int i = 0; i < number; i++) {
y += yBounds[i].getSize().getHeight();
}
g.setColor(Color.black);
double max = 6;
g.setPaint(new GradientPaint(new Point2D.Double(LEFT - max, y - max),
Color.green, new Point2D.Double(LEFT + max, y + max),
Color.black));
GeneralPath path1 = new GeneralPath(Path2D.WIND_EVEN_ODD, 4);
GeneralPath path2 = new GeneralPath(Path2D.WIND_EVEN_ODD, 4);
path1.moveTo(LEFT - 5, y);
path1.lineTo(LEFT - 5 - max, y + max / 2);
path1.lineTo(LEFT - 5 - max, y - max / 2);
path1.lineTo(LEFT - 5, y);
path2.moveTo(5 + LEFT + width, y);
path2.lineTo(5 + LEFT + width + max, y + max / 2);
path2.lineTo(5 + LEFT + width + max, y - max / 2);
path2.lineTo(5 + LEFT + width, y);
g.fill(path1);
g.setPaint(new GradientPaint(new Point2D.Double(LEFT + width - max, y
- max), Color.black, new Point2D.Double(LEFT + max + width, y
+ max), Color.green));
g.fill(path2);
g.setColor(Color.gray);
g.draw(path1);
g.draw(path2);
}
/**
* Paints the border for the specified component with the
* specified position and size.
* @param c the component for which this border is being painted
* @param g the paint graphics
* @param x the x position of the painted border
* @param y the y position of the painted border
* @param width the width of the painted border
* @param height the height of the painted border
*/
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
if ((this.thickness > 0) && (g instanceof Graphics2D)) {
Graphics2D g2d = (Graphics2D) g;
Color oldColor = g2d.getColor();
g2d.setColor(this.lineColor);
Shape outer;
Shape inner;
int offs = this.thickness;
int size = offs + offs;
if (this.roundedCorners) {
float arc = .2f * offs;
outer = new RoundRectangle2D.Float(x, y, width, height, offs, offs);
inner = new RoundRectangle2D.Float(x + offs, y + offs, width - size, height - size, arc, arc);
}
else {
outer = new Rectangle2D.Float(x, y, width, height);
inner = new Rectangle2D.Float(x + offs, y + offs, width - size, height - size);
}
Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD);
path.append(outer, false);
path.append(inner, false);
g2d.fill(path);
g2d.setColor(oldColor);
}
}
protected void paintSearchField(Graphics2D g, JTextComponent c, Rectangle r) {
Graphics2D g2 = (Graphics2D)g.create();
try {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, MacUIUtil.USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE);
g2.translate(r.x, r.y);
int arc = JBUI.scale(6);
double lw = UIUtil.isRetina(g2) ? 0.5 : 1.0;
Shape outerShape = new RoundRectangle2D.Double(JBUI.scale(3), JBUI.scale(3),
r.width - JBUI.scale(6),
r.height - JBUI.scale(6),
arc, arc);
g2.setColor(c.getBackground());
g2.fill(outerShape);
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
path.append(outerShape, false);
path.append(new RoundRectangle2D.Double(JBUI.scale(3) + lw, JBUI.scale(3) + lw,
r.width - JBUI.scale(6) - lw*2,
r.height - JBUI.scale(6) - lw*2,
arc-lw, arc-lw), false);
g2.setColor(Gray.xBC);
g2.fill(path);
if (c.hasFocus() && c.getClientProperty("JTextField.Search.noBorderRing") != Boolean.TRUE) {
DarculaUIUtilPart.paintFocusBorder(g2, r.width, r.height, arc, true);
}
g2.translate(-r.x, -r.y);
boolean withHistoryPopup = isSearchFieldWithHistoryPopup(c);
Icon label = getSearchIcon(c);
boolean isEmpty = !hasText();
Point point = getSearchIconCoord();
if (isEmpty && !c.hasFocus() && !withHistoryPopup) {
label.paintIcon(c, g2, point.x, point.y);
} else {
Graphics ig = g2.create(0, 0, c.getWidth(), c.getHeight());
Area area = new Area(new Rectangle2D.Double(point.x, point.y, isEmpty ? label.getIconWidth() : 16, label.getIconHeight()));
area.intersect(new Area(ig.getClip()));
ig.setClip(area);
label.paintIcon(c, ig, point.x, point.y);
ig.dispose();
}
if (!isEmpty) {
Point ic = getClearIconCoord();
MacIntelliJIconCache.getIcon("searchFieldClear").paintIcon(c, g2, ic.x, ic.y);
}
AbstractAction newLineAction = getNewLineAction(c);
if (newLineAction != null) {
Icon newLineIcon = (Icon)newLineAction.getValue(Action.SMALL_ICON);
if (newLineIcon != null) {
newLineIcon.paintIcon(c, g2, getAddNewLineIconCoord().x, r.y);
}
}
} finally {
g2.dispose();
}
}
/**
* Creates an SVG path string for the supplied Java2D path.
*
* @param path the path ({@code null} not permitted).
*
* @return An SVG path string.
*/
private String getSVGPathData(Path2D path) {
StringBuilder b = new StringBuilder();
if (path.getWindingRule() == Path2D.WIND_EVEN_ODD) {
b.append("fill-rule=\"evenodd\" ");
}
b.append("d=\"");
float[] coords = new float[6];
boolean first = true;
PathIterator iterator = path.getPathIterator(null);
while (!iterator.isDone()) {
int type = iterator.currentSegment(coords);
if (!first) {
b.append(" ");
}
first = false;
switch (type) {
case (PathIterator.SEG_MOVETO):
b.append("M ").append(geomDP(coords[0])).append(" ")
.append(geomDP(coords[1]));
break;
case (PathIterator.SEG_LINETO):
b.append("L ").append(geomDP(coords[0])).append(" ")
.append(geomDP(coords[1]));
break;
case (PathIterator.SEG_QUADTO):
b.append("Q ").append(geomDP(coords[0]))
.append(" ").append(geomDP(coords[1]))
.append(" ").append(geomDP(coords[2]))
.append(" ").append(geomDP(coords[3]));
break;
case (PathIterator.SEG_CUBICTO):
b.append("C ").append(geomDP(coords[0])).append(" ")
.append(geomDP(coords[1])).append(" ")
.append(geomDP(coords[2])).append(" ")
.append(geomDP(coords[3])).append(" ")
.append(geomDP(coords[4])).append(" ")
.append(geomDP(coords[5]));
break;
case (PathIterator.SEG_CLOSE):
b.append("Z ");
break;
default:
break;
}
iterator.next();
}
return b.append("\"").toString();
}
@Override
public void paintOverImage(Graphics2D g2, Composition comp,
AffineTransform imageTransform) {
if (ended) {
return;
}
View view = comp.getView();
if (!view.isActive()) {
return;
}
PRectangle cropRect = getCropRect();
if (cropRect == null) {
return;
}
// TODO done for compatibility. The whole code should be re-evaluated
AffineTransform componentTransform = g2.getTransform();
g2.setTransform(imageTransform);
// paint the semi-transparent dark area outside the crop rectangle
Shape origClip = g2.getClip(); // save for later use
Canvas canvas = comp.getCanvas();
Rectangle canvasBounds = canvas.getBounds();
// Similar to ClipStrategy.FULL, but we need some intermediary variables
Rectangle coVisiblePart = view.getVisiblePart();
// ...but first get this to image space...
Rectangle2D imVisiblePart = view.componentToImageSpace(coVisiblePart);
// ... and now we can intersect
Rectangle2D canvasImgIntersection = canvasBounds.createIntersection(imVisiblePart);
Path2D darkAreaClip = new Path2D.Double(Path2D.WIND_EVEN_ODD);
darkAreaClip.append(canvasImgIntersection, false);
Rectangle2D cropRectIm = cropRect.getIm();
darkAreaClip.append(cropRectIm, false);
g2.setClip(darkAreaClip);
Color origColor = g2.getColor();
g2.setColor(BLACK);
Composite origComposite = g2.getComposite();
g2.setComposite(hideComposite);
g2.fill(canvasImgIntersection);
g2.setColor(origColor);
g2.setComposite(origComposite);
g2.setTransform(componentTransform);
if (state == TRANSFORM) {
// Paint the handles.
// The zooming is temporarily reset because the transformSupport works in component space
// prevents drawing outside the InternalImageFrame/CompositionView
// it is important to call this AFTER setting the unscaled transform
g2.setClip(coVisiblePart);
// draw composition guides
compositionGuide.setType((CompositionGuideType) guidesCB.getSelectedItem());
compositionGuide.draw(cropRect.getCo(), g2);
cropBox.paintHandles(g2);
}
g2.setClip(origClip);
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
if (isComboBoxEditor(c)) {
g.setColor(c.getBackground());
g.fillRect(x, y, width, height);
return;
}
EditorTextField editorTextField = ComponentUtil.getParentOfType((Class<? extends EditorTextField>)EditorTextField.class, c);
if (editorTextField == null) return;
boolean hasFocus = editorTextField.getFocusTarget().hasFocus();
Rectangle r = new Rectangle(x, y, width, height);
if (isTableCellEditor(c)) {
paintCellEditorBorder((Graphics2D)g, c, r, hasFocus);
}
else {
Graphics2D g2 = (Graphics2D)g.create();
try {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, MacUIUtil.USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE);
if (c.isOpaque()) {
g2.setColor(UIUtil.getPanelBackground());
g2.fill(r);
}
JBInsets.removeFrom(r, JBUI.insets(1));
g2.translate(r.x, r.y);
float lw = lw(g2);
float bw = bw();
Shape outer = new Rectangle2D.Float(bw, bw, r.width - bw * 2, r.height - bw * 2);
g2.setColor(c.getBackground());
g2.fill(outer);
Object op = editorTextField.getClientProperty("JComponent.outline");
if (editorTextField.isEnabled() && op != null) {
paintOutlineBorder(g2, r.width, r.height, 0, true, hasFocus, Outline.valueOf(op.toString()));
}
else if (editorTextField.isEnabled() && editorTextField.isVisible()) {
if (hasFocus) {
paintOutlineBorder(g2, r.width, r.height, 0, true, true, Outline.focus);
}
Path2D border = new Path2D.Float(Path2D.WIND_EVEN_ODD);
border.append(outer, false);
border.append(new Rectangle2D.Float(bw + lw, bw + lw, r.width - (bw + lw) * 2, r.height - (bw + lw) * 2), false);
g2.setColor(getOutlineColor(editorTextField.isEnabled(), hasFocus));
g2.fill(border);
}
}
finally {
g2.dispose();
}
}
}