Hallo zusammen,
stehe vor einem scheinbar unlösbaren Problem -.-
also:
Ich habe hier folgende 3 Klassen: Main, WaitIcon, AbstractEvent (ActionListener für den JButton)
(Klassen sind unten angehängt)
Die grundsätzliche Idee ist Folgende: Solange eine Aktion ausgeführt wird, soll eine Animation eingeblendet werden, die signalisiert, dass das Programm zur Zeit beschäftigt ist. Ist die Aktion abgeschlossen, soll die Animation stoppen. Um dies zu realisieren, habe ich eine Klasse geschrieben (WaitIcon) die in einem eigenen Thread ausgeführt wird. Sie gibt ein JLabel zurück, in dem sich ein Icon befindet, welches sich im Intervall von 50ms aktualisiert und besteht aus 12 Einzelbildern (PNG) - gifs kamen nicht in Frage. Dieses JLabel kann dann irgendwo in der GUI eingebaut werden und der WaitIcon-Thread mit WaitIcon.start() gestartet werden. Ruft man nun die Methode WaitIcon.proceed() auf, wird die Animation gestartet. Ruft man die Methode WaitIcon.pause() auf, wird der WaitIcon-Thread angehalten und damit Animation gestoppt.
Um dies zu demonstieren, habe ich in folgendem Code zwei Beispiele (einmal ein Funktionierendes und einmal ein nicht Funktionierendes, welches mein Problem ist!) implementiert.
Sobald das Programm gestartet wird, wird die GUI mit einem Button und dem eigentlichen WaitIcon genzeichnet und aufgerufen. Anschließend wird WaitIcon.proceed() aufgerufen und ein Main-Thread.sleep() für 2 sek. aufgerufen. Dann wird WaitIcon.pause() aufgerufen. Dies Funktioniert. Das WaitIcon dreht sich genau 2 sek. (Animation wird ausgeführt)
Nun habe ich dem ActionListener(AbstractEvent-Klasse) das WaitIcon-Objekt übergeben. Anschließend habe ich den ActionListener dem Button hinzugefügt. Beim Klick soll nun der ActionListener genau das selbe tun wie oben beschrieben. WaitIcon.proceed() ausführen - Main-Thread.sleep(2000) ausführen - WaitIcon.pause() ausführen.
DAS PROBLEM:
Der Thread des WaitIcon wird zwar fortgesetzt, jedoch ist, solange der Main-Thread schläft, keine Animation zu sehen. Das JLabel bzw das JFrame wird erst nach Abarbeitung des sleep() Befehls aktualisiert. Es ist also keine Animation zusehen wie in dem Beispiel der Main-Klasse.
Als ersten jedoch nicht Funktionierenden Lösungsansatz habe ich folgende Erweiterung implementiert:
Ich übergebe dem WaitIcon-Objekt ein Handle auf das eigentliche JFrame und mach in jedem Schleifendurchlauf für die Aktualisierung des Images, einen frame.validate() und frame.repaint() - funktioniert allerdings auch nicht.
Es muss also irgendwie an dem ActionListener liegen. Denn direkt in der Main-Klasse selbst funktioniert es ja. Ich hoffe ihr könnt mir helfen.
Gruß
Daniel
Main-Klasse:
WaitIcon-Klasse:
AbstractEvent-Klasse:
stehe vor einem scheinbar unlösbaren Problem -.-
also:
Ich habe hier folgende 3 Klassen: Main, WaitIcon, AbstractEvent (ActionListener für den JButton)
(Klassen sind unten angehängt)
Die grundsätzliche Idee ist Folgende: Solange eine Aktion ausgeführt wird, soll eine Animation eingeblendet werden, die signalisiert, dass das Programm zur Zeit beschäftigt ist. Ist die Aktion abgeschlossen, soll die Animation stoppen. Um dies zu realisieren, habe ich eine Klasse geschrieben (WaitIcon) die in einem eigenen Thread ausgeführt wird. Sie gibt ein JLabel zurück, in dem sich ein Icon befindet, welches sich im Intervall von 50ms aktualisiert und besteht aus 12 Einzelbildern (PNG) - gifs kamen nicht in Frage. Dieses JLabel kann dann irgendwo in der GUI eingebaut werden und der WaitIcon-Thread mit WaitIcon.start() gestartet werden. Ruft man nun die Methode WaitIcon.proceed() auf, wird die Animation gestartet. Ruft man die Methode WaitIcon.pause() auf, wird der WaitIcon-Thread angehalten und damit Animation gestoppt.
Um dies zu demonstieren, habe ich in folgendem Code zwei Beispiele (einmal ein Funktionierendes und einmal ein nicht Funktionierendes, welches mein Problem ist!) implementiert.
Sobald das Programm gestartet wird, wird die GUI mit einem Button und dem eigentlichen WaitIcon genzeichnet und aufgerufen. Anschließend wird WaitIcon.proceed() aufgerufen und ein Main-Thread.sleep() für 2 sek. aufgerufen. Dann wird WaitIcon.pause() aufgerufen. Dies Funktioniert. Das WaitIcon dreht sich genau 2 sek. (Animation wird ausgeführt)
Nun habe ich dem ActionListener(AbstractEvent-Klasse) das WaitIcon-Objekt übergeben. Anschließend habe ich den ActionListener dem Button hinzugefügt. Beim Klick soll nun der ActionListener genau das selbe tun wie oben beschrieben. WaitIcon.proceed() ausführen - Main-Thread.sleep(2000) ausführen - WaitIcon.pause() ausführen.
DAS PROBLEM:
Der Thread des WaitIcon wird zwar fortgesetzt, jedoch ist, solange der Main-Thread schläft, keine Animation zu sehen. Das JLabel bzw das JFrame wird erst nach Abarbeitung des sleep() Befehls aktualisiert. Es ist also keine Animation zusehen wie in dem Beispiel der Main-Klasse.
Als ersten jedoch nicht Funktionierenden Lösungsansatz habe ich folgende Erweiterung implementiert:
Ich übergebe dem WaitIcon-Objekt ein Handle auf das eigentliche JFrame und mach in jedem Schleifendurchlauf für die Aktualisierung des Images, einen frame.validate() und frame.repaint() - funktioniert allerdings auch nicht.
Es muss also irgendwie an dem ActionListener liegen. Denn direkt in der Main-Klasse selbst funktioniert es ja. Ich hoffe ihr könnt mir helfen.
Gruß
Daniel
Main-Klasse:
Java:
package waiticon;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Main {
private WaitIcon icon;
public static void main(String[] args){
new Main().run();
}
private void run(){
JFrame frame = new JFrame();
icon = new WaitIcon(frame);
AbstractEvent ae = new AbstractEvent(icon);
JButton startBtn = new JButton(ae);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(500, 500));
frame.add(icon.getIcon());
icon.start();
frame.pack();
frame.setVisible(true);
frame.add(startBtn, BorderLayout.NORTH);
frame.validate();
frame.repaint();
icon.proceed();
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
icon.pause();
}
}
WaitIcon-Klasse:
Java:
package waiticon;
import java.awt.Component;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class WaitIcon extends Thread {
private Icon f01;
private Icon f02;
private Icon f03;
private Icon f04;
private Icon f05;
private Icon f06;
private Icon f07;
private Icon f08;
private Icon f09;
private Icon f10;
private Icon f11;
private Icon f12;
private JLabel icon;
private Component comp;
private boolean pause = true;
public WaitIcon(Component param) {
f01 = new ImageIcon("/home/dan/png/f01.png");
f02 = new ImageIcon("/home/dan/png/f02.png");
f03 = new ImageIcon("/home/dan/png/f03.png");
f04 = new ImageIcon("/home/dan/png/f04.png");
f05 = new ImageIcon("/home/dan/png/f05.png");
f06 = new ImageIcon("/home/dan/png/f06.png");
f07 = new ImageIcon("/home/dan/png/f07.png");
f08 = new ImageIcon("/home/dan/png/f08.png");
f09 = new ImageIcon("/home/dan/png/f09.png");
f10 = new ImageIcon("/home/dan/png/f10.png");
f11 = new ImageIcon("/home/dan/png/f11.png");
f12 = new ImageIcon("/home/dan/png/f12.png");
icon = new JLabel();
icon.setIcon(f01);
comp = param;
}
@Override
public void run() {
for (int imageNmbr = 1; imageNmbr <= 12; imageNmbr++) { //schleife läuft unentlich (es sei denn while-schleife wird aufgerufen)...
synchronized (this) {
while (pause) { // ... denn Solange pause true ist, wird dieser Thread
try { // an dieser Stelle angehalten
wait();
} catch (InterruptedException ex) {
}
}
}
switch (imageNmbr) {
case 1:
icon.setIcon(f01);
break;
case 2:
icon.setIcon(f02);
break;
case 3:
icon.setIcon(f03);
break;
case 4:
icon.setIcon(f04);
break;
case 5:
icon.setIcon(f05);
break;
case 6:
icon.setIcon(f06);
break;
case 7:
icon.setIcon(f07);
break;
case 8:
icon.setIcon(f08);
break;
case 9:
icon.setIcon(f09);
break;
case 10:
icon.setIcon(f10);
break;
case 11:
icon.setIcon(f11);
break;
case 12:
icon.setIcon(f12);
imageNmbr = 0;
break;
}
comp.validate();
comp.repaint();
try {
Thread.sleep(50); //aktualisiert die Einzelbilder in einem Intervall von 50ms
} catch (InterruptedException ex) {
}
}
}
public void pause() { //pausiert diesen Thread
pause = true;
}
public void proceed() { //setzt diesen Thread fort
pause = false;
synchronized (this) {
notify();
}
}
public JLabel getIcon() {
return icon;
}
}
AbstractEvent-Klasse:
Java:
package waiticon;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
public class AbstractEvent extends AbstractAction{
private Object obj;
public AbstractEvent(Object param){
super("Start");
obj = param;
}
public void actionPerformed(ActionEvent arg0) {
((WaitIcon)obj).proceed();
try {
Thread.sleep(2000); //Hier kommt die eigentliche Dauerhafte Aktion rein. Das Icon sollte
} catch (InterruptedException ex) { //sich also 2Sek lang drehen bis die pause anweisung ausgeführt wird.
ex.printStackTrace(); //ABER: Die GUI wird nicht aktuallisiert sondern erst ...
}
((WaitIcon)obj).pause(); // an dieser stelle
}
}
Zuletzt bearbeitet: