1 /*
   2  *
   3  * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  *
   9  *   - Redistributions of source code must retain the above copyright
  10  *     notice, this list of conditions and the following disclaimer.
  11  *
  12  *   - Redistributions in binary form must reproduce the above copyright
  13  *     notice, this list of conditions and the following disclaimer in the
  14  *     documentation and/or other materials provided with the distribution.
  15  *
  16  *   - Neither the name of Oracle nor the names of its
  17  *     contributors may be used to endorse or promote products derived
  18  *     from this software without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  21  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 package java2d.demos.Clipping;
  33 
  34 
  35 import java.awt.*;
  36 import java.awt.event.*;
  37 import java.awt.geom.Area;
  38 import java.awt.geom.Ellipse2D;
  39 import java.awt.geom.GeneralPath;
  40 import javax.swing.*;
  41 import java2d.ControlsSurface;
  42 import java2d.CustomControls;
  43 import static java.awt.Color.*;
  44 
  45 
  46 /**
  47  * The Areas class demonstrates the CAG (Constructive Area Geometry)
  48  * operations: Add(union), Subtract, Intersect, and ExclusiveOR.
  49  */
  50 @SuppressWarnings("serial")
  51 public class Areas extends ControlsSurface {
  52 
  53     protected String areaType = "nop";
  54 
  55     public Areas() {
  56         setBackground(WHITE);
  57         setControls(new Component[] { new DemoControls(this) });
  58     }
  59 
  60     @Override
  61     public void render(int w, int h, Graphics2D g2) {
  62         GeneralPath p1 = new GeneralPath();
  63         p1.moveTo(w * .25f, 0.0f);
  64         p1.lineTo(w * .75f, h * .5f);
  65         p1.lineTo(w * .25f, h);
  66         p1.lineTo(0.0f, h * .5f);
  67         p1.closePath();
  68 
  69         GeneralPath p2 = new GeneralPath();
  70         p2.moveTo(w * .75f, 0.0f);
  71         p2.lineTo(w, h * .5f);
  72         p2.lineTo(w * .75f, h);
  73         p2.lineTo(w * .25f, h * .5f);
  74         p2.closePath();
  75 
  76 
  77         Area area = new Area(p1);
  78         g2.setColor(YELLOW);
  79         if (areaType.equals("nop")) {
  80             g2.fill(p1);
  81             g2.fill(p2);
  82             g2.setColor(RED);
  83             g2.draw(p1);
  84             g2.draw(p2);
  85             return;
  86         } else if (areaType.equals("add")) {
  87             area.add(new Area(p2));
  88         } else if (areaType.equals("sub")) {
  89             area.subtract(new Area(p2));
  90         } else if (areaType.equals("xor")) {
  91             area.exclusiveOr(new Area(p2));
  92         } else if (areaType.equals("int")) {
  93             area.intersect(new Area(p2));
  94         } else if (areaType.equals("pear")) {
  95 
  96             double sx = w / 100;
  97             double sy = h / 140;
  98             g2.scale(sx, sy);
  99             double x = w / sx / 2;
 100             double y = h / sy / 2;
 101 
 102             // Creates the first leaf by filling the intersection of two Area
 103             // objects created from an ellipse.
 104             Ellipse2D leaf = new Ellipse2D.Double(x - 16, y - 29, 15.0, 15.0);
 105             Area leaf1 = new Area(leaf);
 106             leaf.setFrame(x - 14, y - 47, 30.0, 30.0);
 107             Area leaf2 = new Area(leaf);
 108             leaf1.intersect(leaf2);
 109             g2.setColor(GREEN);
 110             g2.fill(leaf1);
 111 
 112             // Creates the second leaf.
 113             leaf.setFrame(x + 1, y - 29, 15.0, 15.0);
 114             leaf1 = new Area(leaf);
 115             leaf2.intersect(leaf1);
 116             g2.fill(leaf2);
 117 
 118             // Creates the stem by filling the Area resulting from the
 119             // subtraction of two Area objects created from an ellipse.
 120             Ellipse2D stem = new Ellipse2D.Double(x, y - 42, 40.0, 40.0);
 121             Area st1 = new Area(stem);
 122             stem.setFrame(x + 3, y - 47, 50.0, 50.0);
 123             st1.subtract(new Area(stem));
 124             g2.setColor(BLACK);
 125             g2.fill(st1);
 126 
 127             // Creates the pear itself by filling the Area resulting from the
 128             // union of two Area objects created by two different ellipses.
 129             Ellipse2D circle = new Ellipse2D.Double(x - 25, y, 50.0, 50.0);
 130             Ellipse2D oval = new Ellipse2D.Double(x - 19, y - 20, 40.0, 70.0);
 131             Area circ = new Area(circle);
 132             circ.add(new Area(oval));
 133 
 134             g2.setColor(YELLOW);
 135             g2.fill(circ);
 136             return;
 137         }
 138 
 139         g2.fill(area);
 140         g2.setColor(RED);
 141         g2.draw(area);
 142     }
 143 
 144     public static void main(String[] argv) {
 145         createDemoFrame(new Areas());
 146     }
 147 
 148 
 149     static final class DemoControls extends CustomControls implements
 150             ActionListener {
 151 
 152         Areas demo;
 153         JToolBar toolbar;
 154         JComboBox combo;
 155 
 156         public DemoControls(Areas demo) {
 157             super(demo.name);
 158             this.demo = demo;
 159             add(toolbar = new JToolBar());
 160             toolbar.setFloatable(false);
 161             addTool("nop", "no area operation", true);
 162             addTool("add", "add", false);
 163             addTool("sub", "subtract", false);
 164             addTool("xor", "exclusiveOr", false);
 165             addTool("int", "intersection", false);
 166             addTool("pear", "pear", false);
 167         }
 168 
 169         public void addTool(String str, String tooltip, boolean state) {
 170             JToggleButton b =
 171                     (JToggleButton) toolbar.add(new JToggleButton(str));
 172             b.setFocusPainted(false);
 173             b.setToolTipText(tooltip);
 174             b.setSelected(state);
 175             b.addActionListener(this);
 176             int width = b.getPreferredSize().width;
 177             Dimension prefSize = new Dimension(width, 21);
 178             b.setPreferredSize(prefSize);
 179             b.setMaximumSize(prefSize);
 180             b.setMinimumSize(prefSize);
 181         }
 182 
 183         @Override
 184         public void actionPerformed(ActionEvent e) {
 185             for (Component comp : toolbar.getComponents()) {
 186                 ((JToggleButton) comp).setSelected(false);
 187             }
 188             JToggleButton b = (JToggleButton) e.getSource();
 189             b.setSelected(true);
 190             demo.areaType = b.getText();
 191             demo.repaint();
 192         }
 193 
 194         @Override
 195         public Dimension getPreferredSize() {
 196             return new Dimension(200, 40);
 197         }
 198 
 199         @Override
 200         @SuppressWarnings("SleepWhileHoldingLock")
 201         public void run() {
 202             try {
 203                 Thread.sleep(1111);
 204             } catch (Exception e) {
 205                 return;
 206             }
 207             Thread me = Thread.currentThread();
 208             while (thread == me) {
 209                 for (Component comp : toolbar.getComponents()) {
 210                     ((AbstractButton) comp).doClick();
 211                     try {
 212                         Thread.sleep(4444);
 213                     } catch (InterruptedException e) {
 214                         return;
 215                     }
 216                 }
 217             }
 218             thread = null;
 219         }
 220     } // End DemoControls
 221 } // End Areas
 222