package javacodebook.media.animation; import java.awt.*; import java.awt.geom.*; import java.awt.image.*; import javax.swing.*; /** * Eine einfache Animation, bei der die Bewegung eines Planeten um eine Sonne * und eines Mondes um den Planeten simuliert wird. Physikalisch absolut nicht * überprüft ;-) */ public class Animator extends JComponent implements Runnable{ double earthArc = 0; double moonArc = 0; private BufferedImage bufImage; /* Ausführung der Animation innerhalb eines Threads. */ public void run() { while(true) { //neu Zeichnen animate(); //kurze Pause einlegen try { Thread.sleep(10); } catch(InterruptedException e) { e.printStackTrace(System.out); } } } /** * Hier werden die Berechnungen zur Bewegung der Objekte durchgeführt und * die Objekte erst auf einem Offscreen-Image gezeichnet, dann auf den * Bildschirm. */ public void animate() { //Die Erde im Gegenuhrzeigersinn um die Sonne drehen earthArc -= Math.PI / 360; if(earthArc >= Math.PI*2) earthArc = 0; //den Mond im Uhrzeigersinn um die Erde drehen moonArc += Math.PI / 60; if(moonArc >= Math.PI*2) moonArc = 0; //Eine Referenz auf den Grafik-Kontext der Komponente holen Graphics g = getGraphics(); if(g != null) { paintComponent(g); } g.dispose(); } public void paintComponent(Graphics g) { if(createBuffer()) { //Es wird zunächst in das Offscreen-Image gezeichnet. Dazu holen //wir uns dessen Grafik-Kontext Graphics2D g2 = (Graphics2D) bufImage.getGraphics(); //Mit Hintergrundfarbe füllen g2.setColor(getBackground()); g2.fillRect(0, 0, getWidth(), getHeight()); //Mittelpunkt des Panels als Koordinatenursprung g2.translate(getWidth()/2, getHeight()/2); g2.setColor(Color.ORANGE); //Sonne zeichnen g2.fill(new Ellipse2D.Double(-25, -25, 50, 50)); //Das Koordinatensystem so drehen, wie sich die Erde um die Sonne dreht g2.rotate(earthArc); //Zum Mittelpunkt der Erde verschieben g2.translate(120, 0); g2.setColor(Color.blue); //Erde zeichnen g2.fill(new Ellipse2D.Double(-10, -10, 20, 20)); //Das Koordinatensystem so drehen, wie sich der Mond um die Erde dreht g2.rotate(moonArc); //Zum Mittelpunkt des Mondes verschieben g2.translate(20, 0); g2.setColor(Color.white); //Mond zeichnen g2.fill(new Ellipse2D.Double(-5, -5, 10, 10)); //jetzt das BufferedImage auf den Grafik-Kontext der Komponente, //also auf den Bildschirm zeichnen g.drawImage(bufImage, 0, 0, this); g2.dispose(); } } /* * Das BufferedImage kann erst erzeugt werden, wenn die Komponente gezeichnet * und die Größe damit bekannt ist. */ private boolean createBuffer() { if(bufImage != null) return true;//BufferedImage wurde bereits erzeugt else { if(getWidth() == 0 || getHeight() == 0) return false;//Komponente wurde noch nicht gezeichnet bufImage = new BufferedImage(getWidth(), getHeight(), Transparency.OPAQUE); } return true; } public Dimension getPreferredSize() { return new Dimension(320,320); } public static void main(String[] args) { JFrame f = new JFrame(); f.setResizable(false); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.getContentPane().setLayout(new BorderLayout()); Animator animator = new Animator(); f.getContentPane().add(animator, BorderLayout.CENTER); f.pack(); f.show(); Thread thread = new Thread(animator); thread.start(); } }