/* * * 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.Mix; import static java.awt.Color.LIGHT_GRAY; import static java.awt.Color.WHITE; import static java.lang.Math.random; import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.GeneralPath; import java.awt.geom.Path2D; import java.awt.geom.PathIterator; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java2d.AnimatingControlsSurface; import java2d.CustomControls; import javax.swing.AbstractButton; import javax.swing.JToggleButton; import javax.swing.JToolBar; /** * Animated Bezier Curve shape with images at the control points. * README.txt file scrolling up. Composited Image fading in and out. */ @SuppressWarnings("serial") public class BezierScroller extends AnimatingControlsSurface { private static String[] appletStrs = { " ", "J2Ddemo", "BezierScroller - Animated Bezier Curve shape with images", "For README.txt file scrolling run in application mode", " " }; private static final int NUMPTS = 6; private static Color greenBlend = new Color(0, 255, 0, 100); private static Color blueBlend = new Color(0, 0, 255, 100); private static Font font = new Font(Font.SERIF, Font.PLAIN, 12); private static BasicStroke bs = new BasicStroke(3.0f); private static Image hotj_img; private static BufferedImage img; private static final int UP = 0; private static final int DOWN = 1; private float[] animpts = new float[NUMPTS * 2]; private float[] deltas = new float[NUMPTS * 2]; private BufferedReader reader; private int nStrs; private int strH; private int yy, ix, iy, imgX; private List vector, appletVector; private float alpha = 0.2f; private int alphaDirection; protected boolean doImage, doShape, doText; protected boolean buttonToggle; /* * Using this to scale down globe.png since we want a smaller version, * I know it is 100 x 160 and has a transparent pixel. */ private Image scaled(Image src) { int sw = src.getWidth(null); int sh = src.getHeight(null); int dw = sw/5; int dh = sh/5; BufferedImage bi = new BufferedImage(dw, dh, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = bi.createGraphics(); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g2d.drawImage(src, 0, 0, dw, dh, 0, 0, sw, sh, null); g2d.dispose(); return bi; } @SuppressWarnings("LeakingThisInConstructor") public BezierScroller() { setBackground(WHITE); doShape = doText = true; hotj_img = scaled(getImage("globe.png")); Image image = getImage("jumptojavastrip.png"); int iw = image.getWidth(this); int ih = image.getHeight(this); img = new BufferedImage(iw, ih, BufferedImage.TYPE_INT_RGB); img.createGraphics().drawImage(image, 0, 0, this); setControls(new Component[] { new DemoControls(this) }); } public void animate(float[] pts, float[] deltas, int index, int limit) { float newpt = pts[index] + deltas[index]; if (newpt <= 0) { newpt = -newpt; deltas[index] = (float) (random() * 4.0 + 2.0); } else if (newpt >= limit) { newpt = 2.0f * limit - newpt; deltas[index] = -(float) (random() * 4.0 + 2.0); } pts[index] = newpt; } public void getFile() { try { String fName = "README.txt"; if ((reader = new BufferedReader(new FileReader(fName))) != null) { getLine(); } } catch (Exception e) { reader = null; } if (reader == null) { appletVector = new ArrayList(100); for (int i = 0; i < 100; i++) { appletVector.add(appletStrs[i % appletStrs.length]); } getLine(); } buttonToggle = true; } public String getLine() { String str = null; if (reader != null) { try { if ((str = reader.readLine()) != null) { if (str.length() == 0) { str = " "; } vector.add(str); } } catch (Exception e) { Logger.getLogger(BezierScroller.class.getName()).log( Level.SEVERE, null, e); reader = null; } } else { if (!appletVector.isEmpty()) { vector.add(str = appletVector.remove(0)); } } return str; } @Override public void reset(int w, int h) { for (int i = 0; i < animpts.length; i += 2) { animpts[i + 0] = (float) (random() * w); animpts[i + 1] = (float) (random() * h); deltas[i + 0] = (float) (random() * 6.0 + 4.0); deltas[i + 1] = (float) (random() * 6.0 + 4.0); if (animpts[i + 0] > w / 2.0f) { deltas[i + 0] = -deltas[i + 0]; } if (animpts[i + 1] > h / 2.0f) { deltas[i + 1] = -deltas[i + 1]; } } FontMetrics fm = getFontMetrics(font); strH = fm.getAscent() + fm.getDescent(); nStrs = h / strH + 2; vector = new ArrayList(nStrs); ix = (int) (random() * (w - 80)); iy = (int) (random() * (h - 80)); } @Override public void step(int w, int h) { if (doText && vector.isEmpty()) { getFile(); } if (doText) { String s = getLine(); if (s == null || vector.size() == nStrs && !vector.isEmpty()) { vector.remove(0); } yy = (s == null) ? 0 : h - vector.size() * strH; } for (int i = 0; i < animpts.length && doShape; i += 2) { animate(animpts, deltas, i + 0, w); animate(animpts, deltas, i + 1, h); } if (doImage && alphaDirection == UP) { if ((alpha += 0.025) > .99) { alphaDirection = DOWN; alpha = 1.0f; } } else if (doImage && alphaDirection == DOWN) { if ((alpha -= .02) < 0.01) { alphaDirection = UP; alpha = 0; ix = (int) (random() * (w - 80)); iy = (int) (random() * (h - 80)); } } if (doImage) { if ((imgX += 80) == 800) { imgX = 0; } } } @Override public void render(int w, int h, Graphics2D g2) { if (doText) { g2.setColor(LIGHT_GRAY); g2.setFont(font); float y = yy; //for (int i = 0; i < vector.size(); i++) { for (String string : vector) { g2.drawString(string, 1, y += strH); } } if (doShape) { float[] ctrlpts = animpts; int len = ctrlpts.length; float prevx = ctrlpts[len - 2]; float prevy = ctrlpts[len - 1]; float curx = ctrlpts[0]; float cury = ctrlpts[1]; float midx = (curx + prevx) / 2.0f; float midy = (cury + prevy) / 2.0f; GeneralPath gp = new GeneralPath(Path2D.WIND_NON_ZERO); gp.moveTo(midx, midy); for (int i = 2; i <= ctrlpts.length; i += 2) { float x1 = (midx + curx) / 2.0f; float y1 = (midy + cury) / 2.0f; prevx = curx; prevy = cury; if (i < ctrlpts.length) { curx = ctrlpts[i + 0]; cury = ctrlpts[i + 1]; } else { curx = ctrlpts[0]; cury = ctrlpts[1]; } midx = (curx + prevx) / 2.0f; midy = (cury + prevy) / 2.0f; float x2 = (prevx + midx) / 2.0f; float y2 = (prevy + midy) / 2.0f; gp.curveTo(x1, y1, x2, y2, midx, midy); } gp.closePath(); g2.setColor(blueBlend); g2.setStroke(bs); g2.draw(gp); g2.setColor(greenBlend); g2.fill(gp); PathIterator pi = gp.getPathIterator(null); float[] pts = new float[6]; while (!pi.isDone()) { if (pi.currentSegment(pts) == PathIterator.SEG_CUBICTO) { g2.drawImage(hotj_img, (int) pts[0], (int) pts[1], this); } pi.next(); } } if (doImage) { AlphaComposite ac = AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha); g2.setComposite(ac); g2.drawImage(img.getSubimage(imgX, 0, 80, 80), ix, iy, this); } } public static void main(String[] argv) { createDemoFrame(new BezierScroller()); } static final class DemoControls extends CustomControls implements ActionListener { BezierScroller demo; JToolBar toolbar; public DemoControls(BezierScroller demo) { super(demo.name); this.demo = demo; add(toolbar = new JToolBar()); toolbar.setFloatable(false); addTool("Image", false); addTool("Shape", true); addTool("Text", true); } 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("Image")) { demo.doImage = b.isSelected(); } else if (b.getText().equals("Shape")) { demo.doShape = b.isSelected(); } else { demo.doText = b.isSelected(); } if (!demo.animating.running()) { demo.repaint(); } } @Override public Dimension getPreferredSize() { return new Dimension(200, 40); } @Override @SuppressWarnings("SleepWhileHoldingLock") public void run() { Thread me = Thread.currentThread(); int i = 0; while (thread == me) { try { Thread.sleep(250); } catch (InterruptedException e) { return; } if (demo.buttonToggle) { ((AbstractButton) toolbar.getComponentAtIndex(i++ % 2)). doClick(); demo.buttonToggle = false; } } thread = null; } } // End DemoControls } // End BezierScroller