// JavaProject MysteriousShapes
Mausklicks starten bzw. stoppen nebenläufige Animationen.
Wird die im Programmfenster erscheinende Ellipse bzw. das Rechteck mit der
Maus angeklickt, verändern sich kontinuierlich die Transparenzwerte beider
Figuren. In dem Moment, wo eine Figur verschwindet, ändert sich die
Position dieser Figur innerhalb des Fensters.
Wesentlich für das Ein- bzw. Ausblenden der Figuren ist das AlphaComposite-Objekt ac, bestehend aus der von der Klasse AlphaComposite bereitgestellten Compositing-Regel SRC_OVER und einem alpha-Wert zwischen 0.0f und 1.0f. Die Regel SRC_OVER besagt, dass die jeweils neu zu zeichnende Figur genau über der vorhandenen Figur gezeichnet werden soll; alpha bestimmt den Grad der Transparenz der neuen Figur (1.0f: völlig undurchsichtig, 0.0f: unsichtbar).
Die threads thread_ellipse und thread_rectangle laufen gleichzeitig und unabhängig voneinander ab.
// MysteriousShapes.java
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
class Canvas extends JPanel {
private static final long serialVersionUID = 0L;
private Ellipse2D ellipse;
private Rectangle2D rectangle;
private float alpha_ellipse;
private float alpha_rectangle;
private float diff_alpha_ellipse = -0.01f;
private float diff_alpha_rectangle = -0.01f;
private Color color_ellipse = new Color(100, 90, 255);
private Color color_rectangle = new Color(246, 118, 14);
private float x_e, y_e;
private float x_r, y_r;
boolean ellipse_active;
boolean ellipse_interrupted;
boolean rectangle_active;
boolean rectangle_interrupted;
public void randomizeUpperLeftPointEllipse() {
x_e = (float) (233*Math.random());
y_e = (float) (201*Math.random());
}
public void randomizeUpperLeftPointRectangle() {
x_r = (float) (273*Math.random());
y_r = (float) (201*Math.random());
}
public Canvas() {
addMouseListener(new Adapter());
randomizeUpperLeftPointEllipse();
randomizeUpperLeftPointRectangle();
ellipse = new Ellipse2D.Float(x_e, y_e, 100f, 60f);
rectangle = new Rectangle2D.Float(x_r, y_r, 60f, 60f);
alpha_ellipse = 1f;
alpha_rectangle = 1f;
}
private void defineRendering(Graphics2D g) {
RenderingHints rh;
rh = new RenderingHints (
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
);
g.setRenderingHints(rh);
}
private void defineComposite(Graphics2D g, float alpha) {
AlphaComposite ac;
ac = AlphaComposite.getInstance (
AlphaComposite.SRC_OVER,
alpha
);
g.setComposite(ac);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
defineRendering(g2d);
g2d.setPaint(color_ellipse);
defineComposite(g2d, alpha_ellipse);
g2d.fill(ellipse);
g2d.setPaint(color_rectangle);
defineComposite(g2d, alpha_rectangle);
g2d.fill(rectangle);
g2d.dispose();
}
class Adapter extends MouseAdapter {
RunnableEllipse run_e;
RunnableRectangle run_r;
@Override
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if (ellipse.contains(x, y)) {
if (ellipse_active) {
ellipse_interrupted = true;
ellipse_active = false;
} else {
run_e = new RunnableEllipse();
ellipse_interrupted = false;
run_e.thread_ellipse.start();
}
}
if (rectangle.contains(x, y)) {
if (rectangle_active) {
rectangle_interrupted = true;
rectangle_active = false;
} else {
run_r = new RunnableRectangle();
rectangle_interrupted = false;
run_r.thread_rectangle.start();
}
}
}
}
class RunnableEllipse implements Runnable {
Thread thread_ellipse;
public RunnableEllipse() {
thread_ellipse = new Thread(this);
ellipse_active = true;
}
@Override
public void run() {
while (!ellipse_interrupted) {
repaint();
alpha_ellipse += diff_alpha_ellipse;
if (alpha_ellipse < 0) {
randomizeUpperLeftPointEllipse();
ellipse = new Ellipse2D.Float(x_e, y_e, 100f, 60f);
alpha_ellipse = 0;
diff_alpha_ellipse = -diff_alpha_ellipse;
}
if (alpha_ellipse > 1) {
alpha_ellipse = 1;
diff_alpha_ellipse = -diff_alpha_ellipse;
}
try {
Thread.sleep(40);
}
catch (InterruptedException e) { }
}
}
}
class RunnableRectangle implements Runnable {
Thread thread_rectangle;
public RunnableRectangle() {
thread_rectangle = new Thread(this);
rectangle_active = true;
}
@Override
public void run() {
while (!rectangle_interrupted) {
repaint();
alpha_rectangle += diff_alpha_rectangle;
if (alpha_rectangle < 0) {
randomizeUpperLeftPointRectangle();
rectangle = new Rectangle2D.Float(x_r, y_r, 60f, 60f);
alpha_rectangle = 0;
diff_alpha_rectangle = -diff_alpha_rectangle;
}
if (alpha_rectangle > 1) {
alpha_rectangle = 1;
diff_alpha_rectangle = -diff_alpha_rectangle;
}
try {
Thread.sleep(30);
} catch (InterruptedException e) { }
}
}
}
}
class CFrame extends JFrame {
private static final long serialVersionUID = 0L;
Image icon;
public CFrame() {
setTitle("Mysteriöse Figuren");
icon = Toolkit.getDefaultToolkit().getImage("dh.png");
setIconImage(icon);
setSize(349, 301);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
add(new Canvas());
setVisible(true);
}
}
public class MysteriousShapes {
public static void main(String[] args) {
new CFrame();
}
}
