//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


// Beispiel für das Observer Design Pattern
// Mit der Eingabetaste wird der Inhalt aktualisiert

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 MVC1 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;


  // 4. Schritt  die Modell Variable im JFrame deklarieren
  private CName _name;   // Modell
  private CController _controller;

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

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

    setMenus();
    // Pattern_MVC
    // 5. Schritt  Modell Variable erzeugen
    _name = new CName("Abba");
    //_name.setName("Paul");
    // 6. Schritt  Controller Variable erzeugen
    _controller = new CController();
  }



    // 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++;

    // 9. Schritt  Viewer in der Methgode "New_click" erzeugen
    myInternalFrame frame = new myInternalFrame(
    Integer.toString(_Fensternummer), n%3,
      _name, _controller);

    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, new Integer(1));
  }


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



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

 
}  // MVC1


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

// 2. Schritt Controller ableiten von Observable
class CController extends java.util.Observable {
    // Diese Methode wird von einem Viewern aufgerufen
    
    // 3. Schritt: Im Controller eine Methode für die Viewer zum Updaten schreiben
  public void DataChangedFromViewer(int nr) {
    System.out.println("Controller Changed");
    super.setChanged();
      // Sende Nachricht an ALLE Viewer
    // super.notifyObservers( );
    super.notifyObservers( new Integer(nr) );// alternative, wenn starke Aenderungen
  }

} // CController


// 1. Schritt Datenmodell erstellen
class CName  {
  String sName= "Zappa";

  public CName(String name)  {
     sName=name;
  }
  
  public String getName() {
    return sName;
  }

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

} // CName



// 7. Schritt  im ÍnternalFrame  Implements einbauen und die Methode Update
class myInternalFrame extends JInternalFrame  implements Observer {
  private String _sFileName;

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

  private CName _name;
  private CController _controller;
  private String _Caption;
  int _eigeneFensternr;

  public myInternalFrame(
       String Caption, int nr,
       CName name, CController controller) {
    _Caption = Caption;
    setTitle(Caption);
    _eigeneFensternr=nr;

    _name = name;
    _controller = controller;
    // 7. Schritt Registrieren beiom Controller im Konstruktor des JInternalframes
    _controller.addObserver(this);  // registrierung

    setGUI();
    setVisible(true);
  }

  public void setGUI() {
    label1.setFont( new Font("Arial", Font.BOLD,28));
    edit.setText(  _name.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


   // 7. Schritt  im ÍnternalFrame  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()!=_eigeneFensternr)   || ( I.intValue()==0) ){
      System.out.println("ich bin gemeint: "+_Caption);
      edit.setText( _name.getName() );
      edit.updateUI();
    }
  }

// 8. Schritt  Methode edit_change (Enter) implementieren, Aufruf des Controllers
  void edit_Change(ActionEvent e) {
    System.out.println("geändert");
    _name.setName( edit.getText() );
    //. .DataChangedFromViewer( nr, new String(  ) );
    _controller.DataChangedFromViewer(_eigeneFensternr);
    //.DataChangedFromViewer( nr, new String(edit.getText()  ) );
  }



}  // myInternalFrame


