blob: 14321f6dae2e3e73af2588e7d247855488bf2543 [file] [log] [blame]
/*
*
* Copyright (c) 2007, 2011, 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.Arcs_Curves;
import static java.awt.Color.BLUE;
import static java.awt.Color.GRAY;
import static java.awt.Color.GREEN;
import static java.awt.Color.RED;
import static java.awt.Color.WHITE;
import static java.awt.Color.YELLOW;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
import java.awt.image.BufferedImage;
import java2d.AnimatingControlsSurface;
import java2d.CustomControls;
import javax.swing.Icon;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
/**
* Animated Bezier Curve with controls for different draw & fill paints.
*/
@SuppressWarnings("serial")
public class BezierAnim extends AnimatingControlsSurface {
private static final int NUMPTS = 6;
protected BasicStroke solid = new BasicStroke(10.0f,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
protected BasicStroke dashed = new BasicStroke(10.0f,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 10, new float[] { 5 },
0);
private float animpts[] = new float[NUMPTS * 2];
private float deltas[] = new float[NUMPTS * 2];
protected Paint fillPaint, drawPaint;
protected boolean doFill = true;
protected boolean doDraw = true;
protected GradientPaint gradient;
protected BasicStroke stroke;
public BezierAnim() {
setBackground(WHITE);
gradient = new GradientPaint(0, 0, RED, 200, 200, YELLOW);
fillPaint = gradient;
drawPaint = BLUE;
stroke = solid;
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) (Math.random() * 4.0 + 2.0);
} else if (newpt >= limit) {
newpt = 2.0f * limit - newpt;
deltas[index] = -(float) (Math.random() * 4.0 + 2.0);
}
pts[index] = newpt;
}
@Override
public void reset(int w, int h) {
for (int i = 0; i < animpts.length; i += 2) {
animpts[i + 0] = (float) (Math.random() * w);
animpts[i + 1] = (float) (Math.random() * h);
deltas[i + 0] = (float) (Math.random() * 6.0 + 4.0);
deltas[i + 1] = (float) (Math.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];
}
}
gradient = new GradientPaint(0, 0, RED, w * .7f, h * .7f, YELLOW);
}
@Override
public void step(int w, int h) {
for (int i = 0; i < animpts.length; i += 2) {
animate(animpts, deltas, i + 0, w);
animate(animpts, deltas, i + 1, h);
}
}
@Override
public void render(int w, int h, Graphics2D g2) {
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();
if (doDraw) {
g2.setPaint(drawPaint);
g2.setStroke(stroke);
g2.draw(gp);
}
if (doFill) {
if (fillPaint instanceof GradientPaint) {
fillPaint = gradient;
}
g2.setPaint(fillPaint);
g2.fill(gp);
}
}
public static void main(String argv[]) {
createDemoFrame(new BezierAnim());
}
static class DemoControls extends CustomControls implements ActionListener {
static final TexturePaint tp1, tp2;
static {
BufferedImage bi = new BufferedImage(2, 1,
BufferedImage.TYPE_INT_RGB);
bi.setRGB(0, 0, 0xff00ff00);
bi.setRGB(1, 0, 0xffff0000);
tp1 = new TexturePaint(bi, new Rectangle(0, 0, 2, 1));
bi = new BufferedImage(2, 1, BufferedImage.TYPE_INT_RGB);
bi.setRGB(0, 0, 0xff0000ff);
bi.setRGB(1, 0, 0xffff0000);
tp2 = new TexturePaint(bi, new Rectangle(0, 0, 2, 1));
}
BezierAnim demo;
static Paint drawPaints[] = { new Color(0, 0, 0, 0), BLUE, new Color(0,
0, 255, 126),
BLUE, tp2 };
static String drawName[] = { "No Draw", "Blue", "Blue w/ Alpha",
"Blue Dash", "Texture" };
static Paint fillPaints[] = { new Color(0, 0, 0, 0), GREEN, new Color(0,
255, 0, 126),
tp1, new GradientPaint(0, 0, RED, 30, 30, YELLOW) };
String fillName[] = { "No Fill", "Green", "Green w/ Alpha", "Texture",
"Gradient" };
JMenu fillMenu, drawMenu;
JMenuItem fillMI[] = new JMenuItem[fillPaints.length];
JMenuItem drawMI[] = new JMenuItem[drawPaints.length];
PaintedIcon fillIcons[] = new PaintedIcon[fillPaints.length];
PaintedIcon drawIcons[] = new PaintedIcon[drawPaints.length];
Font font = new Font(Font.SERIF, Font.PLAIN, 10);
@SuppressWarnings("LeakingThisInConstructor")
public DemoControls(BezierAnim demo) {
super(demo.name);
this.demo = demo;
JMenuBar drawMenuBar = new JMenuBar();
add(drawMenuBar);
JMenuBar fillMenuBar = new JMenuBar();
add(fillMenuBar);
drawMenu = drawMenuBar.add(new JMenu("Draw Choice"));
drawMenu.setFont(font);
for (int i = 0; i < drawPaints.length; i++) {
drawIcons[i] = new PaintedIcon(drawPaints[i]);
drawMI[i] = drawMenu.add(new JMenuItem(drawName[i]));
drawMI[i].setFont(font);
drawMI[i].setIcon(drawIcons[i]);
drawMI[i].addActionListener(this);
}
drawMenu.setIcon(drawIcons[1]);
fillMenu = fillMenuBar.add(new JMenu("Fill Choice"));
fillMenu.setFont(font);
for (int i = 0; i < fillPaints.length; i++) {
fillIcons[i] = new PaintedIcon(fillPaints[i]);
fillMI[i] = fillMenu.add(new JMenuItem(fillName[i]));
fillMI[i].setFont(font);
fillMI[i].setIcon(fillIcons[i]);
fillMI[i].addActionListener(this);
}
fillMenu.setIcon(fillIcons[fillPaints.length - 1]);
}
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
for (int i = 0; i < fillPaints.length; i++) {
if (obj.equals(fillMI[i])) {
demo.doFill = true;
demo.fillPaint = fillPaints[i];
fillMenu.setIcon(fillIcons[i]);
break;
}
}
for (int i = 0; i < drawPaints.length; i++) {
if (obj.equals(drawMI[i])) {
demo.doDraw = true;
demo.drawPaint = drawPaints[i];
if (((JMenuItem) obj).getText().endsWith("Dash")) {
demo.stroke = demo.dashed;
} else {
demo.stroke = demo.solid;
}
drawMenu.setIcon(drawIcons[i]);
break;
}
}
if (obj.equals(fillMI[0])) {
demo.doFill = false;
} else if (obj.equals(drawMI[0])) {
demo.doDraw = false;
}
if (!demo.animating.running()) {
demo.repaint();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 36);
}
@Override
@SuppressWarnings("SleepWhileHoldingLock")
public void run() {
Thread me = Thread.currentThread();
while (thread == me) {
for (JMenuItem dmi : drawMI) {
dmi.doClick();
for (JMenuItem fmi : fillMI) {
fmi.doClick();
try {
Thread.sleep(3000 + (long) (Math.random() * 3000));
} catch (InterruptedException e) {
break;
}
}
}
}
thread = null;
}
static class PaintedIcon implements Icon {
Paint paint;
public PaintedIcon(Paint p) {
this.paint = p;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(paint);
g2.fillRect(x, y, getIconWidth(), getIconHeight());
g2.setColor(GRAY);
g2.draw3DRect(x, y, getIconWidth() - 1, getIconHeight() - 1,
true);
}
@Override
public int getIconWidth() {
return 12;
}
@Override
public int getIconHeight() {
return 12;
}
} // End PaintedIcon class
} // End DemoControls class
} // End BezierAnim class