// Glenn Rowe's version of Petzold's Cloverleaf // with minor mods by Nick Taylor (24.10.2003) import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; /** * Draws a four-leaved clover * (with apologies to Charles Petzold) */ class Clover extends JFrame { int frameWidth, frameHeight; Shape contentShape; Area cloverArea; public static void main(String[] argv) { Clover testShape = new Clover(); testShape.setVisible(true); } public Clover() { setTitle("Cloverleaf using Areas"); setSize(300,300); setBackground(Color.white); enableEvents(AWTEvent.WINDOW_EVENT_MASK | AWTEvent.COMPONENT_EVENT_MASK); } /** * Overridden so we can exit when window is closed */ protected void processWindowEvent(WindowEvent e) { super.processWindowEvent(e); if (e.getID() == WindowEvent.WINDOW_CLOSING) { System.exit(0); } } /** * Defines the clover-shaped mask when the frame is * displayed and each time it is resized */ protected void processComponentEvent(ComponentEvent e) { super.processComponentEvent(e); if (e.getID() == ComponentEvent.COMPONENT_RESIZED) { // Get dimensions of the drawing region // excluding the title bar frameWidth = getContentPane().getWidth(); frameHeight = getContentPane().getHeight(); // Define a rectangle that is used to clear the background in paint() Shape contentShape = new Rectangle2D.Double(0, 0, frameWidth, frameHeight); // Construct the clover mask from several Areas // // First, define the four elliptical lobes of the leaf Area[] ellipse = new Area[4]; ellipse[0] = new Area(new Ellipse2D.Double(0, frameHeight/3, frameWidth/2, frameHeight/3)); ellipse[1] = new Area(new Ellipse2D.Double(frameWidth/2, frameHeight/3, frameWidth/2, frameHeight/3)); ellipse[2] = new Area(new Ellipse2D.Double(frameWidth/3, 0, frameWidth/3, frameHeight/2)); ellipse[3] = new Area(new Ellipse2D.Double(frameWidth/3, frameHeight/2, frameWidth/3, frameHeight/2)); // OR together the left and right ellipses ellipse[0].add(ellipse[1]); // OR together the top and bottom ellipses ellipse[2].add(ellipse[3]); // Creates the final clipping mask by XORing the left/right // and top/bottom pairs cloverArea = ellipse[0]; cloverArea.exclusiveOr(ellipse[2]); } } /** * Draws the clover leaf using the clipping Area above. */ public void paint(Graphics g) { // Get the graphics context for the drawing area // excluding the title bar Graphics2D g2d = (Graphics2D)getContentPane().getGraphics(); // Clears the background, since the update() method in JFrame // won't do this for us. g2d.setPaint(getBackground()); g2d.fill(contentShape); // Define the colour and clipping area for the clover g2d.setPaint(Color.black); g2d.setClip(cloverArea); // Draw the radial lines double radius = Math.sqrt(frameWidth*frameWidth + frameHeight*frameHeight)/2.0; GeneralPath clover = new GeneralPath(); for (double angle = 0.0; angle <= 2*Math.PI; angle += Math.PI/180.0) { clover.moveTo(frameWidth/2, frameHeight/2); clover.lineTo((float)(radius * Math.cos(angle)) + frameWidth/2, -(float)(radius * Math.sin(angle)) + frameHeight/2); } g2d.draw(clover); } }