PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java - eine simple Animation


PHuV
2007-05-12, 16:59:51
Ich versuche gerade mal zu verstehen, wie man eine Animation in Java machen kann (ich habe vorher noch keine Grafikprogrammierung in Java gemacht) und bin auch in Java nicht so ganz fit. Als IDE verwende ich Eclipse 3.2.2 mit Java SDK 6.0.1

Als Beispiel diente mir dieses Vorlage

http://kawigi.yajags.com/animation/BasicHello.htm

von

http://kawigi.yajags.com/animation/



package gui;

import java.awt.*;

public class ScrollTest3 extends java.applet.Applet implements Runnable
{
int count;
Thread animator;
String hallo="Hallo";
public void init()
{
setBackground(Color.black);
setSize(1024, 768);
count=0;
}
public void paint(Graphics g)
{
g.setFont(new Font("Serif", Font.BOLD, 50));
for (int i = 0; i<count/20 && i < 768; i++)
{
g.setColor(Color.black);
g.drawString(hallo , 0, i-1);

g.setColor(Color.red);
g.drawString(hallo , 0, i);

if (i>767)
i=0;
}
}

public void start()
{
animator = new Thread(this);
animator.start();
}

public synchronized void stop()
{
animator = null;
notify();
}

public synchronized void run()
{
while (Thread.currentThread() == animator)
{
count++; //increment the frame counter
repaint(); //refresh
try
{
wait (1); //delay
}
catch (InterruptedException e)
{
break;
}
}
}
}


1) Ich will einfach nur einen Text schön sanft nach unten scrollen lassen, ohne flackern und Störungen.
Meine Version sieht einfach nur scheisse aus.
2) Weiterhin möchte ich das gerne mal in eine normale Main-Methode packen (das bekomme ich auch nicht hin)
3) Ich hätte gerne diese Animation in einem JPanel, damit ich das mit Swing-Komponenten weiter verwenden kann. In "Java ist auch eine Insel" habe ich gelesen, daß man AWT und Swing nicht vermischen sollte, aber die Konsequenzen sind mir noch nicht ganz klar.

Wäre nett, wenn mir jemand weiterhelfen könnte.

PS: Ja, ich weiß, mein Code ist sch...

beos
2007-05-12, 17:58:44
.
.
2) Weiterhin möchte ich das gerne mal in eine normale Main-Methode packen
.
.


Hi Wdragon,

ein Applet besitzt - meines Wissens - keine Main Funktion

RMC
2007-05-12, 19:35:29
1) Ich will einfach nur einen Text schön sanft nach unten scrollen lassen, ohne flackern und Störungen.
Meine Version sieht einfach nur scheisse aus.
2) Weiterhin möchte ich das gerne mal in eine normale Main-Methode packen (das bekomme ich auch nicht hin)
3) Ich hätte gerne diese Animation in einem JPanel, damit ich das mit Swing-Komponenten weiter verwenden kann. In "Java ist auch eine Insel" habe ich gelesen, daß man AWT und Swing nicht vermischen sollte, aber die Konsequenzen sind mir noch nicht ganz klar.



2) Kannst du eh machen, ein Applet hat hier keine main Methode...ein Applet hat die Methoden init(), start(), stop() und destroy(). Aber du kannst alles was a drin steht in deine main packen wenn du eine normale Anwendung hast.

3) JPanel ist Swing ;) Außerdem basiert Swing teilweise auf AWT.

PHuV
2007-05-12, 19:43:23
2) Kannst du eh machen, ein Applet hat hier keine main Methode...ein Applet hat die Methoden init(), start(), stop() und destroy(). Aber du kannst alles was a drin steht in deine main packen wenn du eine normale Anwendung hast.


D.h. init usw. einfach in ein main packen?


3) JPanel ist Swing ;) Außerdem basiert Swing teilweise auf AWT.

Das weiß ich ja, nur wie bekomme ich es hin, daß ich eben ein Grafikbildschirm in einem JPanel habe (ich verwende mehrere JPanels für die diversen Schalter und Anzeigen).

RMC
2007-05-12, 19:50:24
D.h. init usw. einfach in ein main packen?

Naja schau dir mal init() an...was passiert da großartig? Nix..Hintergrundfarbe und Größe wird gesetzt...und was macht start()? Lädt den Thread. Im Endeffekt heißt nicht dass diese Zeilen NUR in diese Funktionen gehören...die werden halt zu anderen Zeiten ausgeführt, ist aber völlig irrelevant bei diesem simplen Beispiel. Ja, du kannst das alles in die main packen.


Das weiß ich ja, nur wie bekomme ich es hin, daß ich eben ein Grafikbildschirm in einem JPanel habe (ich verwende mehrere JPanels für die diversen Schalter und Anzeigen).

Du brauchst ein Objekt, das eine paint() Methode besitzt die du Überschreiben kannst. Normalerweise zeichnet man auf ein "Canvas" oder ähnliches Objekt. Das kannst du auf das Panel legen und dann seine paint-Methode überschreiben und reinzeichnen was du möchtest.

PHuV
2007-05-12, 21:05:19
Erst mal danke, und Hurra, ich habe endlich mal ein sanftes Scrolling hinbekommen. Ich sehe aber, das ist ganz schön aufwendig, wenn man noch eine Animation ohne Flickern haben möchte.


package gui;

import java.awt.*;
import java.awt.event.*;

public class ScrollTest5 extends java.applet.Applet implements Runnable
{
int count;
Thread animator;
String greeting;
public void init()
{
greeting = "Hallo 3D-Center-Fans";
setBackground(Color.black);
setSize(1024, 768);
count=0;
}
public void paint(Graphics g)
{
g.setFont(new Font("Serif", Font.BOLD, 50));
g.setColor(Color.red);
g.drawString(greeting, 0, count);
}
public void start()
{
animator = new Thread(this);
animator.start();
}

public synchronized void stop()
{
animator = null;
notify();
}

public synchronized void run()
{
while (Thread.currentThread() == animator)
{
count++;
if (count == 780)
count=0;
repaint();
try
{
wait (10);
}
catch (InterruptedException e)
{
break;
}
}
}
}


Zum Thema AWT und Swing lese ich gerade


Table 1-1. AWT to Swing Component Mapping
AWT Component Nearest Swing Replacement
Button JButton
Canvas JPanel


so ganz peil ich das noch nicht, wann Swing und wann AWT? :confused:
Ich dachte, Swing setzt zwar teilweise auf AWT auf, ist aber was anderes.

PHuV
2007-05-12, 21:17:27
Pah, von der Wega, direkt ohne repaint malen geht ohne flickern


package gui;

import java.awt.*;
import java.awt.event.*;

import java.awt.*;
import java.awt.event.*;

public class ScrollTest6 extends java.applet.Applet implements Runnable
{
int count;
Thread animator;
String greeting;

public void init()
{
greeting = "Hallo 3D-Center-Fans";
setBackground(Color.black);
setSize(1024, 768);
count=0;
}

public void draw(Graphics g)
{
g.setColor(Color.black);
g.drawString(greeting, 0, count-1);

g.setColor(Color.red);
g.drawString(greeting, 0, count);
}

public void start()
{
animator = new Thread(this);
animator.start();
}

public synchronized void stop()
{
animator = null;
notify();
}

public synchronized void run()
{
Graphics g=getGraphics();
g.setFont(new Font("Serif", Font.BOLD, 50));
while (Thread.currentThread() == animator)
{
count++;
if (count == 810)
count=0;
draw(g);
try
{
wait(10);
}
catch (InterruptedException e)
{
break;
}
}
}
}


Flickert genau so wie mein ScrollTest5, und ich muß mich selbst ums löschen des alten Objektes kümmmern, blöd blöd blöd.

RMC
2007-05-12, 21:29:13
Table 1-1. AWT to Swing Component Mapping
AWT Component Nearest Swing Replacement
Button JButton
Canvas JPanel



Ja, normalerweise kann man davon ausgehen, dass Klassen, die mit "J" beginnen zu Swing gehören. Was in AWT "Button" heißt, heißt in Swing "JButton". Dass Canvas das AWT Äquivalent zu JPanel sein soll war mir neu.

Du kannst aber auch die paint Methode eines einfachen JComponents überschreiben, das ist die Basisklasse der meisten Swing Elemente.

PHuV
2007-05-12, 21:34:59
Ja, normalerweise kann man davon ausgehen, dass Klassen, die mit "J" beginnen zu Swing gehören. Was in AWT "Button" heißt, heißt in Swing "JButton". Dass Canvas das AWT Äquivalent zu JPanel sein soll war mir neu.

Du kannst aber auch die paint Methode eines einfachen JComponents überschreiben, das ist die Basisklasse der meisten Swing Elemente.

Wie gesagt, ich bin hier blutiger Laie und lese nur momentan viel über AWT und Swing, und jeder empfiehlt, Swing (da plattformunabhängiger und besser und neuer etc ;) ). Aber die reinen Grafikdemos sind mit AWT gemacht, grr.

Monger
2007-05-13, 00:52:38
Wie gesagt, ich bin hier blutiger Laie und lese nur momentan viel über AWT und Swing, und jeder empfiehlt, Swing (da plattformunabhängiger und besser und neuer etc ;) ). Aber die reinen Grafikdemos sind mit AWT gemacht, grr.

Wenn ich das noch richtig im Kopf habe, erben die Swing Elemente allesamt an irgendeinem Punkt von AWT. Ich weiß, die Aussage ist nicht hundertprozentig korrekt, aber AWT ist ein relativ allgemeines Grafikmodell, und Swing bietet spezialisierte Fensterkomponenten dafür an.

paint() zu überschreiben und von selbst aufzurufen, kann manchmal zu komischen Effekten führen. Zumindest ich hab damit öfters mal Probleme gehabt. Besser imho ist es, wenn man das paint() indirekt auslöst, z.B. über ein invalidate() der Komponente. Dann liegt es am AWT Gerüst, alles vernünftig zu rendern, und in aller Regel macht es das auch ganz gut.

Und übrigens: für zeitgesteuerte Abläufe empfiehlt sich der Swing Timer. Über Threads und waits irgendeinen Zeitrhythmus zu erzeugen, kann furchtbar in die Hose gehen. Wie regelmäßig deine Animation dann läuft, hängt dann wesentlich von der Prozessorauslastung ab. Besser man hat sowas wie einen Timer, der uhrzeitgesteuert Ereignisse abfeuert, und damit ziemlich präzise Zyklen erzeugt.

PHuV
2007-05-13, 03:26:17
Und übrigens: für zeitgesteuerte Abläufe empfiehlt sich der Swing Timer. Über Threads und waits irgendeinen Zeitrhythmus zu erzeugen, kann furchtbar in die Hose gehen. Wie regelmäßig deine Animation dann läuft, hängt dann wesentlich von der Prozessorauslastung ab. Besser man hat sowas wie einen Timer, der uhrzeitgesteuert Ereignisse abfeuert, und damit ziemlich präzise Zyklen erzeugt.

Meinst Du das hier

http://java.sun.com/docs/books/tutorial/uiswing/misc/timer.html

Danke für den Tipp.

Monger
2007-05-13, 03:54:16
Meinst Du das hier

http://java.sun.com/docs/books/tutorial/uiswing/misc/timer.html

Danke für den Tipp.
Genau den meine ich.

PHuV
2007-05-14, 22:35:51
Ich habe gerade diese Funktion getestet, und im Vergleich zu einer Lösung mit Double Buffering finde ich sie nicht so gut.

Ebenso habe ich mal eine Animation mit einem JPanel und einem Frame direkt gemacht, die Animation über das Frame mit AWT läuft deutlich besser als über Swing :( .