# JFrame repaint/validate Probleme



## hephaistos (19. Dez 2003)

hallo again,

ich bin schon wesentlich weiter, als gestern 

verwende nun doch JFrames...

ich habe nun ein Window, in welches ich Daten eingeben lasse, mittels "actionPerformed()"  checke ich dann die eingegebenen Daten und rufe in dieser Methode weitere Methoden auf ("dispose" das Eingabefenster und lade ein neues). Da tritt ein Problem auf:

Ich gehe nämlich "repaint()e" nämlich das Fenster jeweils bei einem Schleifendurchlauf in gewissen Zeitabständen mit "Thread.sleep()". Das funktioniert aber da nicht korrekt, weil nur ein "graues/leeres" Window angezeigt wird.

Hat jemand eine Lösung? Fehlermeldung krieg ich leider keine....

thx!


----------



## Ebenius (19. Dez 2003)

Läuft die Schleife im EventDispatcher-Thread (zum Beispiel direkt aus der _actionPerformed()_-Methode)?

Kannst Du mal ein bisschen *Code *posten (*das wichtige - nicht alles*)?

Es grüßt Ebenius


----------



## Guest (19. Dez 2003)

hallo!

nein, die schleife läuft nicht direkt in der actionPerformed-Methode.
es gibt eine eigene Methode dafür - diese wird in actionPerformed aufgerufen.

code post ich ungern, weil das mein erstes GUI-Geschreibsel ist, da kennt sich bestimmt keiner aus.
ABer wenn du mir so nicht helfen kannst, stell ich ihn natürlich "ungern"  rein.

ciao


----------



## Ebenius (19. Dez 2003)

Gut. Wenn die _actionPerformed()_-Methode die andere Methode aufruft, dann läuft es trotzdem im EventDispatcher-Thread.

Ein bisschen Code sollte hier wirklich helfen. Schneid's halt zusammen, so dass das wesentliche enthalten ist. Wenn Du wirklich *sehr* ungern Code postest, dann erklärs noch genauer... oder schick mir ne Mail...

Es grüßt Ebenius


----------



## Guest (19. Dez 2003)

ja, wie krieg ich das aus diesem "EventDispatcher-Thread" raus? bzw. was kann ich dagegen tun?

danke für deine antworten!


----------



## Ebenius (19. Dez 2003)

Okay, ich glaube Du solltest hier doch mal beschreiben, was Du genau erreichen möchtest (Use-Case-Beschreibung)oder poste halt Source-Code.

Ich habe ja noch nichtmal gesagt, dass es aus dem EventDispatcher-Thread muss... Allerdings sind da
	
	
	
	





```
Thread.sleep(...);
```
-Aufrufe ungünstig!

Es grüßt Ebenius


----------



## Guest (19. Dez 2003)

ahaaa, das dachte ich mir ja.

kann ich das irgendwie umgehen? gibts ein "synonym" für Thread.sleep??? thxx!!!


----------



## Ebenius (19. Dez 2003)

So einfach is ni.

Was willst Du eigentlich wann tun?

Es grüßt Ebenius


----------



## Guest (19. Dez 2003)

okay, hier ist mein geheimer code 
ich denke DU siehst gleich, was los ist 

danke

```
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;

public class CountDown extends WindowAdapter implements ActionListener {
	
	int iRunHours=0, iRunMinutes=0, iRunSeconds=0;

	int iLoops=5, iRange=-1, iLastSeconds=10;
	JFrame countDownWindow, inputWindow;
	JLabel lHours, lMinutes, lSeconds, errorMessage;
	Font fHours, fMinutes, fSeconds;
	DecimalFormat numberFormat;
	ImageIcon logoImage;
	Image topIcon;
	Button startCounter;
	JSpinner inputHours, inputMinutes, inputSeconds;
	String sOccouredErrors="";

	public CountDown() {
		this.numberFormat = new DecimalFormat("00");
	}

	public static void main(String[] args) {
		CountDown cCountDown = new CountDown();
		cCountDown.generateInputWindow();
	}

	public void actionPerformed(ActionEvent event) {

		this.iRunHours   = Integer.parseInt(inputHours.getValue().toString());
		this.iRunMinutes = Integer.parseInt(inputMinutes.getValue().toString());
		this.iRunSeconds = Integer.parseInt(inputSeconds.getValue().toString());
		this.errorMessage.setText("start CountDown...");
		this.startCounter.removeActionListener(this);
		this.inputWindow.removeWindowListener(this);
		this.inputWindow.dispose();

		this.generateCountDownWindow();
//hier beginnt das Problem!
		this.doCountDown();
	}
	
	private void setCountDown(int iRange) {
		this.iRunSeconds += iRange;
		if ( this.iRunSeconds<0 ) {
			this.iRunSeconds = 59;
			this.iRunMinutes--;
		}
		if ( this.iRunMinutes<0 ) {
			this.iRunMinutes = 59;
			this.iRunHours--;
		}
		if ( this.iRunHours<0 ) {
			this.iRunHours = 23;
		}
	}
	
	private void generateInputWindow() {
		this.inputWindow = new JFrame("[CountDown] © by hephaistos");

		try {
			UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
		} catch (Exception e) {
			this.sOccouredErrors += "\n"+e;
		}

		this.inputWindow.getContentPane().setLayout(new FlowLayout());

		this.topIcon = java.awt.Toolkit.getDefaultToolkit().getImage("copyright.gif");
		this.inputWindow.setIconImage(this.topIcon);

		JPanel inputPanel = new JPanel(); 
		inputPanel.setLayout(new GridLayout(4,2));
		inputPanel.add(new JLabel("Stunden: "));
		this.inputHours = new JSpinner(new SpinnerNumberModel(00,00,23,1));
		inputPanel.add(this.inputHours);
		inputPanel.add(new JLabel("Minuten: "));
		this.inputMinutes = new JSpinner(new SpinnerNumberModel(00,00,59,1));
		inputPanel.add(this.inputMinutes);
		inputPanel.add(new JLabel("Sekunden: "));
		this.inputSeconds = new JSpinner(new SpinnerNumberModel(00,00,59,1));
		inputPanel.add(this.inputSeconds);
		this.errorMessage = new JLabel("");
		inputPanel.add(this.errorMessage);
		this.startCounter = new Button("[CountDown starten]");
		this.startCounter.addActionListener(this);
		
		inputPanel.add(startCounter);
		this.inputWindow.getContentPane().add(inputPanel);
		
		this.inputWindow.addWindowListener(this);
		this.inputWindow.setVisible(true);
		this.inputWindow.pack();
		this.inputWindow.setLocation(((java.awt.Toolkit.getDefaultToolkit().getScreenSize().width-this.inputWindow.getWidth())/2),((java.awt.Toolkit.getDefaultToolkit().getScreenSize().height-this.inputWindow.getHeight())/2));
		this.inputWindow.show();
	}
	
	private void generateCountDownWindow() {
		this.countDownWindow = new JFrame("[CountDown] © by hephaistos");

		try {
			UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
		} catch (Exception e) {
			this.sOccouredErrors += "\n"+e;
			System.out.println(this.sOccouredErrors);
		}

		this.countDownWindow.getContentPane().setLayout(new GridLayout(2,1));
		this.countDownWindow.getContentPane().setBackground(new Color(0,0,63));

		this.topIcon = java.awt.Toolkit.getDefaultToolkit().getImage("copyright.gif");
		this.countDownWindow.setIconImage(this.topIcon);

		this.logoImage = new ImageIcon(java.lang.ClassLoader.getSystemResource("logo.gif")); 
		JLabel jlabel = new JLabel(this.logoImage);  
		this.countDownWindow.getContentPane().add(jlabel); 
		
		this.lHours = new JLabel(formatTime(this.iRunHours), JLabel.CENTER);
		this.lHours.setForeground(new Color(255, 51, 0));
		this.lHours.setFont(new Font("Arial", Font.BOLD, 220));
	
		this.lMinutes = new JLabel(formatTime(this.iRunMinutes), JLabel.CENTER);
		this.lMinutes.setForeground(new Color(255, 51, 0));
		this.lMinutes.setFont(new Font("Arial", Font.BOLD, 230));
		
		this.lSeconds = new JLabel(formatTime(this.iRunSeconds), JLabel.CENTER);
		this.lSeconds.setForeground(new Color(255, 51, 0));
		this.lSeconds.setFont(new Font("Arial", Font.BOLD, 240));
		
		JPanel timePanel = new JPanel(); 
		timePanel.setLayout(new GridLayout(1,3));
		timePanel.setBackground(new Color(0,0,63));
		timePanel.add(this.lHours);
		timePanel.add(this.lMinutes);
		timePanel.add(this.lSeconds);
		this.countDownWindow.getContentPane().add(timePanel);
		
		this.countDownWindow.setSize(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height);
		this.countDownWindow.addWindowListener(this);
		this.countDownWindow.setVisible(true);
		this.countDownWindow.show();
		this.countDownWindow.validate();
	}	
	
	private void doCountDown() {
		this.setCountDown(-1);

		while ( !(this.iRunHours==0) || !(this.iRunMinutes==0) || !((this.iRunSeconds-this.iLastSeconds)<=1) ) {
			this.setCountDown(this.iRange);
			this.lHours.setText(formatTime(this.iRunHours));
			this.lMinutes.setText(formatTime(this.iRunMinutes));
			this.lSeconds.setText(formatTime(this.iRunSeconds));

			this.countDownWindow.repaint();
			this.sleepForMillis(1000);
		}
		//letzte X Sekunden
		for (int i=0; i<=this.iLastSeconds; i++) {
			this.setCountDown(this.iRange);

			this.lSeconds.setText(formatTime(this.iRunSeconds));
			this.fSeconds = this.lSeconds.getFont();
			this.lSeconds.setForeground(new Color(240, 248, 255));
			this.lSeconds.setFont(new Font(this.lSeconds.getName(), this.fSeconds.getStyle(), this.fSeconds.getSize()+20));

			this.sleepForMillis(500);

			this.lSeconds.setText(formatTime(this.iRunSeconds));
			this.fSeconds = this.lSeconds.getFont();
			this.lSeconds.setForeground(new Color(255, 51, 0));
			this.lSeconds.setFont(new Font(this.lSeconds.getName(), this.fSeconds.getStyle(), this.fSeconds.getSize()-20));
			this.countDownWindow.repaint();
			this.sleepForMillis(500);
		}
		//Blinken lassen
		for (int i=0; i<40; i++) {
			if ( i%2==0 ) {
				this.fHours = this.lHours.getFont();
				this.lHours.setForeground(new Color(255, 51, 0));
				this.lHours.setFont(new Font(this.lHours.getName(), this.fHours.getStyle(), this.fHours.getSize() +10));
				this.fMinutes = this.lMinutes.getFont();
				this.lMinutes.setForeground(new Color(255, 51, 0));
				this.lMinutes.setFont(new Font(this.lMinutes.getName(), this.fMinutes.getStyle(), this.fMinutes.getSize() +20));
				this.fSeconds = this.lMinutes.getFont();
				this.lSeconds.setForeground(new Color(255, 51, 0));
				this.lSeconds.setFont(new Font(this.lSeconds.getName(), this.fSeconds.getStyle(), this.fSeconds.getSize() +10));
			} else {
				this.fHours = this.lHours.getFont();
				this.lHours.setForeground(new Color(0, 255, 255));
				this.lHours.setFont(new Font(this.lHours.getName(), this.fHours.getStyle(), this.fHours.getSize() -10));
				this.fMinutes = this.lMinutes.getFont();
				this.lMinutes.setForeground(new Color(0, 255, 255));
				this.lMinutes.setFont(new Font(this.lMinutes.getName(), this.fMinutes.getStyle(), this.fMinutes.getSize() -20));
				this.fSeconds = this.lMinutes.getFont();
				this.lSeconds.setForeground(new Color(0, 255, 255));
				this.lSeconds.setFont(new Font(this.lSeconds.getName(), this.fSeconds.getStyle(), this.fSeconds.getSize() -10));
			}
			this.countDownWindow.repaint();
			this.sleepForMillis(50);
		}
	}
	
	private String formatTime(int iTime) {
		return this.numberFormat.format(iTime);
	}
	
	private void sleepForMillis(int iWaitFor) {
		try {
			Thread.sleep(iWaitFor);
		} catch (InterruptedException e) {
			//nothing
		}
	}
	
	public void windowClosing(WindowEvent event){
		if ( this.countDownWindow != null ) {
			this.countDownWindow.dispose();
		}
		if ( this.inputWindow != null ) {
			this.inputWindow.dispose();
		}
		System.exit(0);
	} 
}
```


----------



## Ebenius (19. Dez 2003)

Gast hat gesagt.:
			
		

> ich denke DU siehst gleich, was los ist


Auch wenn Du jetzt lachst: Ich *habe* gleich gesehen was los ist. Deine _doCountDown()_-Methode läuft direkt im EventDispatcher-Thread. Dieser Thread wird auch zum Zeichnen benötigt. Daher kannst Du ihn nicht einfach blockieren und _repaint()_ aufrufen, da Du damit quasi das komplette UI totlegst.

 :idea: Vorschlag (Pseudo-Code):

```
public void actionPerformed(...)
{
    disableAllInteractingComponents();
    startTimer();
}
```
... und den Timer initialisierst Du dann so, dass er nach Ablauf der Zeit alles wieder enabled. Schau Dir einfach mal java.util.Timer und javax.swing.Timer an. Einer der beiden wird dir dann schon helfen.

 :!: Dadurch wird Dein Code auch erheblich kürzer und Du postest ihn weniger ungern  8) 

Es grüßt Ebenius


----------



## Ebenius (19. Dez 2003)

An dieser Stelle könnte auch folgendes Thema aus diesem Forum helfen: Button löst Schleife aus, danach friert die GUI ein ?

Es grüßt noch immer
Ebenius


----------



## Guest (19. Dez 2003)

Frage:
so "Button-Klicks" kann man eh NUR mit actionPerformed aufrufen oder?
weil aus dem Timer werd ich nicht wirklich schlau.

Wie könnte ich denn das machen?

thx


----------



## Ebenius (19. Dez 2003)

Dann lies Dir mal meinen letzten Link genau Durch. In diesem Beitrag ist auch nochmal auf eine Seite von Sun verlinkt, wie man mit Threads & Swing umgeht.

Viel Spaß.
Es grüßt Ebenius


----------



## hephaistos (20. Dez 2003)

hallo,

hab doch noch einiges suchen müssen, aber jetzt hauts hin 

habs mit new Thread gemacht - aber bis dahin wars ein langer weg.

danke für deine hilfe!


----------



## Ebenius (20. Dez 2003)

Wenn man ein bisschen dafür arbeitet ist der Erfolg doch um so schöner. Ist aber okay, die Party fing eh erst spät an; ich hatte Zeit. 

Es grüßt Ebenius


----------

