Drawing Crisp Circles in Java with Graphics2D and BufferedImage
These articles are AI-generated summaries. Please check the original sources for full details.
Draw a Decent Looking Circle in Java | Baeldung
Daniel Fintinariu demonstrates how to render high-quality circles in Java Swing. The article highlights that Java2D’s Ellipse2D.Double API with rendering hints produces smoother results than drawOval() for scalable UI components.
Why This Matters
Ideal geometric shapes require perfect antialiasing and stroke control, but raster displays introduce pixelation. At 12–24px sizes, even antialiased circles show uneven stroke widths due to subpixel rounding errors. The cost of ignoring this is inconsistent UI elements across platforms, impacting user experience in dashboards and icons.
Key Insights
- “Antialiasing + stroke control improves small-circle rendering, 2025”
- “Ellipse2D.Double over drawOval() for composable shapes”
- “BufferedImage used by Stripe for icon consistency in UI components”
Working Example
public final class CirclePanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
try {
double diameter = Math.min(getWidth(), getHeight()) - 12 - 2;
double cx = getWidth() / 2.0;
double cy = getHeight() / 2.0;
double x = cx - diameter / 2.0;
double y = cy - diameter / 2.0;
Shape circle = new Ellipse2D.Double(x, y, diameter, diameter);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2.setPaint(new Color(0xBBDEFB));
g2.fill(circle);
g2.setPaint(new Color(0x0D47A1));
g2.setStroke(new BasicStroke(2f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2.draw(circle);
} finally {
g2.dispose();
}
}
}
BufferedImage makeSupersampledCircle(int finalSize, int scale, float stroke) {
int hi = finalSize * scale;
BufferedImage img = new BufferedImage(hi, hi, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
try {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
double d = hi - stroke;
Shape circle = new Ellipse2D.Double(stroke / 2.0, stroke / 2.0, d, d);
g2.setPaint(new Color(0xBBDEFB));
g2.fill(circle);
g2.setPaint(new Color(0x0D47A1));
g2.setStroke(new BasicStroke(stroke, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2.draw(circle);
} finally {
g2.dispose();
}
return img;
}
Practical Applications
- Use Case: Badge icons in dashboards with transparent backgrounds
- Pitfall: Skipping
RenderingHints.VALUE_STROKE_PUREcauses inconsistent stroke widths on small circles
References:
Continue reading
Next article
Drawing a Quality Circle in Java Swing
Related Content
Drawing a Quality Circle in Java Swing
Enhance Java Swing circle drawing with antialiasing and offscreen rendering for improved accuracy and visual quality, especially at small sizes.
Wildcard Search in Elasticsearch: Techniques and Java Implementation
Master wildcard queries in Elasticsearch using Java with code examples for prefix, regexp, and fuzzy searches.
Building a Zero-Dependency 'Life in Weeks' Poster Generator
Ali Alp built a one-file HTML generator that renders 5,200 SVG circles and exports identical PDFs using zero backend or frameworks.