import javax.swing.Icon; import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; /** * An icon that draws a CompositeShape. */ public class ShapeIcon implements Icon { private final CompositeShape shape; private final int width; private final int height; private boolean outline = false; // Flag to indicate if the icon should be outlined /** * Constructs a ShapeIcon. * @param shape the shape to draw * @param width the desired width of the icon * @param height the desired height of the icon */ public ShapeIcon(CompositeShape shape, int width, int height) { this.shape = shape; this.width = width; this.height = height; } /** * Sets whether this icon should draw an outline (e.g., when selected). * @param outline true to draw outline, false otherwise. */ public void setOutline(boolean outline) { this.outline = outline; } @Override public int getIconWidth() { return width; } @Override public int getIconHeight() { return height; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2 = (Graphics2D) g.create(); // Work on a copy // Enable antialiasing for smoother graphics g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Translate to the icon's drawing position g2.translate(x, y); double shapeWidth = shape.getWidth(); double shapeHeight = shape.getHeight(); // Calculate scaling factor to fit shape within icon bounds double scaleX = (shapeWidth == 0) ? 1 : (double) width / shapeWidth; double scaleY = (shapeHeight == 0) ? 1 : (double) height / shapeHeight; double scale = Math.min(scaleX, scaleY) * 0.8; // Use 80% of space for padding // Calculate translation to center the scaled shape double dx = (width - shapeWidth * scale) / 2.0; double dy = (height - shapeHeight * scale) / 2.0; // Apply centering translation and scaling AffineTransform originalTransform = g2.getTransform(); g2.translate(dx, dy); g2.scale(scale, scale); // Draw the shape shape.draw(g2); // Restore original transform before drawing outline (if any) g2.setTransform(originalTransform); // Draw outline if selected if (outline) { // Simple rectangle outline around the icon area g2.setColor(java.awt.Color.GRAY); g2.drawRect(0, 0, width - 1, height - 1); g2.drawRect(1, 1, width - 3, height - 3); // Inner outline } g2.dispose(); // Clean up the graphics copy } }