You are here:Home » Java 2D » Effects in Java 2D

Effects in Java 2D

Effects

In this part of the Java 2D programming tutorial, we will show some effects.

Bubbles

In the first example, we will see growing coloured bubbles, that randomly appear and disappear on the screen. The example comes from the Java 2D demo.
Bubbles.java
package com.zetcode;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class Bubbles extends JPanel implements ActionListener {


private static Color colors[] = {
Color.blue, Color.cyan, Color.green,
Color.magenta, Color.orange, Color.pink,
Color.red, Color.yellow, Color.lightGray, Color.white
};


private Ellipse2D.Float[] ellipses;
private double esize[];
private float estroke[];
private double maxSize = 0;
private boolean initialize = true;

Timer timer;
ActionListener updateProBar;


public Bubbles() {

setBackground(Color.black);
ellipses = new Ellipse2D.Float[25];
esize = new double[ellipses.length];
estroke = new float[ellipses.length];

for (int i = 0; i < ellipses.length; i++) {
ellipses[i] = new Ellipse2D.Float();
getRandomXY(i, 20 * Math.random(), 200, 200);
}

timer = new Timer(20, this);
timer.setInitialDelay(190);
timer.start();
}


public void getRandomXY(int i, double size, int w, int h) {

esize[i] = size;
estroke[i] = 1.0f;
double x = Math.random() * (w - (maxSize / 2));
double y = Math.random() * (h - (maxSize / 2));
ellipses[i].setFrame(x, y, size, size);
}


public void reset(int w, int h) {

maxSize = w / 10;
for (int i = 0; i < ellipses.length; i++) {
getRandomXY(i, maxSize * Math.random(), w, h);
}
}


public void step(int w, int h) {

for (int i = 0; i < ellipses.length; i++) {

estroke[i] += 0.025f;
esize[i]++;

if (esize[i] > maxSize) {
getRandomXY(i, 1, w, h);

} else {
ellipses[i].setFrame(ellipses[i].getX(), ellipses[i].getY(),
esize[i], esize[i]);
}
}
}


public void render(int w, int h, Graphics2D g2) {

for (int i = 0; i < ellipses.length; i++) {
g2.setColor(colors[i % colors.length]);
g2.setStroke(new BasicStroke(estroke[i]));
g2.draw(ellipses[i]);
}
}


public void paint(Graphics g) {

super.paintComponent(g);

Graphics2D g2 = (Graphics2D)g;

RenderingHints rh =
new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);

g2.setRenderingHints(rh);
Dimension size = getSize();

if (initialize) {
reset(size.width, size.height);
initialize = false;
}

this.step(size.width, size.height);

render(size.width, size.height, g2);

}


public void actionPerformed(ActionEvent e) {
repaint();
}

public static void main(String[] args) {

JFrame frame = new JFrame("Bubbles");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Bubbles());
frame.setSize(350, 250);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
This is bubbles example.
private static Color colors[] = { 
Color.blue, Color.cyan, Color.green,
Color.magenta, Color.orange, Color.pink,
Color.red, Color.yellow, Color.lightGray, Color.white
};
These are the colors of the bubbles.
esize = new double[ellipses.length];
estroke = new float[ellipses.length];
These are size and stroke arrays. Both size and stroke of the bubble grow during the animation.
esize[i] = size;
estroke[i] = 1.0f;
double x = Math.random() * (w - (maxSize / 2));
double y = Math.random() * (h - (maxSize / 2));
ellipses[i].setFrame(x, y, size, size);
In the getRandomXY() method, we set the default size and stroke and set a random position for the bubble.
estroke[i] += 0.025f;
esize[i]++;
In every animation step, the stroke and the size of the bubble grows.
if (esize[i] > maxSize) {
getRandomXY(i, 1, w, h);

} else {
ellipses[i].setFrame(ellipses[i].getX(), ellipses[i].getY(),
esize[i], esize[i]);
}
After the bubble reaches its maximum size, it is reset to the minimum size and randomly repositioned on the panel. Else it is displayed as it is.
Bubbles
Figure: Bubbles

Star

The next example shows a rotating and scaling star.
Star.java
package com.zetcode;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.GeneralPath;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Star extends JPanel implements ActionListener {

double points[][] = {
{ 0, 85 }, { 75, 75 }, { 100, 10 }, { 125, 75 },
{ 200, 85 }, { 150, 125 }, { 160, 190 }, { 100, 150 },
{ 40, 190 }, { 50, 125 }, { 0, 85 }
};

Timer timer;

private double angle = 0;
private double scale = 1;
private double delta = 0.01;

public Star() {

timer = new Timer(10, this);
timer.start();
}

public void paint(Graphics g) {
super.paint(g);

int h = getHeight();
int w = getWidth();


Graphics2D g2d = (Graphics2D)g;

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);

g2d.translate(w/2, h/2);
GeneralPath star = new GeneralPath();
star.moveTo(points[0][0], points[0][1]);

for (int k = 1; k < points.length; k++)
star.lineTo(points[k][0], points[k][1]);

star.closePath();
g2d.rotate(angle);
g2d.scale(scale, scale);

g2d.fill(star);
}

public static void main(String[] args) {

JFrame frame = new JFrame("Moving star");
frame.add(new Star());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(420, 250);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}


public void actionPerformed(ActionEvent e) {

if ( scale < 0.01 ) {
delta = -delta;
} else if (scale > 0.99) {
delta = -delta;
}

scale += delta;
angle += 0.01;

repaint();
}
}
In this demo, we have a star. The star rotates and grows and then shrinks. Quite a nice demo.
double points[][] = { 
{ 0, 85 }, { 75, 75 }, { 100, 10 }, { 125, 75 },
{ 200, 85 }, { 150, 125 }, { 160, 190 }, { 100, 150 },
{ 40, 190 }, { 50, 125 }, { 0, 85 }
};
These points are used to draw the star.
private double angle = 0;
private double scale = 1;
private double delta = 0.01;
The angle is used when we rotate the star. The scale factor determines the size of the star. Finally, the delta factor is the amount of the change of the scale.
if ( scale < 0.01 ) {
delta = -delta;
} else if (scale > 0.99) {
delta = -delta;
}
Here the star stops shrinking and starts growing and vice versa.

Puff

Next we show a puff effect.
Star.java
package com.zetcode;

import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class Puff extends JPanel implements ActionListener {

Timer timer;
int x = 1;
float alpha = 1;

public Puff() {
timer = new Timer(8, this);
timer.setInitialDelay(190);
timer.start();
}

public void paint(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;

RenderingHints rh =
new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);

g2d.setRenderingHints(rh);

Font font = new Font("Dialog", Font.PLAIN, x);
g2d.setFont(font);

FontMetrics fm = g2d.getFontMetrics();
String s = "ZetCode";
Dimension size = getSize();

int w = (int) size.getWidth();
int h = (int) size.getHeight();

int stringWidth = fm.stringWidth(s);

g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
alpha));

g2d.drawString(s, (w - stringWidth) / 2, h / 2);
}


public static void main(String[] args) {

JFrame frame = new JFrame("Puff");
frame.add(new Puff());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public void actionPerformed(ActionEvent e) {
x += 1;

if (x > 40)
alpha -= 0.01;

if (alpha <= 0.01)
timer.stop();
repaint();
}
}
This effect is common in flash animations or film intros. Text grows gradually on the screen and after some time it slowly disappears.
Font font = new Font("Dialog", Font.PLAIN, x);
g2d.setFont(font);
This is the font that we use for our text.
FontMetrics fm = g2d.getFontMetrics();
Here we get the FontMetrics class. The class stores information about the rendering of a particular font on a particular screen.
int stringWidth = fm.stringWidth(s);
We use the stringWidth() method of the FontMetrics object to get the width of our screen. We need it in order to place the text in the middle of the screen.
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
Here we set the transparency of the text being drawn.
g2d.drawString(s, (w - stringWidth) / 2, h / 2);
This code line draws the string in the (horizontal) middle of the screen.
if (x > 40)
alpha -= 0.01;
After the string is 40 pixels big, it begins fading.
In this part of the Java 2D tutorial, we did some visual effects.

0 comments:

Post a Comment