Animation auf JPanel per Knopfdruck

Status
Nicht offen für weitere Antworten.

Mofi

Bekanntes Mitglied
ok, das klingt jetzt doof, aber ich krieg das irgendwie nicht hin.

ums kurz zu umschreiben. in dem Java Kopf bis Fuß, war in einem kapitel, eine übungsaufgabe, wo man animation auf einem JPanel machen sollte.

jedenfalls, dacht ich mir, kann man das ja so verändern, dass diese animation immer wieder abläuft, wenn man auf einen button drückt - und genau das funktioniert nicht und ich weiß nicht wieso.

der code wäre:
[HIGHLIGHT="Java"]
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Animation2{
protected int x = 1;
protected int y = 1;
public MeinZeichenPanel zP;

public void setX(int _x){
x = _x;
}
public void setY(int _y){
y = _y;
}

public static void main(String[] args){
Animation2 gui = new Animation2();
gui.los();
}

public void los(){
JFrame frame = new JFrame();
frame.setTitle("Animationen :)");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,300);
JPanel bpanel = new JPanel();
JButton button = new JButton("Start");
button.addActionListener(new ButtonListener());
bpanel.add(button);
zP = new MeinZeichenPanel();
frame.getContentPane().add(BorderLayout.CENTER, zP);
frame.getContentPane().add(BorderLayout.SOUTH, bpanel);
frame.setVisible(true);
malen();
}
public void malen(){
for(int i = 0; i<124; i++, y++, x++){
x++;
zP.repaint();
try{
Thread.sleep(50);
}catch(Exception e){
}
}// for ende
setX(1);
setY(1);

}

class MeinZeichenPanel extends JPanel{
public void paintComponent(Graphics g){
g.setColor(Color.white);
g.fillRect(0,0,500,250);
g.setColor(Color.blue);
g.fillRect(x,y,500-x*2,250-y*2);
}
}
class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
malen();
}//Methode ende
}// innere Klasse ende
}
[/HIGHLIGHT]

also es passiert folgendes, am anfang funktioniert die animation noch (blaue rechteck wird kleiner)
aber wenn ich auf den button drücke passiert nix, außer dass das fenster scheinbar schon arbeitet (ich hab das gefühl, dass das Thread.sleep(50) schon funktioniert, der rest nur nicht) und am ende hat man ein großes blaues rechteck.
wenn man die malen() methode am anfang ausklammert(in der los() methode) bleibt das rechteck so wie es ist, aber wenn man auf den button drückt, passiert animationsmäßig immernoch nichts....

ich hab das gefühl, dass das problem irgendwo mit den x und y variablen liegt, aber mir fällt dazu echt nix mehr ein...
 

benders

Aktives Mitglied
Statt zP.repaint()
zP.paint(zP.getGraphics());

benutzen.

Hat damint zu tun, wann Swing die Panels neu zeichnet, bzw. ob es überhaupt nötig ist.
 

diggaa1984

Top Contributor
Statt zP.repaint()
zP.paint(zP.getGraphics());

benutzen.

Hat damint zu tun, wann Swing die Panels neu zeichnet, bzw. ob es überhaupt nötig ist.


ich verweis mal darauf (ganz oben im AWT/SWING/SWT - Forum ^^)
Da Java plattformunabhängig ist sind wir zu weit vom Betriebssystem entfernt um diese Entscheidung selbst treffen zu können.
Hier kommt das AWT/Swing Toolkit zum Einsatz. Das Betriebssystem teilt dem Toolkit mit wann welcher Bereich der Anwendung neu gezeichnet werden muss.
Aus eben diesem Grund ist der scheinbar offensichtlich Weg über getGraphics falsch.
Anstatt sich aktiv ein Graphics Objekt zu holen und anzufangen zu zeichnen muss der Swing Programmierer passiv zeichnen, also darauf warten das AWT/Swing unsere Objekte zum zeichnen auffordert, denn nur AWT/Swing wissen wann das nötig ist.
Dies ist ein sehr häufiger Trugschluß, weshalb hier so detailiert auf die Problematik eingegangen wurde.
Bleibt die Frage wie man es denn richtig macht.
Jede JComponent verfügt über eine Methode paintComponent(Graphics g).
Wie man sieht wird hier das benötigte Graphics Objekt direkt als Parameter übergeben.
Diese Methode ist nicht dazu da das sie von einem Programmierer aufgerufen wird, stattdessen übernimmt diese Aufgabe das Toolkit.
Vereinfacht gesagt:
Wann immer AWT/Swing der Meinung ist das ein Neuzeichnen erforderlich ist wird diese Methode aufgerufen. [...]

Da wir nun nicht mehr aktiv Zeichnen können muss eine Methode her mit der wir Swing mitteilen können das eine Komponente neu gezeichnet werden muss.
In diesem Beispiel ist das der Fall wenn sich auf den Knopf gedrückt wurde.
Für diese Notwendigkeit verfügt jede JComponent über eine repaint() Methode.
repaint ist weniger als Befehl sondern mehr als freundliche Bitte zu verstehen.

das es mit repaint nicht funktioniert liegt nun daran, dass das framework selbst entscheidet wann gezeichnet wird, und durch das Thread-Sleep und der Schleife wird es quasi daran gehindert diese nötige Zeit zu finden!?
 

Marco13

Top Contributor
AAAAH!!! :mad: Dieter Nuhr hat da mal so ein berühmtes Zitat geprägt...

Man sollte (wenn man nicht 100% weiß, was man da tut) NIE auf einer Component "getGraphics" aufrufen!!!

In diesem Fall muss die eigentliche Animation in einen eigenen Thread ausgelagert werden. Die "actionPerformed"-Methode wird vom Event-Dispatch-Thread ausgeführt, der auch für das Zeichnen verantwortlich ist. Solange er in der "malen"-Methode hängt, kann er nicht neu Zeichnen. Abilfe:
Code:
public void actionPerformed(ActionEvent ev){
   malen();
  }//Methode ende
ändern in
Code:
public void actionPerformed(ActionEvent ev){
    Thread t = new Thread(new Runnable()
    {
        public void run()
        {
           malen();
        }
    });
    t.start();
  }//Methode ende
 

Mofi

Bekanntes Mitglied
Wie wärs damit, malen() in einem neuen Thread auszuführen?..
das wäre vermutlich eine idee, wenn ich das kapitel schon gelesen hätte :p

das mag merkwürdig klingen, aber bisher wurde der befehl Thread.sleep einfach nur in dem buch benutzt und mehr über threads kommt erst noch.

@diggaa1984
und bisher dacht ich auch, dass man paint() selber nicht aufruft (hab ich so gelesen) und hatte mich gewundert, dass man mir das vorschlägt. aber es funktioniert in diesem falle ja auch..

@marco13
danke ich werds mir merken und dein code testen :)

wie gesagt direkt threads kamen noch nicht vor beim lesen :) ( sollt ich wohl doch erstmal lesen bevor ich weiter übe...)


danke für eure antworten :)

(und wenn mir mal wer erklärt wo das häckchen sein soll, was man setzten kann/soll/darf würd ich mich auch freuen...ich finds einfach nicht, egal wie lange ich suche :bahnhof: )
 

Marco13

Top Contributor
und bisher dacht ich auch, dass man paint() selber nicht aufruft (hab ich so gelesen) und hatte mich gewundert, dass man mir das vorschlägt. aber es funktioniert in diesem falle ja auch..

Dann ändere mal die Größe des Fensters während der Animation. Vielleicht kracht's, vielleicht nicht ...
 

diggaa1984

Top Contributor
das es mit repaint nicht funktioniert liegt nun daran, dass das framework selbst entscheidet wann gezeichnet wird, und durch das Thread-Sleep und der Schleife wird es quasi daran gehindert diese nötige Zeit zu finden!?

(ohne neuen Thread)


kann das jemand bestätigen, oder is das so ohne weiteres nicht zu sagen!? ;)
 

Mofi

Bekanntes Mitglied
und bisher dacht ich auch, dass man paint() selber nicht aufruft (hab ich so gelesen) und hatte mich gewundert, dass man mir das vorschlägt. aber es funktioniert in diesem falle ja auch..

Dann ändere mal die Größe des Fensters während der Animation. Vielleicht kracht's, vielleicht nicht ...
es kracht nix (bei mir zumindestens)
aber wie gesagt ich werds mir merken, dass man paint() nicht selber aufruft :)
 

Marco13

Top Contributor
das es mit repaint nicht funktioniert liegt nun daran, dass das framework selbst entscheidet wann gezeichnet wird, und durch das Thread-Sleep und der Schleife wird es quasi daran gehindert diese nötige Zeit zu finden!?

(ohne neuen Thread)


kann das jemand bestätigen, oder is das so ohne weiteres nicht zu sagen!? ;)

Neeja... nicht so ganz: Ein Aufruf von "repaint" bedeutet so viel wie "Zeichne sobald wie möglich mal neu". Es wird die Aufgabe "Zeichne neu" in eine Warteschlange (die Event Queue) gelegt, und diese Warteschlange wird ständig von einem Thread (dem Event-Dispatch-Thread) abgearbeitet. Dieser Thread führt aber auch die actionPerformed-Metode - und damit in diesem Fall "malen" - aus. Er ist also mit der "malen"-Methode beschäftigt, und während er "malen" abarbeitet, wird zig-mal gesagt: "Zeichne so bald wie möglich neu" - und "so bald wie möglich" ist in diesem Fall: Sobald er mit dem Abarbeiten der "malen"-Methode fertig ist....
 

diggaa1984

Top Contributor
aso und das resultat wäre zudem noch das er dann 1000x das gleiche malt, da die werte bereits den endgültigen zustand beinhalten
 

Marco13

Top Contributor
Theoretisch ja, praktisch nein: Swing ist schon "intelligent" genug, dass es mehrere repaint-Aufrufe, die in kurzer Abfolge kommen bzw. deren Neuzeichnen nicht rechtzeitig abgearbeitet wird, zusammenzufassen ("event coalescing"). Dabei werden auch neuzuzeichnende Bereiche berücksichtigt, d.h. wenn man ein JPanel hat, das zwei Buttons enthält, und man ruft auf beiden Buttons "repaint" auf, dann werden diese repaints ggf. zusammengefasst, zu einem "großen" repaint für das JPanel. Oder an einem anderen Beispiel:
for (int i=0; i<1000; i++) component.repaint();
wird mit ziemlicher Sicherheit nur EIN neuzeichnen (auf jeden Fall aber nicht 1000) der Component verursachen.
D.h. in diesem Beispiel würde er am Ende nur einmal neu zeichnen, weil sich nach diesem ersten Neuzeichnen ja nichts mehr getan hat, und er die anderen repaints quasi ignorieren kann...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
L JPanel kleine "Animation" AWT, Swing, JavaFX & SWT 7
C Animation auf einem JPanel AWT, Swing, JavaFX & SWT 3
Developer_X Swing JPanel-THE ANIMATION AWT, Swing, JavaFX & SWT 3
O Animation in einem JPanel AWT, Swing, JavaFX & SWT 2
P Animation läuft nicht korrekt AWT, Swing, JavaFX & SWT 8
Ernesto95 JavaFX Return Value nach Beendigung einer Animation AWT, Swing, JavaFX & SWT 15
H Simple Animation mit Swing AWT, Swing, JavaFX & SWT 2
DeBoiJoshua 2D-Grafik Gif Animation will nicht laden AWT, Swing, JavaFX & SWT 1
S JavaFX WebView zeigt keine Animation AWT, Swing, JavaFX & SWT 5
E showAndWait is not allowed during animation or layout processing Memory FX AWT, Swing, JavaFX & SWT 2
A 2D-Grafik Ruckelfreie Animation AWT, Swing, JavaFX & SWT 20
L JavaFX Animation, erst zeichnen dann anzeigen AWT, Swing, JavaFX & SWT 4
L JavaFX Animation für Panel wechsel AWT, Swing, JavaFX & SWT 3
J Java FX Koordinaten NACH Animation setzen, wie? AWT, Swing, JavaFX & SWT 9
Pr0m3theus Animation nach Event AWT, Swing, JavaFX & SWT 6
F JavaFX Timeline Animation soll X- und Y-Position während Animation ändern AWT, Swing, JavaFX & SWT 2
javampir 2D-Grafik Effizienz bei animation AWT, Swing, JavaFX & SWT 0
C Pixel-Rendering/Animation Performance in BufferedImage AWT, Swing, JavaFX & SWT 1
wolfgang63 JavaFX Animation, Kreise im vorgegebem Takt durchs Fenster laufen lassen AWT, Swing, JavaFX & SWT 3
P Ansatz für 2D Animation gesucht AWT, Swing, JavaFX & SWT 2
Thallius HHübsche Kopier Animation? AWT, Swing, JavaFX & SWT 5
E Animation läuft nicht mehr flüssig AWT, Swing, JavaFX & SWT 8
E Warum macht die einfache Animation einen kleinen Fehler? AWT, Swing, JavaFX & SWT 14
B 2D-Grafik Dynamisches Erstellen von Images und deren Animation AWT, Swing, JavaFX & SWT 4
R Swing Komponenten bleiben bei Animation unsichtbar AWT, Swing, JavaFX & SWT 7
J GIF Animation AWT, Swing, JavaFX & SWT 2
B Swing Thread+Animation AWT, Swing, JavaFX & SWT 7
R Swing Animation mit JLayeredPane? AWT, Swing, JavaFX & SWT 8
K 3D-Grafik Animation AWT, Swing, JavaFX & SWT 4
U Gif Animation mit JLabel AWT, Swing, JavaFX & SWT 3
P KeyListener + Animation AWT, Swing, JavaFX & SWT 2
D 2D-Grafik Animation flackert AWT, Swing, JavaFX & SWT 8
R Polygon-Animation mit Darstellungsfehlern AWT, Swing, JavaFX & SWT 5
StupidAttack Animation, JComponent AWT, Swing, JavaFX & SWT 3
S SWT Rudimentäre Bild Animation AWT, Swing, JavaFX & SWT 3
A paintComponent() - Animation AWT, Swing, JavaFX & SWT 2
S Ich brauche eine Idee: Animation mit teil eines Bildes AWT, Swing, JavaFX & SWT 16
H "Animation" AWT, Swing, JavaFX & SWT 2
S Animation korrekt darstellen AWT, Swing, JavaFX & SWT 8
Developer_X Nach Animation Button adden AWT, Swing, JavaFX & SWT 3
T JFrame und Scale-Animation AWT, Swing, JavaFX & SWT 8
M Animation berechnen AWT, Swing, JavaFX & SWT 4
P Problem bei Animation AWT, Swing, JavaFX & SWT 2
K Animation auf GUI AWT, Swing, JavaFX & SWT 3
R ruckelfreie animation AWT, Swing, JavaFX & SWT 8
T Animation will nicht trotz Thread. AWT, Swing, JavaFX & SWT 14
S animation Flackern trotz doppelpufferung wieso? AWT, Swing, JavaFX & SWT 2
S Animation geht nicht AWT, Swing, JavaFX & SWT 3
m@nu Animation in GlassPane: Performanceeinbruch JFrame maximiert AWT, Swing, JavaFX & SWT 17
rudi.schraml Animation von Robotern auf FactoryFloor - repaint()? AWT, Swing, JavaFX & SWT 7
J Animation - Runnable AWT, Swing, JavaFX & SWT 3
H Animation startet nicht/ Thread AWT, Swing, JavaFX & SWT 6
N Animation nach einem bestimmten Ereignis starten lassen? AWT, Swing, JavaFX & SWT 4
A Problem mit Animation AWT, Swing, JavaFX & SWT 4
M Animation mit Keylistener AWT, Swing, JavaFX & SWT 2
P Zwei JPanel übereianderlegen AWT, Swing, JavaFX & SWT 14
XWing Basic JPanel mit 2 Buttons beutzen. AWT, Swing, JavaFX & SWT 10
G JPanel per Drag and Drop JButtons und Bilder ablegen AWT, Swing, JavaFX & SWT 1
G JPanel mit JButtons und Bilder AWT, Swing, JavaFX & SWT 5
N AWT JPanel zu Jframe hinzufügen AWT, Swing, JavaFX & SWT 2
M clear JPanel before repainting AWT, Swing, JavaFX & SWT 1
B ImageIcon auf JPanel austauschen AWT, Swing, JavaFX & SWT 3
T Swing Reload JPanel + darin liegende ProgressBar AWT, Swing, JavaFX & SWT 9
P Swing Mehrere JLabels mit ImageIcon in JPanel lesen AWT, Swing, JavaFX & SWT 1
E JScrollPane mit JPanel verbinden AWT, Swing, JavaFX & SWT 1
F JPanel Celleditor AWT, Swing, JavaFX & SWT 8
B JPanel-Inhalte inkl. JTextarea zoomen? AWT, Swing, JavaFX & SWT 3
B Mit ContentPane werden Komponenten angezeigt, mit SplitPane, JPanel nicht? AWT, Swing, JavaFX & SWT 6
CptK Funktionsgraphen effizient zeichnen und nur Teile von JPanel erneuern AWT, Swing, JavaFX & SWT 2
P Button simpler random auf einem JPanel verteilen? AWT, Swing, JavaFX & SWT 3
O Swing "Eigenes" JPanel wird dem JScrollPane nicht hinzugefügt AWT, Swing, JavaFX & SWT 5
Ich lerne Java. Swing Von JPanel A auf JPanel B zugreifen. AWT, Swing, JavaFX & SWT 4
A JPanel austauschen und Focus geben AWT, Swing, JavaFX & SWT 3
E Auf JPanel malen und davor JComponenten anzeigen AWT, Swing, JavaFX & SWT 12
L JComponent aus JPanel anhand Mausposition ermitteln AWT, Swing, JavaFX & SWT 10
J JPanel wird nicht angezeigt AWT, Swing, JavaFX & SWT 2
B Verschiebbares JPanel "ruckelt" im Randbereich AWT, Swing, JavaFX & SWT 2
S Swing JPanel nimmt keinen KeyListener an AWT, Swing, JavaFX & SWT 7
K JLabel mit Bilder im nicht initialisierten JPanel hinzufügen AWT, Swing, JavaFX & SWT 5
Hatsi09 Swing JPanel Bild einfügen AWT, Swing, JavaFX & SWT 14
L JPanel zeigt keinen Inhalt AWT, Swing, JavaFX & SWT 1
dereki2000 JPanel mit Rückgbe wie bei JOptionPane AWT, Swing, JavaFX & SWT 3
E Hintergrundfarbe setzen in JPanel funktioneirt nicht AWT, Swing, JavaFX & SWT 4
P JPanel KeyListener hinzufügen AWT, Swing, JavaFX & SWT 8
S Nach scrollen verschwindet das zuvor im JPanel gezeichnete AWT, Swing, JavaFX & SWT 2
P Bewegung eines Balkens in eineum JPanel welches als Spielfeld fungiert AWT, Swing, JavaFX & SWT 2
L Swing JPanel Größe anpassen AWT, Swing, JavaFX & SWT 6
D Platzierung von JTextfield in JPanel AWT, Swing, JavaFX & SWT 3
D Swing Anwendung ohne JPanel erstellen AWT, Swing, JavaFX & SWT 1
M Swing JPanel in JScrollPane AWT, Swing, JavaFX & SWT 3
M Zwei JPanel übereinander nur vorderes "repainten" AWT, Swing, JavaFX & SWT 3
J 2D-Grafik Background einer Jpanel Klasse ändern AWT, Swing, JavaFX & SWT 1
J Ziehen eines Buttons im JPanel AWT, Swing, JavaFX & SWT 2
J Button lässt sich nicht auf dem JPanel verschieben AWT, Swing, JavaFX & SWT 5
D zwei JLabel stapeln in einem JPanel AWT, Swing, JavaFX & SWT 5
DaCrazyJavaExpert Swing JPanel "ContentPane" wird nicht gesetzt/angezeigt AWT, Swing, JavaFX & SWT 16
DaCrazyJavaExpert Swing Größe des JPanel ändern/wird nicht geändert. AWT, Swing, JavaFX & SWT 3
DaCrazyJavaExpert Swing JPanel wird in JScollPane nicht angezeigt AWT, Swing, JavaFX & SWT 2
it_is_all JPanel verschwindet nach Button-Klick AWT, Swing, JavaFX & SWT 2
B Bar Plot in Swing JPanel AWT, Swing, JavaFX & SWT 0

Ähnliche Java Themen

Neue Themen


Oben