/* * * Copyright (c) 2007, 2018, Oracle and/or its affiliates. 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 Oracle 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. */ package java2d.demos.Clipping; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.image.BufferedImage; import javax.swing.*; import java2d.AnimatingControlsSurface; import java2d.CustomControls; import static java.lang.Math.random; import static java.awt.Color.*; /** * Animated clipping of an image & composited shapes. */ @SuppressWarnings("serial") public class ClipAnim extends AnimatingControlsSurface { private static Image dimg, cimg; static TexturePaint texturePaint; static { BufferedImage bi = new BufferedImage(5, 5, BufferedImage.TYPE_INT_RGB); Graphics2D big = bi.createGraphics(); big.setBackground(YELLOW); big.clearRect(0, 0, 5, 5); big.setColor(RED); big.fillRect(0, 0, 3, 3); texturePaint = new TexturePaint(bi, new Rectangle(0, 0, 5, 5)); } private AnimVal[] animval = new AnimVal[3]; protected boolean doObjects = true; private Font originalFont = new Font(Font.SERIF, Font.PLAIN, 12); private Font font; private GradientPaint gradient; private int strX, strY; private int dukeX, dukeY, dukeWidth, dukeHeight; public ClipAnim() { cimg = getImage("clouds.jpg"); dimg = getImage("duke.png"); setBackground(WHITE); animval[0] = new AnimVal(true); animval[1] = new AnimVal(false); animval[2] = new AnimVal(false); setControls(new Component[] { new DemoControls(this) }); } @Override public void reset(int w, int h) { for (AnimVal a : animval) { a.reset(w, h); } gradient = new GradientPaint(0, h / 2, RED, w * .4f, h * .9f, YELLOW); double scale = 0.4; dukeHeight = (int) (scale * h); dukeWidth = (int) (dimg.getWidth(this) * scale * h / dimg.getHeight(this)); dukeX = (int) (w * .25 - dukeWidth / 2); dukeY = (int) (h * .25 - dukeHeight / 2); FontMetrics fm = getFontMetrics(originalFont); double sw = fm.stringWidth("CLIPPING"); double sh = fm.getAscent() + fm.getDescent(); double sx = (w / 2 - 30) / sw; double sy = (h / 2 - 30) / sh; AffineTransform Tx = AffineTransform.getScaleInstance(sx, sy); font = originalFont.deriveFont(Tx); fm = getFontMetrics(font); strX = (int) (w * .75 - fm.stringWidth("CLIPPING") / 2); strY = (int) (h * .72 + fm.getAscent() / 2); } @Override public void step(int w, int h) { for (AnimVal a : animval) { if (a.isSelected) { a.step(w, h); } } } @Override public void render(int w, int h, Graphics2D g2) { GeneralPath p1 = new GeneralPath(); GeneralPath p2 = new GeneralPath(); for (AnimVal a : animval) { if (a.isSelected) { double x = a.x; double y = a.y; double ew = a.ew; double eh = a.eh; p1.append(new Ellipse2D.Double(x, y, ew, eh), false); p2.append(new Rectangle2D.Double(x + 5, y + 5, ew - 10, eh - 10), false); } } if (animval[0].isSelected || animval[1].isSelected || animval[2].isSelected) { g2.setClip(p1); g2.clip(p2); } if (doObjects) { int w2 = w / 2; int h2 = h / 2; g2.drawImage(cimg, 0, 0, w2, h2, null); g2.drawImage(dimg, dukeX, dukeY, dukeWidth, dukeHeight, null); g2.setPaint(texturePaint); g2.fillRect(w2, 0, w2, h2); g2.setPaint(gradient); g2.fillRect(0, h2, w2, h2); g2.setColor(LIGHT_GRAY); g2.fillRect(w2, h2, w2, h2); g2.setColor(RED); g2.drawOval(w2, h2, w2 - 1, h2 - 1); g2.setFont(font); g2.drawString("CLIPPING", strX, strY); } else { g2.setColor(LIGHT_GRAY); g2.fillRect(0, 0, w, h); } } public static void main(String[] argv) { createDemoFrame(new ClipAnim()); } public class AnimVal { double ix = 5.0; double iy = 3.0; double iw = 5.0; double ih = 3.0; double x, y; double ew, eh; // ellipse width & height boolean isSelected; public AnimVal(boolean isSelected) { this.isSelected = isSelected; } public void step(int w, int h) { x += ix; y += iy; ew += iw; eh += ih; if (ew > w / 2) { ew = w / 2; iw = random() * -w / 16 - 1; } if (ew < w / 8) { ew = w / 8; iw = random() * w / 16 + 1; } if (eh > h / 2) { eh = h / 2; ih = random() * -h / 16 - 1; } if (eh < h / 8) { eh = h / 8; ih = random() * h / 16 + 1; } if ((x + ew) > w) { x = (w - ew) - 1; ix = random() * -w / 32 - 1; } if ((y + eh) > h) { y = (h - eh) - 2; iy = random() * -h / 32 - 1; } if (x < 0) { x = 2; ix = random() * w / 32 + 1; } if (y < 0) { y = 2; iy = random() * h / 32 + 1; } } public void reset(int w, int h) { x = random() * w; y = random() * h; ew = (random() * w) / 2; eh = (random() * h) / 2; } } static final class DemoControls extends CustomControls implements ActionListener { ClipAnim demo; JToolBar toolbar; public DemoControls(ClipAnim demo) { super(demo.name); this.demo = demo; add(toolbar = new JToolBar()); toolbar.setFloatable(false); addTool("Objects", true); addTool("Clip1", true); addTool("Clip2", false); addTool("Clip3", false); } public void addTool(String str, boolean state) { JToggleButton b = (JToggleButton) toolbar.add(new JToggleButton(str)); b.setFocusPainted(false); b.setSelected(state); b.addActionListener(this); int width = b.getPreferredSize().width; Dimension prefSize = new Dimension(width, 21); b.setPreferredSize(prefSize); b.setMaximumSize(prefSize); b.setMinimumSize(prefSize); } @Override public void actionPerformed(ActionEvent e) { JToggleButton b = (JToggleButton) e.getSource(); if (b.getText().equals("Objects")) { demo.doObjects = b.isSelected(); } else if (b.getText().equals("Clip1")) { demo.animval[0].isSelected = b.isSelected(); } else if (b.getText().equals("Clip2")) { demo.animval[1].isSelected = b.isSelected(); } else if (b.getText().equals("Clip3")) { demo.animval[2].isSelected = b.isSelected(); } if (!demo.animating.running()) { demo.repaint(); } } @Override public Dimension getPreferredSize() { return new Dimension(200, 40); } @Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { return; } ((AbstractButton) toolbar.getComponentAtIndex(2)).doClick(); try { Thread.sleep(5000); } catch (InterruptedException e) { return; } if (getSize().width > 400) { ((AbstractButton) toolbar.getComponentAtIndex(3)).doClick(); } thread = null; } } // End DemoControls } // End ClipAnim