# Zaehler Ausgabe



## preo (23. Apr 2011)

Hallo liebe Community, 

ich bin ein JavaME (bzw. Java) Anfänger. Nun sollte ich für die Schule
ein Programm schreiben welches einen Timer startet wodurch eine Zählervariable
immer weiter Hochgezählt wird.

Nun habe ich das Programm in 2 Klassen erstellt
TimerGUI.java und Counter.Java. Im TimerGUI wird habe ich allgemein commands 
display etc. implementiert. Im Counter habe ich dann den Timer der gestartet wird
sowie get() set() Methoden. 

Jetzt mein Problem: Die Ausgabe der Zählervariable Klappt in der Klasse Counter
super jedoch im TimerGUI über get garnicht. Entweder habe ich garkeine Ausgabe
oder immer nur eine 0. Für die ausgabe habe ich eine While-Schleife welche durchläuft
solange die Variable timerSt = true ist. Ich hänge hier mal die Funktionierende version
mit Ausgabe über Counter an. Ich wäre sehr über eure Hilfe erfreut.

TimerGUI

```
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
 * @author Terror_Elch
 */
public class TimerGUI extends MIDlet implements CommandListener{

    private Display disp;
    private Form formMain;
    Counter count = new Counter();
    private Command cmdStart,cmdStop,cmdExit, cmdReset;
    public static StringItem msg;
    private boolean timerS;

    //<editor-fold defaultstate="collapsed" desc=" Generated Fields ">                      
    //</editor-fold>                    

 
    
    public TimerGUI() {
        formMain = new Form("Stopuhr");
        cmdStart = new Command("Start",Command.OK,0);
        cmdStop = new Command("Stop",Command.OK,0);
        cmdReset = new Command("Reset",Command.OK,0);
        cmdExit = new Command ("Exit",Command.EXIT,1);
        formMain.addCommand(cmdStart);
        formMain.addCommand(cmdExit);
        formMain.setCommandListener(this);
        msg = new StringItem("","Timer nicht Gestartet");
        
    }

    //<editor-fold defaultstate="collapsed" desc=" Generated Methods ">                       
    //</editor-fold>                     

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: initialize ">                                           
    /**
     * Initilizes the application.
     * It is called only once when the MIDlet is started. The method is called before the <code>startMIDlet</code> method.
     */
    private void initialize() {                                         
        // write pre-initialize user code here
                                           
        // write post-initialize user code here
    }                            
    //</editor-fold>                          

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: startMIDlet ">                                        
    /**
     * Performs an action assigned to the Mobile Device - MIDlet Started point.
     */
    public void startMIDlet() {                                      
        // write pre-action user code here
                                        
        // write post-action user code here
    }                             
    //</editor-fold>                           

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: resumeMIDlet ">                                         
    /**
     * Performs an action assigned to the Mobile Device - MIDlet Resumed point.
     */
    public void resumeMIDlet() {                                       
        // write pre-action user code here
                                         
        // write post-action user code here
    }                              
    //</editor-fold>                            

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: switchDisplayable ">                                              
    /**
     * Switches a current displayable in a display. The <code>display</code> instance is taken from <code>getDisplay</code> method. This method is used by all actions in the design for switching displayable.
     * @param alert the Alert which is temporarily set to the display; if <code>null</code>, then <code>nextDisplayable</code> is set immediately
     * @param nextDisplayable the Displayable to be set
     */
    public void switchDisplayable(Alert alert, Displayable nextDisplayable) {                                            
        // write pre-switch user code here
        Display display = getDisplay();                                               
        if (alert == null) {
            display.setCurrent(nextDisplayable);
        } else {
            display.setCurrent(alert, nextDisplayable);
        }                                             
        // write post-switch user code here
    }                                   
    //</editor-fold>                                 

    public Display getDisplay () {
        return Display.getDisplay(this);
    }


    public void exitMIDlet() {
        switchDisplayable (null, null);
        destroyApp(true);
        notifyDestroyed();
    }


    public void startApp() {

        disp = Display.getDisplay(this);
        disp.setCurrent(formMain);
        formMain.append(msg);

    }


    public void pauseApp() {

    }


    public void destroyApp(boolean unconditional) {
    }

    public void commandAction(Command c, Displayable d){
        if(c==cmdExit){
            destroyApp(true);
            notifyDestroyed();
        }
        if(c==cmdStart){

            
            formMain.removeCommand(cmdStart);
            formMain.addCommand(cmdStop);
            count.timerStart();
 
        }
        if(c==cmdStop){
            formMain.removeCommand(cmdStop);
            formMain.addCommand(cmdReset);
            count.timerStop();
        }
        if(c==cmdReset){
            formMain.removeCommand(cmdReset);
            formMain.addCommand(cmdStart);
            count.timerReset();
        }
    }


}
```

Counter

```
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.util.Timer;
import java.util.TimerTask;

/**
 * @author Terror_Elch
 */
public class Counter extends TimerTask {

    private Timer timer;
    private int zaehler;
    private int interval = 1000;

synchronized public int getZaehler(){
        return this.zaehler;
    }
    public void setZaehler(int z){
        this.zaehler = z;
    }

    public void timerStart(){
        timer = new Timer();
        timer.schedule(new Counter(), interval, interval);
    }

    public void timerStop(){
        timer.cancel();
        timer = null;
    }
    public void timerReset(){
        zaehler = 0;
        TimerGUI.msg.setText(""+zaehler);
    }

    public void run(){
        zaehler++;
        TimerGUI.msg.setText(Integer.toString(zaehler));
    }

}
```

Mit freundlichen Grüßen 

Preo


----------



## SlaterB (24. Apr 2011)

du postest also den funktionierenden Code, zu dem du keinerlei Fragen hast

ansonsten hast du noch ein nicht funktionierendes Programm, dessen Code du nicht postest,
und suchst nun einen Hellseher?


----------



## preo (25. Apr 2011)

Ich dachte jemand hätte mir das Umformen können.
Also das andere Programm sieht so aus wie das Obige
mit der ausnahme das ich zeile 130 des TimerGUI folgende
Zeilen hinzugefügt werden.


```
timerS = true;
while(timerS = true){
msg.setText(Integer.toString(count.getZaehler));
}
```

im Counter fällt dann die Zeile 41 Weg.

Mit freundlichen Grüßen

Preo


----------



## SlaterB (26. Apr 2011)

= true weist einer Variablen true zu, == true vergleicht auf true,
wenn es eine lokale Variable ist und keine Abbruchmöglichkeit gibt, dann kannst du auch gleich while(true) für Endlosschleife schreiben,
übrigends mit potentiell Millionen Durchläufen pro Sekunde, wenn du keine Pause einlegst

wenn du das ganze wirklich in Zeile 130 einfügst, dann passiert das vor counter.start(), richtig?
der startet nie weil die Schleife ewig dauert, ergo maximal 0,

dann gibt es noch die Regel, dass man in GUI-Aktionen keine messbare Zeit belegen sollte, weil die GUI solange gar nichts anderes machen kann (wie neuzeichnen oder auf weitere Events reagieren), solange ein Event dran ist,
der Timer ist nicht nur für Zeitmessung, sondern auch für nebenläufige Ausführung,
daher ist eine solche Schleife generell ungünstig


----------



## preo (26. Apr 2011)

Habe jetzt deine Tipps angewendet.
Nun habe ich das Problem das in meiner GUI die 
getZaehler Methode eine 0 ausliefert. 
Gebe ich es jedoch in der Klasse Counter aus
wird normal (über getZaehler()) die Zahl hochgezählt.

Habe es nochmal mit System.out.println(); ausgegeben
um zu sehen was Ausgeliefert wird.

Hat jemand vllt. eine Idee warum die GUI Klasse nur
eine 0 Zurückbekommt ? ???:L

Mit freundlichen Grüßen

Preo


----------



## SlaterB (26. Apr 2011)

vielleicht zwei verschiedene Counter-Objekte?
poste doch bitte vollständigen Code oder was genau hast du von der geposteten funktionierenden Variante geändert, 
nur Zeile 41 in run() von Counter?
TimerGUI.msg.setText(Integer.toString(zaehler));
?


----------



## preo (27. Apr 2011)

Guten Morgen,

Hier ist der aktuelle Code


TimerGUI, Ausgabe der Werte befindet sich in Zeile 134.

```
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
 * @author Terror_Elch
 */
public class TimerGUI extends MIDlet implements CommandListener{

    private Display disp;
    private Form formMain;
    Counter count = new Counter();
    private Command cmdStart,cmdStop,cmdExit, cmdReset;
    public static StringItem msg;
    private boolean timerS;

    //<editor-fold defaultstate="collapsed" desc=" Generated Fields ">                      
    //</editor-fold>                    

 
    
    public TimerGUI() {
        formMain = new Form("Stopuhr");
        cmdStart = new Command("Start",Command.OK,0);
        cmdStop = new Command("Stop",Command.OK,0);
        cmdReset = new Command("Reset",Command.OK,0);
        cmdExit = new Command ("Exit",Command.EXIT,1);
        formMain.addCommand(cmdStart);
        formMain.addCommand(cmdExit);
        formMain.setCommandListener(this);
        msg = new StringItem("","Timer nicht Gestartet");
        
    }

    //<editor-fold defaultstate="collapsed" desc=" Generated Methods ">                       
    //</editor-fold>                     

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: initialize ">                                           
    /**
     * Initilizes the application.
     * It is called only once when the MIDlet is started. The method is called before the <code>startMIDlet</code> method.
     */
    private void initialize() {                                         
        // write pre-initialize user code here
                                           
        // write post-initialize user code here
    }                            
    //</editor-fold>                          

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: startMIDlet ">                                        
    /**
     * Performs an action assigned to the Mobile Device - MIDlet Started point.
     */
    public void startMIDlet() {                                      
        // write pre-action user code here
                                        
        // write post-action user code here
    }                             
    //</editor-fold>                           

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: resumeMIDlet ">                                         
    /**
     * Performs an action assigned to the Mobile Device - MIDlet Resumed point.
     */
    public void resumeMIDlet() {                                       
        // write pre-action user code here
                                         
        // write post-action user code here
    }                              
    //</editor-fold>                            

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: switchDisplayable ">                                              
    /**
     * Switches a current displayable in a display. The <code>display</code> instance is taken from <code>getDisplay</code> method. This method is used by all actions in the design for switching displayable.
     * @param alert the Alert which is temporarily set to the display; if <code>null</code>, then <code>nextDisplayable</code> is set immediately
     * @param nextDisplayable the Displayable to be set
     */
    public void switchDisplayable(Alert alert, Displayable nextDisplayable) {                                            
        // write pre-switch user code here
        Display display = getDisplay();                                               
        if (alert == null) {
            display.setCurrent(nextDisplayable);
        } else {
            display.setCurrent(alert, nextDisplayable);
        }                                             
        // write post-switch user code here
    }                                   
    //</editor-fold>                                 

    public Display getDisplay () {
        return Display.getDisplay(this);
    }


    public void exitMIDlet() {
        switchDisplayable (null, null);
        destroyApp(true);
        notifyDestroyed();
    }


    public void startApp() {

        disp = Display.getDisplay(this);
        disp.setCurrent(formMain);
        formMain.append(msg);

    }


    public void pauseApp() {

    }


    public void destroyApp(boolean unconditional) {
    }

    public void commandAction(Command c, Displayable d){
        if(c==cmdExit){
            destroyApp(true);
            notifyDestroyed();
        }
        if(c==cmdStart){

            timerS = true;
            formMain.removeCommand(cmdStart);
            formMain.addCommand(cmdStop);
            count.timerStart();
            while(timerS == true)
            {
            msg.setText(Integer.toString(count.getZaehler()));
            }

        }
        if(c==cmdStop){
            formMain.removeCommand(cmdStop);
            formMain.addCommand(cmdReset);
            count.timerStop();
        }
        if(c==cmdReset){
            formMain.removeCommand(cmdReset);
            formMain.addCommand(cmdStart);
            count.timerReset();
        }
    }


}
```

Counter


```
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.util.Timer;
import java.util.TimerTask;

/**
 * @author Terror_Elch
 */
public class Counter extends TimerTask {

    private Timer timer;
    private int zaehler;
    private int interval = 1000;

synchronized public int getZaehler(){
        return this.zaehler;
    }
    public void setZaehler(int z){
        this.zaehler = z;
    }

    public void timerStart(){
        timer = new Timer();
        timer.schedule(new Counter(), interval, interval);
    }

    public void timerStop(){
        timer.cancel();
        timer = null;
    }
    public void timerReset(){
        zaehler = 0;
        TimerGUI.msg.setText(""+zaehler);
    }

    public void run(){
        zaehler++;
        
    }

}
```

Es sieht so aus als hätte die GUI ein Problem
mit der getZaehler-Methode und würde keine
Werte erhalten. Wie gesagt wenn ich in Zeile
136 System.out.println benutze bekomme
ich wenigstens auf der Console eine 0 Ausgegeben.
Habe leider keine Ahnung woran das liegen könnte.


----------



## SlaterB (27. Apr 2011)

mein Gedächtnis ist ja schlecht, aber zum Glück wird alles notiert, 
enthielt meine vorherige Antwort nicht zufällig Sätze wie 



SlaterB hat gesagt.:


> dann gibt es noch die Regel, dass man in GUI-Aktionen keine messbare Zeit belegen sollte, weil die GUI solange gar nichts anderes machen kann [..]
> daher ist eine solche Schleife generell ungünstig


?

gut, ich habe auch bisschen anderes erzählt, etwa dass der Timer vor der Schleife gestartet werden sollte,
das hilft anscheinend nicht, 
aber die Schleife ist wirklich böse böse böse, darauf kann man sich konzentrieren 
setzte ein System.out.println("xy") in die run-Methode des Timers, und prüfe, ob diese Ausgabe kommt,
einmal mit Schleife, einmal ohne Schleife in der GUI (ganz egal ob das Ergebnis gesetzt wird)

keine Schleife in der GUI, höchstens nebenläufig per Thread bzw. Timer!


----------



## preo (27. Apr 2011)

Alle Varianten von System.out.println("xy"); funktionieren.
In der run()-Methode des counters sowie in der
GUI mit und ohne Schleife. 

Das große Problem ist ja das Beschaffen der Zahl 
über getZaehler(); da die TimerGUI immer wieder
eine 0 bekommt selbst wenn im Counter die Ausgabezeile
über getZaehler abläuft, und diese dann richtige
Werte liefert.

Könnte ich eine Schleife bauen die bei jedem Tick des 
Timers aus counter eine Zeile ausgibt ? 

Danke für die Hilfe


----------



## SlaterB (27. Apr 2011)

ok, zurück zur dritten Antwort "vielleicht zwei verschiedene Counter-Objekte?"
so ist es nämlich, in Counter schreibst du
[c]timer.schedule(new Counter(), interval, interval);[/c]
die run-Methode wird also in einem anderen Counter-Objekt ausgeführt als in der GUI bekannt, verwende
[c]timer.schedule(this, interval, interval);[/c]


----------



## preo (27. Apr 2011)

Ah tatsächlich jetzt klappt es .
Heh auf sowas wär ich wohl nie gekommen.

Danke dir vielmals.

Eine kleine Frage bleibt aber offen...
Ist es möglich eine for-Schleife zu schreiben
die bei jedem TimerTick eine ausgabe macht ?

Oder müsste ich da zusätzlich einen 2en Timer
in die GUI einbauen für die Ausgabe ?


----------



## SlaterB (27. Apr 2011)

was spricht denn grundsätzlich dagegen das einfach den Timer machen zu lassen, also die ursprüngliche Version?
wenn du den Code nicht in einer separaten Klasse haben willst, 
kannst du ein anonymes Runnable-Objekt definieren und an Counter übergeben, damit der diesen Code ausführt


----------



## preo (27. Apr 2011)

Es würde im prinzip nichts dagegen sprechen
die Ausgabe über den Counter zu realisieren.
Leider war in der Aufgabenstellung vorgegeben
das dies im TimerGUI passieren soll .

Danke dir für deine Hilfe

Ich war schon völlig am Verzweifeln.

Mit freundlichen Grüßen

Preo


----------

