Mega Code Archive

 
Categories / Java / 2D Graphics GUI
 

Gradient Shapes

import java.awt.Color; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RadialGradientPaint; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.SwingUtilities; /*  * DrawShapes_2008.java  *  * Created on May 1, 2007, 4:16 PM  *  * Copyright (c) 2007, Sun Microsystems, Inc  * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  *   * Redistributions of source code must retain the above copyright  *     notice, this list of conditions and the following disclaimer.  *   * Redistributions in binary form must reproduce the above  *     copyright notice, this list of conditions and the following  *     disclaimer in the documentation and/or other materials provided  *     with the distribution.  *   * Neither the name of the TimingFramework project nor the names of its  *     contributors may be used to endorse or promote products derived  *     from this software without specific prior written permission.  *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */ /**  *  * @author Chet  */ public class DrawShapes_2008 extends JComponent {     private List<Shape> shapes = new ArrayList();     private boolean getStar = true;          /**      * Generates a star Shape from the given location, radii, and points      * parameters. The Shape is created by constructing a GeneralPath      * that moves between the inner and outer rings.      */     private static Shape generateStar(double x, double y,                                       double innerRadius, double outerRadius,                                       int pointsCount) {         GeneralPath path = new GeneralPath();         double outerAngleIncrement = 2 * Math.PI / pointsCount;         double outerAngle = 0.0;         double innerAngle = outerAngleIncrement / 2.0;         x += outerRadius;         y += outerRadius;         float x1 = (float) (Math.cos(outerAngle) * outerRadius + x);         float y1 = (float) (Math.sin(outerAngle) * outerRadius + y);         float x2 = (float) (Math.cos(innerAngle) * innerRadius + x);         float y2 = (float) (Math.sin(innerAngle) * innerRadius + y);         path.moveTo(x1, y1);         path.lineTo(x2, y2);         outerAngle += outerAngleIncrement;         innerAngle += outerAngleIncrement;         for (int i = 1; i < pointsCount; i++) {             x1 = (float) (Math.cos(outerAngle) * outerRadius + x);             y1 = (float) (Math.sin(outerAngle) * outerRadius + y);             path.lineTo(x1, y1);             x2 = (float) (Math.cos(innerAngle) * innerRadius + x);             y2 = (float) (Math.sin(innerAngle) * innerRadius + y);             path.lineTo(x2, y2);             outerAngle += outerAngleIncrement;             innerAngle += outerAngleIncrement;         }         path.closePath();         return path;     }          /**      * Generates a donut shape from the given location and radii by subtracting      * an inner circular Area from an outer one.      */     private static Shape generateDonut(double x, double y,             double innerRadius, double outerRadius) {         Area a1 = new Area(new Ellipse2D.Double(x, y, outerRadius, outerRadius));         double innerOffset = (outerRadius - innerRadius)/2;         Area a2 = new Area(new Ellipse2D.Double(x + innerOffset, y + innerOffset,                  innerRadius, innerRadius));         a1.subtract(a2);         return a1;     }     /**       * This class processes mouse clicks and generates stars and donuts,      * alternately, in the click location. The new shape is added to the      * List of current shapes, then the scene is repainted.      */     private class ClickReceiver extends MouseAdapter {         public void mouseClicked(MouseEvent me) {             int centerX = me.getX();             int centerY = me.getY();             double innerSize = 1 + (25 * Math.random());             double outerSize = innerSize + 10 + (15 * Math.random());             Shape newShape;             if (getStar) {                 int numPoints = (int)(8 * Math.random() + 5);                 newShape = generateStar(centerX - outerSize,                          centerY - outerSize,                         innerSize, outerSize, numPoints);             } else {                 newShape = generateDonut(centerX - outerSize/2,                          centerY - outerSize/2,                         innerSize, outerSize);             }             getStar = !getStar;             shapes.add(newShape);             repaint();         }     }          @Override     protected void paintComponent(Graphics g) {         Graphics2D g2d = (Graphics2D)g;         // Paint a gradient for the sky         GradientPaint background = new GradientPaint(0f, 0f, Color.GRAY.darker(),                 0f, (float)getHeight(), Color.GRAY.brighter());         g2d.setPaint(background);         g2d.fillRect(0, 0, getWidth(), 4*getHeight()/5);                  // Paint a gradient for the ground         background = new GradientPaint(0f, (float)4*getHeight()/5,                  Color.BLACK,                 0f, (float)getHeight(), Color.GRAY.darker());         g2d.setPaint(background);         g2d.fillRect(0, 4*getHeight()/5, getWidth(), getHeight()/5);                  // Enable anti-aliasing to get smooth outlines         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,                 RenderingHints.VALUE_ANTIALIAS_ON);                  // Iterate through all of the current shapes         for (Shape shape : shapes) {             // Get the bounds to compute the RadialGradient properties             Rectangle rect = shape.getBounds();             Point2D center = new Point2D.Float(                     rect.x + (float)rect.width / 2.0f,                     rect.y + (float)rect.height / 2.0f);             float radius = (float)rect.width / 2.0f;             float[] dist = {0.1f, 0.9f};             Color[] colors = {Color.WHITE, Color.BLACK};                          // Create and set a RadialGradient centered on the object,             // going from white at the center to black at the edges             RadialGradientPaint paint = new RadialGradientPaint(center, radius,                     dist, colors);             g2d.setPaint(paint);                          // Finally, render our shape             g2d.fill(shape);         }     }          /**      * Creates a new instance of DrawShapes_2008      */     public DrawShapes_2008() {         setBackground(Color.WHITE);         addMouseListener(new ClickReceiver());     }          private static void createAndShowGUI() {             JFrame f = new JFrame("Draw Shapes");         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         f.setSize(500, 500);         f.add(new DrawShapes_2008());         f.setVisible(true);     }          public static void main(String args[]) {         Runnable doCreateAndShowGUI = new Runnable() {             public void run() {                 createAndShowGUI();             }         };         SwingUtilities.invokeLater(doCreateAndShowGUI);     } }