Zeitschleife

Status
Nicht offen für weitere Antworten.

Cardmaster

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


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

Cardmaster

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

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

Diagramm.jpg


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


Ablauf.jpg


Hoffe das bringt etwas.
 

Prusik

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

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

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

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

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

Mitglied
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

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


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

Mitglied
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

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

Mitglied
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

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

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

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

Cardmaster

Mitglied
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

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

Mitglied
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

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

Code:
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
Code:
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)
Code:
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

Aktives Mitglied
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...
Code:
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:

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

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

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

Code:
   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.
Code:
splashScreen.setCommandListener(this);
und
2.
Code:
this.screen = screen;

nicht wirklich aus.



[/code]import org.netbeans.microedition.lcdui.SplashScreen;
Code:
kennt er gar nicht.

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

Prusik

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

Code:
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();
    }
}
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:

Code:
   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();
    }
}
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.
Code:
splashScreen.setCommandListener(this);
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.
Code:
this.screen = screen;

nicht wirklich aus.
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...


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

Code:
Zaehler z = new Zaehler(splashScreen);


Cardmaster hat gesagt.:
[/code]import org.netbeans.microedition.lcdui.SplashScreen;
Code:
kennt er gar nicht.
[/quote]
wirf diese Zeile mal raus.. ich hatte ein Problem, weil es noch einen anderen SplashScreen in einem anderen Package gibt - wenn ich mich richtig errinnere... 

[quote]

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

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

Bekanntes Mitglied
Naja ich denke mal wenn du Sachen wie
Code:
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

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

Code:
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 ?

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

Aktives Mitglied
Code:
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).


Code:
catch (Exception ex) {
                    ex.printStackTrace();
}
gibt die Fehlermeldung aus.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Throwable.html#printStackTrace()
 
Status
Nicht offen für weitere Antworten.

Oben