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 
Areas()55     public Areas() {
56         setBackground(WHITE);
57         setControls(new Component[] { new DemoControls(this) });
58     }
59 
60     @Override
render(int w, int h, Graphics2D g2)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 
main(String[] argv)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 
DemoControls(Areas demo)155         public DemoControls(Areas demo) {
156             super(demo.name);
157             this.demo = demo;
158             add(toolbar = new JToolBar());
159             toolbar.setFloatable(false);
160             addTool("nop", "no area operation", true);
161             addTool("add", "add", false);
162             addTool("sub", "subtract", false);
163             addTool("xor", "exclusiveOr", false);
164             addTool("int", "intersection", false);
165             addTool("pear", "pear", false);
166         }
167 
addTool(String str, String tooltip, boolean state)168         public void addTool(String str, String tooltip, boolean state) {
169             JToggleButton b =
170                     (JToggleButton) toolbar.add(new JToggleButton(str));
171             b.setFocusPainted(false);
172             b.setToolTipText(tooltip);
173             b.setSelected(state);
174             b.addActionListener(this);
175             int width = b.getPreferredSize().width;
176             Dimension prefSize = new Dimension(width, 21);
177             b.setPreferredSize(prefSize);
178             b.setMaximumSize(prefSize);
179             b.setMinimumSize(prefSize);
180         }
181 
182         @Override
actionPerformed(ActionEvent e)183         public void actionPerformed(ActionEvent e) {
184             for (Component comp : toolbar.getComponents()) {
185                 ((JToggleButton) comp).setSelected(false);
186             }
187             JToggleButton b = (JToggleButton) e.getSource();
188             b.setSelected(true);
189             demo.areaType = b.getText();
190             demo.repaint();
191         }
192 
193         @Override
getPreferredSize()194         public Dimension getPreferredSize() {
195             return new Dimension(200, 40);
196         }
197 
198         @Override
199         @SuppressWarnings("SleepWhileHoldingLock")
run()200         public void run() {
201             try {
202                 Thread.sleep(1111);
203             } catch (Exception e) {
204                 return;
205             }
206             Thread me = Thread.currentThread();
207             while (thread == me) {
208                 for (Component comp : toolbar.getComponents()) {
209                     ((AbstractButton) comp).doClick();
210                     try {
211                         Thread.sleep(4444);
212                     } catch (InterruptedException e) {
213                         return;
214                     }
215                 }
216             }
217             thread = null;
218         }
219     } // End DemoControls
220 } // End Areas
221 
222