//Titel:            MVC Pattern mit Testbeispiel für MDI-Fenster
//Version:          2.0, 06.11.2010
//Copyright:        HS-Harz, FB AI
//Autor:            Dipl.-Inf.(TU) Dipl.-Ing.(FH) Michael Wilhelm
//Beschreibung:     Beispiel eines MVC mit Enter-Taste fuer den Datentransfer
//                  Modell und Controller zusammen in einer Klasse


// Beispiel für das Observer Design Pattern
// Mit der Eingabetaste wird der Inhalt aktualisiert
// Modell und Controller zusammen

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


// InternalFrame
import javax.swing.event.*;

import java.util.Observable;
import java.util.Observer;


public class MVC2 extends JFrame {

  // Container für die Clientfenster
  private JDesktopPane _desktopPane = new JDesktopPane();

    // Menü Variablen
  private JMenuBar menuBar1;
  private JMenu MainFile;
  private JMenuItem MnNew;
  private JMenuItem MnOpen;
  private JMenuItem MnClose;

  private JMenu MainEdit;
  private JMenuItem MnCut;
  private JMenuItem MnCopy;
  private JMenuItem MnInsert;

  private int _Fensternummer=0;


   // 3. Schritt  die Modell Variable im JFrame deklarieren
  private Modell _modell;   // Modell 

   // Konstruktor
  public MVC2() {
    this.setSize(new Dimension(800, 400));
    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    setGUI();
  }

  public void setGUI() {
    this.getContentPane().setLayout( new BorderLayout() );
    this.setContentPane(_desktopPane);

    setMenus();
    // 4. Schritt  die Modell+Controller Variable erzeugen
    _modell = new Modell();
    _modell.setName("Paul");
  }



    // setzt die Menüs
  private void setMenus() {
    menuBar1 = new JMenuBar();

      // DATEI
    MainFile = new JMenu("Datei");
    MnNew = new JMenuItem("Neu");
    MnClose = new JMenuItem("Schließen");

    MnNew.addActionListener(new ActionListener()  {
      public void actionPerformed(ActionEvent e) {
        MnNew_click();
      }
    });
    MnNew.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
    MainFile.add(MnNew);

    MainFile.addSeparator();

    // --------------------------
    MnClose.addActionListener(new ActionListener()  {
      public void actionPerformed(ActionEvent e) {
        MnClose_click();
      }
    });
    MainFile.add(MnClose);


    menuBar1.add(MainFile);

    // ----------------
    this.setJMenuBar(menuBar1);

  } // setMenus


  // Menü Aktions Methoden

  void MnNew_click() {
    JInternalFrame[] ff = _desktopPane.getAllFrames();
    int n=ff.length+1;
    _Fensternummer++;

    // 7. Schritt  Viewer in der Methgode "New_click" erzeugen    
   JFInternalFrame1 frame = new JFInternalFrame1(
           Integer.toString(_Fensternummer),
         n%3, _modell);

    ff = _desktopPane.getAllFrames();
    int i = ff.length;
    int w = ff.length*260;
    int h = ff.length*110;
    frame.setBounds( 10, 10, 380, 100);
    frame.setLocation(  (i%2)*390+10, 60+110*(i/2)  );

    _desktopPane.add(frame);
  }


  void MnClose_click() {
    System.exit(0);
  }



  static public void main(String[] args) {
    MVC2 frame = new MVC2();
    frame.setVisible(true);
  }

  

}  // MVC2


//   |
//  +--java.util.Observable

// 1. Schritt ableiten von Observable, damit Controller und Modell
class Modell  extends java.util.Observable {
  String sName= "Zappa";

  public String getName() {
    return sName;
  }

  public void setName(String Name) {
    this.sName = Name;
  }

    // Diese Methode wird von einem Viewern aufgerufen
    //
    // 2. Schritt: Im Controller eine Methode für die Viewer zum Updaten schreiben
  public void DataChangedFromViewer(int nr, String s) {
    System.out.println("s in CName: "+s);
    this.setName(s);  // geänderte Daten speichern
    super.setChanged();
      // Sende Nachricht an ALLE Viewer
    super.notifyObservers( new Integer(1) );
  }

} // Modell


// 5. Schritt  im InternalFrame  Implements einbauen und die Methode Update
class JFInternalFrame1 extends JInternalFrame
       implements Observer {
  private String _sFileName;

  private JLabel label1 = new JLabel("Student");
  private JTextField edit = new JTextField("XXXXX");

  private Modell _modell;
  private String _Caption;
  int nr;

  public JFInternalFrame1( String Caption, 
           int nr, Observable DatenModell) {
    _Caption = Caption;   
    setTitle(Caption);
    this.nr=nr;

    _modell = (Modell) DatenModell;  //

  // 5. Schritt  im InternalFrame  Implements einbauen und die Methode Update
  _modell.addObserver(this);  // registrierung

    setGUI();
    setVisible(true);  // neu ab JDK 5.0
  }

  public void setGUI() {
    label1.setFont( new Font("Arial", Font.BOLD,28));
    edit.setText(  _modell.getName()     );
    edit.setFont( new Font("Arial", Font.BOLD,28));

    this.setClosable(true);
    this.setIconifiable(true);
    this.setMaximizable(true);
    this.setResizable(true);
    this.getContentPane().setLayout( new GridLayout(1,2) );


    this.getContentPane().add(label1);
    this.getContentPane().add(edit);

    edit.addActionListener(new java.awt.event.ActionListener() {
        //  Aufgerufen wenn Return-Taste
      public void actionPerformed(ActionEvent e) {
        edit_Change(e);
      }
    });


  }  // setGUI
  

  // 5. Schritt  im InternalFrame  Implements einbauen und die Methode Update
  // aufgerufen vom Controller
  public void update(Observable o, Object arg) {
    System.out.println("Update");
    Integer I = (Integer) arg;
//    if ( ( I.intValue()==nr) || ( I.intValue()==0) ){
      System.out.println("ich bin gemeint: "+_Caption);
      edit.setText( _modell.getName() );
      edit.updateUI();
  //  }
  }

// 6. Schritt  Methode edit_change (Enter) implementieren, Aufruf des Controllers
  void edit_Change(ActionEvent e) {
    System.out.println("geändert");
    _modell.DataChangedFromViewer( nr,edit.getText());
  }



}  // JFInternalFrame1


