# Zeitschleife



## Cardmaster (25. Dez 2007)

Wollte mich jetzt mit meinem nächsten Projekt ein wenig mit Schleifen beschäftigen. Zu diesem Zweck hab ich ein Programm geschrieben, welches per do while Anweisung die fortschreitende Zeit in Sekundenintervallen angibt.



```
do{
       
       ++s;
         
       try{Thread.sleep(1000);}
       catch(InterruptedException e){}
       
      
       System.out.println("Sek:"+s); 
     splashScreen.setText("Sek:"+s);
            
     }  
     while(s=>0) ;
        
splashScreen.setText("Sek:"+s);
```

Die Ausgabe des Textes will aber nicht so ganz funktionieren. Zur Kontrolle habe ich eine System.out.println-Anweisung in das Programm eingebaut. Diese funktioniert so wie ich es mir vorgestellt habe. Die Anweisung, welche den Text aber wirklich auf dem Handy anzeigt (splashScreen.setText) gibt keinerlei Zahlen aus. Was habe ich falsch gemacht ? Hoffe auf Hilfe. 
Frohe Weihnachtstage


----------



## Prusik (25. Dez 2007)

zeig bitte mal den Code, wo du splashScreen auf das Fenster dazufügst...


----------



## Cardmaster (26. Dez 2007)

Hier der Code, welcher den Splashscreen erstellt. (er wurde automatisch von Netbeans generiert, von daher gaube ich nicht, dass hier der Fehler liegt).


```
public SplashScreen getSplashScreen() {
        if (splashScreen == null) {
            // write pre-init user code here
            splashScreen = new SplashScreen(getDisplay());
            splashScreen.setTitle("splashScreen");
            splashScreen.addCommand(getOkCommand());
            splashScreen.setCommandListener(this);
            // write post-init user code here
        }
        return splashScreen;
    }
```

Hier noch mal ein Flowdiagramm-Bild zum Programmablauf:







Und hier die Reihenfolge, in der die einzelnen Kompontenten erstellt werden:







Hoffe das bringt etwas.


----------



## Prusik (26. Dez 2007)

kannst du mal eine Ausgabe vor der Schleife auf dem Fenster machen lassen? Funktioniert das? 


```
splashScreen.setText("Ich war da"); 
do{
       
       ++s;
         
       try{Thread.sleep(1000);}
       catch(InterruptedException e){}
       
     
       System.out.println("Sek:"+s);
     splashScreen.setText("Sek:"+s);
           
     } 
     while(s=>0) ;
```

Wie sieht jetzt die Ausgabe aus? kommt gar nichts, oder was steht?
Kommentier zu Versuchszwecken auch mal noch die beiden unteren splashScreen.setText("..."); aus, damit wir sehen, ob es das gerade überschreibt...

So finden wir raus, ob das Problem in der Schleife liegt, oder wo auch immer...


----------



## Cardmaster (26. Dez 2007)

Ich habe den Quellcode jetzt wie unten stehend verändert:


```
splashScreen.setText("Ich war da"); 
        do{
       
       ++s;
         
       try{Thread.sleep(1000);}
       catch(InterruptedException e){}
       
     
       System.out.println("Sek:"+s);
//   splashScreen.setText("Sek:"+s);
           
     } 
     while(s>=0) ;
//splashScreen.setText("Sek:"+s);
```

Dabei hat sich jedoch nichts am Programmablauf verändert. Ich drücke auf den Ok-Button im Programm, daraufhin beginnt die Schleife endlos per System.out.println Sek:1 Sek:2 ... auszugeben. Der SplashScreen, welcher währenddessen angezeigt wird ändert sich jedoch nicht. Er bleibt weiß.


----------



## Prusik (26. Dez 2007)

edit: das war falsch... 

hm.. das Objekt ist vorhanden, also keine NullPointerException... aber die setText-Methode macht nix. Gibts irgend ne stelle im Programm, wo es funktioniert, also wo du text setzen kannst?
------------------------
edit: langsam wirds peinlich.. http://java.sun.com/javase/6/docs/api/java/awt/SplashScreen.html keine ahnung wieso dass ich es zuvor nicht gefunden habe.. habe nach SplashScreen gegoogelt da kommt nix in den ersten einträgen, Splash Screen schon.. grr... 

nur sehe ich da nirgends eine methode set setText() *nichtsmehrversteh*


----------



## Cardmaster (29. Dez 2007)

Mmh also bei meinem ersten Javaprogramm, wo ich einen Zufallsgenerator erstellt habe ging das mit Splashscreen und "set Text". Und wenn ich die Schleifenanweisung entferne und nur noch die set Text Anweisung reinsetze geht es auch. 
Gibt es eine andere Möglichkeit Text in einer Schleife auf den Handybildschirm auszugeben  :roll: ? Ich meine es muss ja nicht unbedingt der SplashScreen sein.


----------



## Prusik (29. Dez 2007)

kannst du es mal mit einer anderen Schleife probieren (bin irgendwie ratlos.. aber ein versuch ists wert...)



```
splashScreen.setText("Ich war da");
int s=0;
while(1==1){
       
       s++;
         
       try{
            Thread.sleep(1000);
       }
       catch(InterruptedException e){
             e.printStackTrace();
       }
       
     
       System.out.println("Sek:"+s);
//   splashScreen.setText("Sek:"+s);
           
     }
splashScreen.setText("Sek:"+s);
```

hab auch sonst noch einiges geändert.. vielleicht hilfts ja was...


----------



## Cardmaster (29. Dez 2007)

Also ich habe mal die Schleife eingefügt, dass Ergebnis war jedoch das Selbe. Die letzte SplasScreen - Anweisung am Ende erreicht das Programm nicht, weil davor eine Endlossschleife produziert wird.

Wie kann ich denn ansonsten ein Zeitmesserprogramm realisieren muss es über eine Schleife sein ?


----------



## Prusik (29. Dez 2007)

ah moment.. also die schleife läuft durch, und beendet einfach nicht.. kannst du auch ausgeben (edit: auf dem splashScreen)?! hab gemeint das funktioniere nicht? 

wer löst denn die Stopuhr aus, bzw. wann soll sie gestoppt werden?


----------



## Cardmaster (1. Jan 2008)

Ich habe jetzt erst nur einmal einen Endlosschleife programmiert, die durch einen Knopfdruck vom Andwender ausgelöst werden soll. Die Schleife arbeitet ja so wie sie es soll (die Syste.out.println()-Ausgabe macht ja genau das, was sie soll. Das Problem liegt (das hast du schon richtig verstanden) beim Splashscreen. Dieser verändert sich nicht. Er sollte aber genau das selbe anzeigen wie die System.out.println()-Anweisung.

Sonstige Ausgaben auf dem Splashscreen (also wenn ich keine Schleife verwende) gingen bis jetzt ohne Probleme.


----------



## Prusik (2. Jan 2008)

was passiert, wenn du die endlosschleife durch eine begrenzte Schleife ersetzt, also ein 


```
for(int i=0;i<1000;i++){
//...
}
```

und wenn du den Thread entfernst? (zuerst in der begrenzten Schleife).


----------



## Cardmaster (2. Jan 2008)

Also ich habe das jetzt einmal mit der begrentzen Schleife ausprobiert. Das Ergebnis war jedoch wieder das selbe, wie oben beschrieben.  Wie meinst du das genau mit Thread löschen ?
Ich denke mitlerweile nicht mehr, dass es an der Schleife sondern irgendwie am Aufruf von SplasScreen liegt, was genau das aber sein könnte hab ich keine Ahnung.
Noch mal Danke für die Hilfe!


----------



## Prusik (2. Jan 2008)

Danke für welche Hilfe? Siehst ja, dass ich eigentlich keine Ahnung habe, nur versuche, das Problem irgwendwie einzugrenzen.. um es vielleicht dann doch noch zu lösen.. aber mit J2ME hab ich eigentlich noch nie wirklich gearbeitet, mal eine kurze einführung...

das mit dem Thread löschen meinte ich so:

```
splashScreen.setText("Ich war da");

for(int s=0;i<1000;i++){     
      System.out.println("Sek:"+s);
      splashScreen.setText("Sek:"+s);         
     }
splashScreen.setText("und fertig");
```

So können wir sehen, ob das Problem nicht am Thread liegt.. und bis 1000 wird wohl noch gezählt werden können ohne dem CPU eine Verschnaufpause zu geben.. gänge ja auch noch viel höher  einfach zum schauen ob das so geht.. um zu wissen, was Probleme darstellt.


----------



## Cardmaster (4. Jan 2008)

Ich habe mal ein bissel rum gesurft und bin dabei auf einen wie ich finde sehr interessanten Foreneintrag gestoßen:

www.wer-weiss-was.de/theme35/article4347168.html

Hoffe es ist erlaubt auf andre Foren zu verlinken.

So wie ich den obigen Eintrag verstanden habe liegt das Problem daran, dass die Schleife alle Rechenkapazität für sich beansprucht und die Anzeige somit blockiert. Die Anzeige soll nur ganz am Schluss (wenn die Schleife durchlaufen ist) wieder etwas anzeigen können.
Der Test meines Programms mit einer Durchlaufszeit von nur 10 sec hat das auch bestätigt.

Mal schauen, ob ich das schwierige Problem mit meinen Anfängerkenntnissen überhaupt lösen kann oder ob ichs lieber bleiben lasse.
@Prusik: Hilfe insofern das du etwas postest und dich für mein Problem interessierst.

Wäre gut, wenn mir das noch jemand etwas genauer erklären könnnte, mit Threads kenn ich mich noch nicht besonders gut aus.

Meines Erachtens nach könnte man die Schleife auch durch irgendetwas (z.B. einen weiteren Druck auf eine Taste) unterbrechen/beenden und dann halt die Zeit (ganz zum Schluss anzeigen) lassen. Ist das denn zu realisieren ?


----------



## Prusik (4. Jan 2008)

wenn man Probleme nur mit Interesse lösen könnte, dann gebe es fast keine Probleme mehr... wobei Interesse chan Probleme lösen, aber lassen wir den philsophischen Teil 

edit: übersetzung CH-Deutsch - Deutsch, war gerade nicht konzentriert... : chan = kann 

Zu den Threads, das ist keine Hexerei... 
schau dir doch mal
http://www.galileocomputing.de/openbook/javainsel6/javainsel_09_001.htm#Xxx999359 an... da ist es sehr gut beschrieben! 

ich versuchs mir auch mal zu überlegen, du müsstest die Schleife in einen anderen Thread nehmen... also beispielsweise so:


```
class Zaehler implements Runnable {
int wert;
public void setWert(wert){
this.wert = wert
}
public int getWert(){
}
public run(){
        do{
       try{Thread.sleep(50);}
       catch(InterruptedException e){}
       

           
     }
     while(s>=0) ;
}    

}
```

sowie die Klasse mit dem SplashScreen

```
class XY{
Zaehler z;
public SplashScreen getSplashScreen() {
        if (splashScreen == null) {
            // write pre-init user code here
            splashScreen = new SplashScreen(getDisplay());
            splashScreen.setTitle("splashScreen");
            splashScreen.addCommand(getOkCommand());
            splashScreen.setCommandListener(this);
             z = new Zaehler();
            splashScreen.setText("Wert zurzeit"+z.getWert());
            // write post-init user code here
        }
        return splashScreen;
    }
```


und um die Schleife zu starten (im ActionListener)

```
z.start();
```

Ich hoffe, ich gebe dir hier keinen blödsinn an, ich würds mal so probieren, ich hatte mal ein ähnliches Problem, als ich eine Stoppuhr brauchte, um zu schauen, wie lange der User hat um sein Memory aufzulösen... 
Eventuell stimmts auch überhaupt nicht - bin auch noch nicht so lange bei Java, und im griff hab ichs au noch nicht so.. aber total falsch wirds nicht sein, sonst werd ich dann schon korrigiert...


----------



## Prusik (4. Jan 2008)

Schande über mich, j etzt mach ich einen Doppelpost, aber das ists mir wert.. ich habs rasch ausprobiert.. und das klappt also: hat nicht ganz gestimmt oben, aber fast... die richtung war richtig...
Und zwar siehst jetzt so aus:

Klasse Zaehler mit dem Thread.. gänge auch irgendwie mit Runnable, aber habs gerade nicht im kopf, mit extends Thread gehts auf jeden fall auch.. den unterschied müsste man mal  nachlesen... 

```
import org.netbeans.microedition.lcdui.SplashScreen;

public class Zaehler extends Thread{
    private SplashScreen screen;
    public Zaehler(SplashScreen screen){
        this.screen = screen;
    }
    public void run() {
            for(int i = 0;i<10;i++){
                try {
                    screen.setText("Zahl:"+i);
                    System.out.println(i);
                    Thread.sleep(500);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
    }
}
```

Und dann in der Klasse, die das GUI erzeugt:


```
public SplashScreen getSplashScreen() {
        if (splashScreen == null) {
            // write pre-init user code here
            splashScreen = new SplashScreen(getDisplay());
            splashScreen.setTitle("splashScreen");
            splashScreen.setCommandListener(this);
            // write post-init user code here
            Zaehler z = new Zaehler(splashScreen);
            z.start(); //Aufruf könnte z.B. auch in einem Listener stattfinden
            
        }
        return splashScreen;
    }
```

hoffe das klappt so


----------



## Cardmaster (7. Jan 2008)

Mmh bin einfach zu blöd. Habe jetzt versucht mein Programm in ein Multithreadingprogi umzuschreiben. NetBeans sagt mir jeodch dann immer hierbei:


```
public class MultiThread {   //illegal start of expression
    public static void main(String args[]){   //inner classes cannot have static declarations
        AusgabeThread a = new AusgabeThread();
       a.start();
    }
}
```

Mein gesamter Quellcode im Abschnitt Method sieht dabei so aus:


```
switchDisplayable(null, getSplashScreen());
     class ZeitschleifeThread extends Thread {
 int zeit;
    public void run (){
 while (true){
     ++zeit;
 System.out.println("Zeit1:"+zeit)    ;
 }    
 }   
}

class AusgabeThread extends Thread {
 
 ZeitschleifeThread z = new ZeitschleifeThread();
  public void run(){
  z.start();
  while (true)
      if (z.zeit>0){
        System.out.println("Zeit2:"+z.zeit)    ;  
      }
  }
 }    
    

public class MultiThread {
    public static void main(String args[]){
        AusgabeThread a = new AusgabeThread();
       a.start();
    }
}
```

Was mache ich nur falsch. Könntest du mir als blutigem Anfänger die beiden Codebeispiele noch etwas erläutern ich kenn mich z.B. mit :

1.
	
	
	
	





```
splashScreen.setCommandListener(this);
```
und
2. 
	
	
	
	





```
this.screen = screen;
```

nicht wirklich aus.



[/code]import org.netbeans.microedition.lcdui.SplashScreen;
	
	
	
	





```
kennt er gar nicht.

Dennoch danke für die beiden Posts. (es liegt ja an mir das ich es net raffe)
```


----------



## Prusik (7. Jan 2008)

Cardmaster hat gesagt.:
			
		

> Mmh bin einfach zu blöd. Habe jetzt versucht mein Programm in ein Multithreadingprogi umzuschreiben. NetBeans sagt mir jeodch dann immer hierbei:
> 
> 
> ```
> ...


Steht doch... inner classes cannot have static declarations... Ich hab eine eigene Klasse gemacht.. also im Netbeans recahtsklick auf den Projektordner (package), neue Klasse, und dort das rein. 


			
				Cardmaster hat gesagt.:
			
		

> Mein gesamter Quellcode im Abschnitt Method sieht dabei so aus:
> 
> 
> ```
> ...


Wieso hast du zwei Threads? ich hab nur einen... 




			
				Cardmaster hat gesagt.:
			
		

> Was mache ich nur falsch. Könntest du mir als blutigem Anfänger die beiden Codebeispiele noch etwas erläutern ich kenn mich z.B. mit :
> 
> 1.
> 
> ...


Das sollte bei dir auch stehen, ist von NetBeans generiert... Ist eigentlich nicht von relevanz -trotzdem kurz, was es bedeutet, kennst du das Listener-Prinzip? Ja, wir haben ja von ActionListenern gesprochen, ist eingelich das gleiche, nur jetzt auf commands, also z.B. ein Tastendruck (ich hoffe, das stimmt, hab nicht nachgesehen und kenne mich wie schon gesagt nicht aus mit J2ME)



			
				Cardmaster hat gesagt.:
			
		

> und
> 2.
> 
> 
> ...


sorry, ich hab die variablennamen nicht schön gewählt - also normalerweise macht man das so, aber wenn man das noch nie gesehen hat ists nicht schön übersichtlich...



```
public class Zaehler extends Thread{
    private SplashScreen screen;
    public Zaehler(SplashScreen screen_uebergabe){
        this.screen = screen_uebergabe;
    }
    public void run() {
            for(int i = 0;i<10;i++){
                try {
                    screen.setText("Zahl:"+i);
                    System.out.println(i);
                    Thread.sleep(500);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
    }
}
```
Du setzt das Attribut screen der Klasse Zaehler auf den übergabewert - der hier übergeben wird: 


```
Zaehler z = new Zaehler(splashScreen);
```




			
				Cardmaster hat gesagt.:
			
		

> [/code]import org.netbeans.microedition.lcdui.SplashScreen;
> 
> 
> 
> ...



gerngeschehen - ich lern auch laufend Neues (auch hier) und bin auch froh, wenn mir geholfen wird! 

Ich hoffe, das klappt jettz sonst einfach nochmals nachhacken... es ist eher für mich peinlich, wenn ich es nicht erklären kann [/code]


----------



## MiMij (8. Jan 2008)

Naja ich denke mal wenn du Sachen wie

```
this.screen = screen;
```
Nicht verstehst, solltest du nochmal mit den Java grundlagen anfangen und dann dich weiter vorarbeiten bis du ach zu Threads kommst.


----------



## Cardmaster (9. Jan 2008)

Ah super, 
jetzt ist mir um einiges mehr klar. Das mit der eingenständigen Klasse erzeugen war der Knackpunkt bei dem ganzen was ich net gecheckt habe. 

Jezt habe ich nur noch eine Frage:


```
import org.netbeans.microedition.lcdui.SplashScreen;
```

wieso muss man bei der Klassendeklaration "org.netbeans" in die import Anweisung einfügen. Das habe ich vorher noch nie gemacht und bin deshalb ein wenig verwundert. Könnte ich das bitte noch erklärt bekommen ?

Und was hat es mit dieser Exception auf sich ? Was wird da abgefangen ? Meines Meinung nach ist das auf das Sleep Command zurück zu führen. Stimmt das ?


```
catch (Exception ex) {
                    ex.printStackTrace();
                }
```



Ich wollte jetzt gerne die Anwendung auch über einen Button "Stop" unterbrechen können. Aber wie mache ich das? Die Anweisung z.sleep(); hat bei mir nicht recht funktioniert (hatte wieder den Anschein, der Compiler kennt den Thread so von außen nicht).


Vielen Dank noch einmal. Jetzt bin ich echt ein gutes Stück weiter gekommen.[/code]


----------



## Prusik (9. Jan 2008)

```
import org.netbeans.microedition.lcdui.SplashScreen;
```

lass das NetBeans besorgen, ich würd die Zeile löschen, schauen wos eine Meldung gibt, und dann soll dir NetBeans die richtige Klasse laden - die im lcdui und nicht die andere (weiss nicht mehr wo die war). 



```
catch (Exception ex) {
                    ex.printStackTrace();
}
```
gibt die Fehlermeldung aus. 
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Throwable.html#printStackTrace()


----------

