Button soll nach Klick Text ändern und Programm in 3 Sekunden beenden

Jack159

Bekanntes Mitglied
Hallo,

Ich habe ein Programm geschrieben, welches ein JFrame, JPanel und JButton enthält.
Beim Klick auf den Button soll der Button zunächst seinen Text in "Wurde geklickt" ändern und sich bzw. das Programm anschließend in 3 Sekunden beenden.

Das Problem ist nun, dass wenn ich auf den Button klicke, der Button seinen Text nicht ändert und außerdem dann während diese 3 Sekunden ablaufen, der Button so seltsam runtergedrückt ist...
Mache ich das ganze ohne die 3 Sekunden Wartezeit + Programm beenden, dann ändert der Button seinen Text problemlos...

Wo liegt das Problem?

Java:
`package k;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class App extends JFrame {
	
	public static void main(String[] args) {
		
		final App f1 = new App();
		f1.setSize(300, 300);
		f1.setLocationRelativeTo(null);
		f1.setVisible(true);
		
		final JPanel p1 = new JPanel();
		f1.add(p1);
		
		final JButton b1 = new JButton("Button 1");
		f1.setLayout(new FlowLayout());
		p1.add(b1);
		
	
		
		
		
		
		ActionListener a = new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
			
			
				b1.setText("Wurde geklickt");
				
				if(b1.getText()=="Wurde geklickt") {
					try {
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						
					}
					System.exit(0);
					
					
				}
					
				
				
			}
			
		};
		b1.addActionListener(a);
		
		
		
		
	}	

}
 
Die actionPerformed-Methode wird vom "Event Dispatcher Thread" aufgerufen, dieser Thread ist für GUI zuständig. Da du den EDT 3 Sekunden lang schlafen legst, kann er in der Zeit nicht mehr die GUI aktualisieren.

Du solltest bspw.
Code:
javax.swing.Timer
benutzen um das Programm nach 3 Sekunden zu beenden, dadurch wird der EDT nicht blockiert.

PS: Strings muss man immer mit .equals vergleichen, niemals mit ==
 
Danke erstmal euch beiden.

Habe nun eine Variante mit "Button" statt "JButton" gefunden. Wenn ich also "Button" nehme, dann funktioniert meine ursprüngliche Variante per Thread (Ohne Timer) wie gewollt.... 😵

Hier nochmal der Code, mit dem es jetzt funktioniert:

Java:
package k;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class App extends JFrame {
	public  App f1;
	public static void main(String[] args) {
		
		final App f1 = new App();
		f1.setSize(300, 300);
		f1.setLocationRelativeTo(null);
		f1.setVisible(true);
		
		final JPanel p1 = new JPanel();
		f1.add(p1);
		
		final Button b1 = new Button("Button 1");
		f1.setLayout(new FlowLayout());
		p1.add(b1);
		
	
		
		
		
		
		ActionListener a = new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
			
			
				b1.setLabel("Wurde geklickt");
				
				try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    
                }
                System.exit(0);
				

		
			}
			
		};
		b1.addActionListener(a);
		
		
		
		
	}	

}
 
Habe nun eine Variante mit "Button" statt "JButton" gefunden. Wenn ich also "Button" nehme, dann funktioniert meine ursprüngliche Variante per Thread (Ohne Timer) wie gewollt.... 😵
Mische niemals AWT (Button) und Swing (JPanel) Komponenten. Das kann zu ungewollten Nebeneffekten führen.

Zu deinem Problem siehe die Antwort von Schandro. Du musst das warten und beenden in nem separaten Thread ausführen.
 
Das ist keine gute Lösung. Der Rest deiner GUI ist swing,
Code:
Button
dagegen ist AWT. Man sollte das nicht mischen. Du solltest alles mit swing machen (d.h.
Code:
JButton
) und meinen Vorschlag mit javax.swing.Timer umsetzen. Glaub mir, du wirst ansonsten einige unschöne Probleme bekommen 😉
 

Zurück
Oben