/*
R O G R A M M B E S C H R E I B U N G

Veränderung zur Vorgängerversion: 
Die Logik der Reaktion auf die Eingabe wird im Controller gesteuert, 
d.h es wird dort festgelegt, wie dasProgramm auf eine Eingabe 
(z.B. auf einen Klick eines Buttons) reagiert. 
Eine andere Möglichkeit, dies zu realisieren:
Aus dem Controller wird eine Wanze gemacht und diese an die  
Buttons angebracht. 
Da der Controller jetzt ein ActionListener ist, kann die Logik der Reaktion 
auf die Eingabe in der im Controller befindlichen Methode 
actionPerformed(...) implementiert werden. 


Model:
enthält die darzustellenden Daten und die zugehörigen Methoden.

View:
stellt die Daten des Models dar

Controller:
nimmt die Anwendereingaben (z.B. Mausklick auf Button "+") entgegen und 
verändert dementsprechend die Daten (Summenbildung) des Modells 
(mit Hilfe der Methoden des Models). 
 
 
*/

package taschenrechnermvc15;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;
import javax.swing.*;

public class StartklasseTaschenrechnerMVC15 {

    public static void main(String[] args) {
        TRController trController = new TRController();        
        TRView trView = new TRView();
        TRModel trModel = new TRModel();
        
        // Verlinken von M, V und C
        trController.setTrModel(trModel);
        trController.setTrView(trView);
        trView.setTrModel(trModel);
        
        // "Prozeße" starten
        trModel.WanzeAnbringen(trView);
        trView.WanzeAnbringen(trController);
    }
}

 
/*  
TRModel wird zu einem Ereignisauslöser gemacht, d.h. zum Leben erweckt. 
Außerdem wird an TRModel die Wanze TRView angebracht:
Jedes Mal, wenn im TRModel Daten geändert werden, wird durch 
setChanged() und notifyObservers() gefeuert, d.h. ein Ereignisobjekt geworfen
und dadurch die automatisch aufgerufene, ereigniseinfangende Methode 
update(...) in TRView aufgerufen.
*/
class TRModel extends Observable {
    private double speicherwert;

    public TRModel() {
        speicherwert=0;
    }
    
    public double getSpeicherwert(){
        return speicherwert;
    }

    public void setSpeicherwert(double wert){
        speicherwert=wert;
        // Dem Model das Feuern ermöglichen        
        setChanged();
        notifyObservers();        
    }

    public void addiereDazu(double wert) {
        speicherwert=speicherwert+wert;
        // Dem Model das Feuern ermöglichen
        setChanged();
        notifyObservers();        
    }
    
    public void WanzeAnbringen(TRView trView) {
        this.addObserver(trView);
    }
}

/*
TRView wird zu einer Wanze gemacht, die TRModel überwacht.
Dies geschieht, indem an TRModel die Wanze TRView angebracht wird.  
Außerdem wird an TRView die Wanze TRController angebracht, besser:
an die buttons buttonPlus und buttonGleich wird die Wanze
TRController angebracht:
Jedes Mal, wenn ein Button angeklickt wird, wird gefeuert, d.h. ein 
Ereignisobjekt geworfen und dadurch die automatisch aufgerufene, 
ereigniseinfangende Methode actionPerformed(ActionEvent ae) in
TRController aufgerufen.
*/  
class TRView extends JFrame implements Observer {
    private TRModel trModel;
    private JButton buttonPlus;
    private JButton buttonGleich;    
    private JTextField tfdZahl;

    public TRView(){        
        buttonsAnbringen();
    }

    public TRModel getTrModel() {
        return trModel;
    }

    public void setTrModel(TRModel trModel) {
        this.trModel = trModel;
    }
    
    public String getJTextField() {
        return tfdZahl.getText();
    }

    public void setJTextField(String str) {
        this.tfdZahl.setText(str);
    }
    
    public void buttonsAnbringen() {
        buttonPlus = new JButton("+");
        buttonGleich = new JButton("=");        
        tfdZahl = new JTextField("hier Zahl eingeben", 30);

        // Beim Anklicken dieses Buttons bekommt das geworfene Ereignisobjekt 
        // den Identifier "btn+". Dieser kann dann in der ereigniseinfangenden
        // Methode (zur Unterscheidung) verwendet werden
        buttonPlus.setActionCommand("btn+");
        // Beim Anklicken dieses Buttons wird der String "btn=" versendet.  
        buttonGleich.setActionCommand("btn=");
        
        getContentPane().add(buttonPlus, BorderLayout.EAST);
        getContentPane().add(buttonGleich, BorderLayout.WEST);
        getContentPane().add(tfdZahl, BorderLayout.CENTER);        
        this.setSize(200, 100);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    public void WanzeAnbringen(TRController tRController) {
        buttonPlus.addActionListener(tRController);
        buttonGleich.addActionListener(tRController);        
    }
    
    // wird automatisch aufgerufen (ereigniseinfangende Methode), 
    // wenn in TRModel ein Ereignisobjekt geworfen wird.
    public void update(Observable m, Object o) {
        if (m == trModel) {
            setJTextField(String.valueOf(trModel.getSpeicherwert()));            
        }
    }
}

/*
TRController wird zu einer Wanze gemacht, die TRView überwacht.
Dies geschieht, indem an TRView die Wanze TRController angebracht wird,
besser:
an die buttons buttonPlus und buttonGleich der TRView wird die Wanze
TRController angebracht:
Jedes Mal, wenn ein Button angeklickt wird, wird gefeuert, d.h. ein 
Ereignisobjekt geworfen und dadurch die automatisch aufgerufene, 
ereigniseinfangende Methode actionPerformed(ActionEvent ae) in
TRController aufgerufen.

*/
class TRController implements ActionListener{
    private TRView trView;
    private TRModel trModel;

    public TRController() {
    }

    public TRView getTRView() {
        return trView;
    }

    public TRView getTrView() {
        return trView;
    }

    public void setTrView(TRView trView) {
        this.trView = trView;
    }

    public TRModel getTrModel() {
        return trModel;
    }

    public void setTrModel(TRModel trModel) {
        this.trModel = trModel;
    }
    
    // wird automatisch aufgerufen (ereigniseinfangende Methode), 
    // wenn in TRView ein Ereignisobjekt geworfen wird (Button angeklickt).
    public void actionPerformed(ActionEvent ae){
        String str;
        // Das durch Anklicken eines der beiden buttons geworfene 
        // Ereignisobjekt kann genau identifiziert werden, d.h:
        // es kann genau festgestelt werden, woher (von welchem Button)
        // das Ereignis ausgelöst wurde.
        str=ae.getActionCommand();
        // System.out.println("Der String heisst: "+str);        
        
        if(str.equals("btn+")){
            double wert = Double.valueOf(trView.getJTextField());
            trModel.setSpeicherwert(wert);                
        }
        
        if(str.equals("btn=")){
            double wert = Double.valueOf(trView.getJTextField());
            trModel.addiereDazu(wert);                
        }
    }
}    
    
    
    
    
     