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