Swing Actionlistener verhindert repaint?!

danoman

Mitglied
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:
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:

Landei

Top Contributor
Swing zeichnet immer in der EDT (auch wenn man unsaubererweise den Code in anderen Threads startet) und auch der ActionListener-Code wird in der EDT ausgeführt. Das heißt, Thread.sleep in ActionListener legt genau den für das Zeichnen zuständigen Thread lahm. Um das zu umgehen, müsste der Code im ActionListener in einen eigenen Thread gepackt werden. Übrigens gibt es die Klasse javax.swing.Timer (nicht java.util.Timer), die für Animationen in Swing verwendet werden sollte.
 

danoman

Mitglied
Ok ich werds mit Timer mal versuchen. Was ich dann aber nicht verstehe ist, dass der Aufruf in der Main-Klasse funktioniert. Normal dürfte der ja auch nicht funzen.
Aber danke erstmal für die Info =)

Gruß
Daniel

EDIT:
Achso, soll das heißen dass der ActionListener, genauso wie Swing, im EDT ausgeführt werden? Was ja dann für das Beispiel in der Main-Klasse nicht zutreffen würde, was erklären würde, warum es da geht. Aber dann müsste doch ein validate, bzw repaint auf das JFrame in der WaitIcon-Klasse reichen oder nicht? (Also in dem eigentlichen Thread, der die Animation bearbeitet)
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
C Button ActionListener funktioniert nicht AWT, Swing, JavaFX & SWT 1
B Actionlistener mit Java Swing AWT, Swing, JavaFX & SWT 2
L jComboBox Actionlistener wird beim erstmaligen Befüllen getriggert AWT, Swing, JavaFX & SWT 7
H Viele ActionListener (MouseListener) - Performance AWT, Swing, JavaFX & SWT 24
pkm MainFrame durch Actionlistener auffrischen, aber wie? AWT, Swing, JavaFX & SWT 2
L actionListener für Button AWT, Swing, JavaFX & SWT 97
R Actionlistener funktioniert nicht AWT, Swing, JavaFX & SWT 4
N Bilder auf Button einfügen und mehrmals ändern (ein Button, mehrere ActionListener) AWT, Swing, JavaFX & SWT 2
R ActionListener in Actionlistener AWT, Swing, JavaFX & SWT 6
S Swing Variable in Actionlistener aufrufen AWT, Swing, JavaFX & SWT 10
P Swing ActionListener überschreibt einen Wert aus der Hauptklasse nicht AWT, Swing, JavaFX & SWT 5
N Aufruf einer anderen Klasse durch Button ActionListener AWT, Swing, JavaFX & SWT 2
M AWT Kann meinen Fehler beim ActionListener nicht finden AWT, Swing, JavaFX & SWT 5
F Wie bekomme ich den Wert der ComboBox in eine Variable gespeichert welche ich für meinen ActionListener nutzen kann? AWT, Swing, JavaFX & SWT 3
L Ein Actionlistener für ein Textfeld, anstatt viele Actionlistener für ein Textfeld AWT, Swing, JavaFX & SWT 7
coolian ActionListener funktonirt nicht richtig auf JMenuItem AWT, Swing, JavaFX & SWT 4
L ActionListener zu Button in Panel hinzufügen AWT, Swing, JavaFX & SWT 10
R Kann JLabel in ActionListener nicht aufrufen AWT, Swing, JavaFX & SWT 4
Blender3D einzelner ActionListener vs anonyme ActionListener AWT, Swing, JavaFX & SWT 10
T Swing Änderung des ActionListener Events nach Klick auf JButton AWT, Swing, JavaFX & SWT 2
xYurisha ActionListener Methoden Buttons zuweisen! AWT, Swing, JavaFX & SWT 16
J ActionListener bei Buttons AWT, Swing, JavaFX & SWT 14
S Swing Problem mit Button und ActionListener AWT, Swing, JavaFX & SWT 5
it_is_all ActionListener umlenken/ updaten mit AddActionListener funktioniert nicht AWT, Swing, JavaFX & SWT 3
it_is_all Event Handling ActionListener in anderer Klasse klappt nicht AWT, Swing, JavaFX & SWT 4
F "ActionListener" funktioniert nicht AWT, Swing, JavaFX & SWT 4
Z ActionListener Variable übergeben AWT, Swing, JavaFX & SWT 12
T JProgressbar während actionListener updaten AWT, Swing, JavaFX & SWT 1
S While Schleife im Actionlistener AWT, Swing, JavaFX & SWT 1
S ActionListener für alle Buttons AWT, Swing, JavaFX & SWT 26
R Swing ActionListener bei JButton AWT, Swing, JavaFX & SWT 9
T ActionListener nimmt JTextField nicht mehr an. AWT, Swing, JavaFX & SWT 2
P ActionListener Graphics Einbauen AWT, Swing, JavaFX & SWT 0
S actionlistener mit 2 fenster integrieren AWT, Swing, JavaFX & SWT 11
Liondary GUI - ActionListener AWT, Swing, JavaFX & SWT 7
J ActionListener erkennt Variable nicht AWT, Swing, JavaFX & SWT 6
E ActionListener führt falsche Funktion aus AWT, Swing, JavaFX & SWT 6
Sin137 ActionListener in MVC AWT, Swing, JavaFX & SWT 7
M ActionListener und mathematische Methoden AWT, Swing, JavaFX & SWT 13
A Oberfläche mit zwei Klassen und actionlistener verbinden AWT, Swing, JavaFX & SWT 7
Paul15 ActionListener Variablen AWT, Swing, JavaFX & SWT 13
Y ActionListener AWT, Swing, JavaFX & SWT 2
K Ereignisbehandlung, ActionListener, ActionEvent AWT, Swing, JavaFX & SWT 3
A Gui für Vokabeltrainer (ActionListener) AWT, Swing, JavaFX & SWT 14
C Im ActionListener Buttons disablen, einen Thread starten, dann Buttons enablen AWT, Swing, JavaFX & SWT 2
M JTextArea wird nicht aktualisiert (ActionListener-Problem) AWT, Swing, JavaFX & SWT 1
J Event Handling JOptionPane ActionListener setzen. AWT, Swing, JavaFX & SWT 3
S ActionListener Klasse aufrufen AWT, Swing, JavaFX & SWT 4
R Swing Problem: IOException bei ActionListener AWT, Swing, JavaFX & SWT 1
J ActionListener soll auf paint() Methode zugreifen AWT, Swing, JavaFX & SWT 1
A JButton wird bei ActionListener nicht "angenommen" AWT, Swing, JavaFX & SWT 7
T Einfaches Problem mit ActionListener AWT, Swing, JavaFX & SWT 2
K ActionListener mit KeyListener AWT, Swing, JavaFX & SWT 7
K GUI, Button, ActionListener - ein paar Einsteigerprobleme AWT, Swing, JavaFX & SWT 1
W Verschachtelter ActionListener AWT, Swing, JavaFX & SWT 0
N gewünschte ActionListener bei RadioButton mit isSelected geht nicht AWT, Swing, JavaFX & SWT 2
C Probleme mit Buttons und einem ActionListener AWT, Swing, JavaFX & SWT 2
K Swing JMenu und ActionListener AWT, Swing, JavaFX & SWT 4
A Swing ActionListener AWT, Swing, JavaFX & SWT 8
V ActionListener Abhängigkeitenproblem AWT, Swing, JavaFX & SWT 6
M ActionListener für mehrere Klassen AWT, Swing, JavaFX & SWT 4
J ActionListener für Buttons AWT, Swing, JavaFX & SWT 3
M Event Handling ActionListener übergeben ich checks net AWT, Swing, JavaFX & SWT 4
C Swing ComboBox - ActionListener deaktivieren AWT, Swing, JavaFX & SWT 2
S Button (ActionListener) funktioniert nicht, wenn y-Koordinate verändert wird AWT, Swing, JavaFX & SWT 5
L Swing ActionListener führt seine Aufgabe nur teilweise aus. AWT, Swing, JavaFX & SWT 7
A Swing ActionListener kann nicht hinzugefügt werden AWT, Swing, JavaFX & SWT 4
P Actionlistener - 3 klassen - kompliziert - auf methoden zugreifen AWT, Swing, JavaFX & SWT 3
Q CardLayout, ausgelagerte Panels, ActionListener AWT, Swing, JavaFX & SWT 5
M ProgressBar in ActionListener AWT, Swing, JavaFX & SWT 4
D AWT eigenem Knopf ActionListener zuweisen AWT, Swing, JavaFX & SWT 24
E Wert aus ActionListener geben AWT, Swing, JavaFX & SWT 4
J ActionListener per Innere Klasse oder e.getActionCommand() if-Abfrage? AWT, Swing, JavaFX & SWT 12
L Swing ActionListener zugriff auf bestimmte Elemente AWT, Swing, JavaFX & SWT 3
P Swing Seltsames ActionListener-Verhalten AWT, Swing, JavaFX & SWT 7
Oliver530 ActionListener von eigener ButtonKlasse AWT, Swing, JavaFX & SWT 16
Kenan89 statischer ActionListener keine Wirkung? AWT, Swing, JavaFX & SWT 2
Kenan89 statischer ActionListener keine Wirkung? AWT, Swing, JavaFX & SWT 3
C In der Schleife ActionListener aktivieren AWT, Swing, JavaFX & SWT 3
B Swing Problem beim ActionListener AWT, Swing, JavaFX & SWT 5
P Swing JPanel mit ActionListener mehrfach verwenden AWT, Swing, JavaFX & SWT 8
1 ActionEvent generieren und an ActionListener weiterleiten AWT, Swing, JavaFX & SWT 12
N Swing Klasse erbt von JDialog - Problem mit innerer ActionListener-Klasse AWT, Swing, JavaFX & SWT 6
N JCombobox und Actionlistener Aktion nur ausführen, wenn Useraktion ihn auslöst AWT, Swing, JavaFX & SWT 4
N Componente und Actionlistener AWT, Swing, JavaFX & SWT 5
C ActionListener AWT, Swing, JavaFX & SWT 6
Corben ActionListener Error AWT, Swing, JavaFX & SWT 2
F Wert durch ActionListener an Klasse übergeben AWT, Swing, JavaFX & SWT 3
I Swing Problem mit InputMap bei JButton (ActionListener) AWT, Swing, JavaFX & SWT 3
S Swing JButton mit ActionListener innerhalb einer JTable AWT, Swing, JavaFX & SWT 4
P Variablen in einem ActionListener zurücksetzen AWT, Swing, JavaFX & SWT 6
M AWT Problem mit ActionListener AWT, Swing, JavaFX & SWT 2
A Swing Bug in Swing? Wenn checkbox disabled reagiert ActionListener nicht AWT, Swing, JavaFX & SWT 5
S ActionListener "nach oben weitergeben" AWT, Swing, JavaFX & SWT 10
M Anonymer ActionListener AWT, Swing, JavaFX & SWT 4
L SWT Actionlistener Combobox öffnen AWT, Swing, JavaFX & SWT 4
S MenuBar ActionListener Event ... AWT, Swing, JavaFX & SWT 6
B Swing Formular mit mehreren Elementen - wie die ActionListener-Verarbeitung lösen? AWT, Swing, JavaFX & SWT 2
M getSource() findet Button nicht - ActionListener AWT, Swing, JavaFX & SWT 4
S Swing mit ActionListener auf Objekte einer anderen Klasse zugreifen AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben