//Titel:            Testbeispiel für MDI-Fenster

// Beispiel eines MDI-Fenster

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

// Packages für Opendialog
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.filechooser.*;
import java.util.Hashtable;
import java.util.Enumeration;

// Packages für Filter
import javax.swing.filechooser.*;
import java.io.File;
import java.util.Hashtable;
import java.util.Enumeration;




public class MDI03 extends JFrame   implements ActionListener  {

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

    // Variablen für die Menüs
  private JMenuBar menuBar1;   // MenüContainer
  private JMenu mainFile;      // Hauptmenü
  private JMenuItem mnNew;     // Menüeintrag
  private JMenuItem mnOpen;   
  private JMenuItem mnSaveAs;
  private JMenuItem mnClose;   

  private JMenu mainWindows;        
  private JMenuItem mnPrevWindows; 
  private JMenuItem mnNextWindows; 
  private JMenuItem mnTile;        
  private JMenuItem mnTileVertical;        
  private JMenuItem mnTileHorizontal;        
  private JMenuItem mnCascade; 


  String sFileName="";


   // Konstruktor
  public MDI03() {
    this.setSize( 600, 400);
    setTitle( "MDI: 2. Beispiel");
    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    setGUI();
  }

  public void setGUI() {
      // BorderLayout setzen
    this.getContentPane().setLayout( new BorderLayout() );

      // Variable DesktopPane einfügen
      // in ihr werden alle Clientfenster eingefügt
    JScrollPane sc = new JScrollPane (desktopPane);
    this.getContentPane().add(sc, BorderLayout.CENTER);
    setMenus();
  }



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

      // DATEI
    mainFile = new JMenu("Datei");
    mnNew = new JMenuItem("Neu");
    mnOpen = new JMenuItem("Öffnen");
    mnSaveAs = new JMenuItem("Speichern unter");
    mnClose = new JMenuItem("Schließen");

    mainFile.add(mnNew);
    mainFile.add(mnOpen);
    mainFile.addSeparator();
    mainFile.add(mnSaveAs);
    mainFile.add(mnClose);


   mnNew.addActionListener(this);
   mnNew.setActionCommand("NewFile");
   mnNew.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));

    mnOpen.addActionListener(this);
    mnOpen.setActionCommand("OpenFile");
    mnOpen.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));

    mnSaveAs.addActionListener(this);
    mnSaveAs.setActionCommand("SaveAsFile");

    mnClose.addActionListener(this);
    mnClose.setActionCommand("Close");

    mainFile.add(mnClose);

      // Hauptmenü FILE in den MenüBar einfügen
    menuBar1.add(mainFile);

    // ----------------
    // Menü Windows
    mainWindows = new JMenu("Fenster");
    mnPrevWindows = new JMenuItem("Vorheriges Fenster");
    mnNextWindows = new JMenuItem("Nächstes Fenster");
    mnCascade = new JMenuItem("Kaskade");
    mnCascade.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_F6, 0));

    mnTile = new JMenuItem("Aufteilen");
    mnTile.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_F7, 0));
    mnTileVertical = new JMenuItem("Aufteilen Vertikal");
    mnTileVertical.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_F8, 0));

    mnTileHorizontal = new JMenuItem("Aufteilen Horizontal");
    mnTileHorizontal.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_F9, 0));

      // MenüEinträge definieren
    mainWindows.add(mnPrevWindows);
    mainWindows.add(mnNextWindows);
    mainWindows.addSeparator();
    mainWindows.add(mnCascade);
    mainWindows.add(mnTile);
    mainWindows.add(mnTileVertical);
    mainWindows.add(mnTileHorizontal);
    menuBar1.add(mainWindows);

      // Event definieren
    mnPrevWindows.addActionListener(this);
    mnPrevWindows.setActionCommand("WinPrev");

    mnNextWindows.addActionListener(this);
    mnNextWindows.setActionCommand("WinNext");

    mnCascade.addActionListener(this);
    mnCascade.setActionCommand("Cascade");

    mnTile.addActionListener(this);
    mnTile.setActionCommand("Tile");

    mnTileVertical.addActionListener(this);
    mnTileVertical.setActionCommand("TileVertical");
    mnTileHorizontal.addActionListener(this);
    mnTileHorizontal.setActionCommand("TileHorizontal");

    this.setJMenuBar(menuBar1);

    for (int i = 0; i < menuBar1.getComponentCount(); i++) {
      JMenu main = (JMenu) menuBar1.getComponent(i);
      main.setFont(new Font("Arial", Font.BOLD, 18));
      for (int j = 0; j < main.getItemCount(); j++) {
        Component c = main.getItem(j);
        if (c instanceof JMenuItem) {
          JMenuItem mn = (JMenuItem) c;
          mn.setFont(new Font("Arial", Font.BOLD, 18));
        }
      }
    }

  } // setMenus


  public void actionPerformed(ActionEvent e) {
       String cmd = e.getActionCommand();

       if (cmd.equals("NewFile") ) {
           mnNew_click();
        }
       if (cmd.equals("OpenFile") ) {
          mnOpen_click();
       }

       if (cmd.equals("SaveAsFile") ) {
          mnSaveAs_click();
       }


       if (cmd.equals("WinPrev") ) {
          WindowLayout.mnPrevWindows(desktopPane);
       }
       if (cmd.equals("WinNext") ) {
          WindowLayout.mnNextWindows(desktopPane);
       }

       if (cmd.equals("Cascade") ) {
          WindowLayout.mnCascade(desktopPane);
       }
       if (cmd.equals("Tile") ) {
          WindowLayout.mnTile(desktopPane);
       }
       if (cmd.equals("TileVertical") ) {
          WindowLayout.mnTileVertical(desktopPane);    
       }
       if (cmd.equals("TileHorizontal") ) {
          WindowLayout.mnTileHorizontal(desktopPane);
       }

    }  // actionPerformed

    public void mnNew_click() {
            MyInternalFrame frame = new MyInternalFrame(null, desktopPane.getAllFrames().length+1);
           addClientFrame(frame);
   }
   

private void addClientFrame(JInternalFrame frame) {
     final int w = 350;
     final int h = 200;
     int pos = desktopPane.getAllFrames().length+1;
     frame.setBounds(
             (pos*50 % (desktopPane.getWidth()-w) ),
             (pos*50 % (desktopPane.getHeight()-h) ),
             w, h);
     desktopPane.add(frame);
     desktopPane.moveToFront(frame);
  }

     // Beispiel zum Öffnen EINER Datei
  void mnOpen_click() {
   JFileChooser jFileChooser1 = new JFileChooser();
   String sFileName;

     // Filter definieren
   MyFileFilter javaFilter, txtFilter;

       // Eine Maske
	javaFilter = new MyFileFilter( "java", "Java-Texte");
       // Zwei Masken
	txtFilter = new MyFileFilter(  new String[] {"dat", "txt"}, "Texte");

     // setzen der Optionen
   jFileChooser1.setMultiSelectionEnabled(false);
   jFileChooser1.setCurrentDirectory( 
    new File(  (String) System.getProperties().get("user.dir")  )   );
   jFileChooser1.addChoosableFileFilter(javaFilter);
   jFileChooser1.addChoosableFileFilter( txtFilter);

      // Aufruf des Dialogfensters
    if (JFileChooser.APPROVE_OPTION == jFileChooser1.showOpenDialog(this)) {
        // holen des Dateinamens
      sFileName = jFileChooser1.getSelectedFile().getPath();
        // Erzeugen des Clientframes
      MyInternalFrame frame = new MyInternalFrame( sFileName, desktopPane.getAllFrames().length+1 );
       addClientFrame(frame);
    }
  }  // mnOpen


     // Beispiel zum Oeffnen MEHRERER Datei
  void mnOpen2_click() {
   JFileChooser jFileChooser1;
   String sFileName;
   File [] files;  // Array für

   jFileChooser1 = new JFileChooser();
   jFileChooser1.setMultiSelectionEnabled(true);

   jFileChooser1.setCurrentDirectory(  new File(  (String) System.getProperties().get("user.dir")  )   );

     // Okay gedrückt ?
    if (JFileChooser.APPROVE_OPTION == jFileChooser1.showOpenDialog(this)) {
      files = jFileChooser1.getSelectedFiles();

      int k;
      k = files.length;
      for (int i=0; i<files.length; i++) {
         sFileName = files[i].getPath();
         MyInternalFrame frame = new MyInternalFrame( sFileName, desktopPane.getAllFrames().length+1 );
         addClientFrame(frame);
      }
    }
  }  // mnOpen

 
  void mnSaveAs_click() {
   JFileChooser jFileChooser1 = new JFileChooser();
   String sFileName;

   MyFileFilter dbsFilter;

   dbsFilter = new MyFileFilter( new String[] {"std"}, "Studenten-Datenbank");

   jFileChooser1.setCurrentDirectory(  new File(  (String) System.getProperties().get("user.dir")  )   );
   jFileChooser1.addChoosableFileFilter(dbsFilter);

	// Ok-Schalter gedrückt ?
    if (JFileChooser.APPROVE_OPTION == jFileChooser1.showSaveDialog(this)) {
      sFileName = jFileChooser1.getSelectedFile().getPath();
      SaveToFile();
    }
  }

  public void SaveToFile() {
    // suche aktive Fenster
    // speichert eine Datei
   MyInternalFrame frame;
   JInternalFrame[] ff;  // Array of all internal Clientwindow
   ff = desktopPane.getAllFrames();
   if (ff.length>0) {
     frame = (MyInternalFrame) ff[0];
     System.out.println( frame.getTitle() );
   }
  }  // SaveToFile


   // wird aufgerufen beim Schließen des Hauptfensters
  void mnClose_click() {
     this.dispose(); //     System.exit(0);
  }



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





// Clientfenster
class MyInternalFrame extends JInternalFrame {
  private String _sFileName;
  private String _Caption;
  private int _nr;


  public MyInternalFrame(String sFileName, int nr) {
    _sFileName = sFileName;
    if (sFileName==null)
      _Caption = "noname";
    else
      _Caption = sFileName;
    _nr = nr;
    setGUI();
    setVisible(true);
  }

  public void setGUI() {
    this.setClosable(true);
    this.setIconifiable(true);
    this.setMaximizable(true);
    this.setResizable(true);
    this.getContentPane().setLayout( new BorderLayout() );
    this.setTitle(_nr+": "+_Caption);
  }

}  // MyInternalFrame




class WindowLayout {

  
    public static void mnPrevWindows(JDesktopPane desktopPane) {     
      JInternalFrame[] frames = desktopPane.getAllFrames();
      if(frames.length > 1)
     { 
         desktopPane.selectFrame(false);
     }
   }
	
   public static void mnNextWindows(JDesktopPane desktopPane) {
       JInternalFrame[] frames = desktopPane.getAllFrames();
        if(frames.length > 1)
       {
          desktopPane.selectFrame(true);
       }
   }


 private static  void setCascadeFrame(JDesktopPane desktopPane) {
   final int w = 250;
   final int h = 150;
   JInternalFrame frame;     // the actual Clientwindow
   JInternalFrame[] ff;  // Array of all internal Clientwindow
   ff = desktopPane.getAllFrames();
   for (int pos = 0; pos<ff.length; pos++) {
      frame = (JInternalFrame)ff[pos];  // typecasting
      frame.setBounds(
     (pos*50 % (desktopPane.getWidth()-w) ),
     (pos*50 % (desktopPane.getHeight()-h) ), 
         w, h);
   } // for
  }  // setCascadeFrame()


   // -----------------
  public static void mnCascade(JDesktopPane desktopPane) {
      int i, j, p, Abstand, w, h, n;
      JInternalFrame f;     // the actual Clientwindow
      JInternalFrame[] ff;  // Array of all internal Clientwindow
      ff = desktopPane.getAllFrames();
      n = ff.length;  // Count of Frames
      // calc the distance of the frames, depends on the count of the frames
      if (n > 0) {
           if (n<=3)
             Abstand = 80;
           else {
             if (n>6)
               Abstand = 25;
             else
               Abstand = 40;
           }
           // calc the width and height of each frame
           w = desktopPane.getWidth() - (n-1)*Abstand;
           h = desktopPane.getHeight() - (n-1)*Abstand;
           if ( (w<80) || (h<80) || (n>20) ) {
             setCascadeFrame(desktopPane);
           }
           else {
             if (w<=0) w = 100;
             if (h<=0) h = 50;
             // the top frame has the index 0 !
             // index i is for the position
             // index j ist for the frames, the last is the top-frame !
             for (i = 0, j=n-1; i <n; i++,j--) {
                 f = (JInternalFrame)ff[j];  // typecasting
                 p = i*Abstand;
                 f.setLocation(p, p);        // position
                 f.setSize(w,h);             // width height
             }
           }
      }
  }   // MnCascade_click() {


  public static void mnTile(JDesktopPane desktopPane) {
    System.out.println("Menüeintrag Tile");
      JInternalFrame[] ff;    // Array for all internal frames
      JInternalFrame f; //
      int hoehe, anz, breite, left, top;
      int indexCol, anzCol, anzRow, anzRowUnten, n, i, h, b1, b2;
      boolean bZweiBreiten;

      ff = desktopPane.getAllFrames();
        // Count > 0 ?
      if (ff.length > 0) {
          // Quadratische Aufteilung

            /*
             5:
                 -
                - -
                - -

             11:
                 - -
                - - -
                - - -
                - - -

            */

          n = ff.length;
          if (n < 1) {
              return;
          }
          if (n == 1) {
              f = (JInternalFrame)ff[0];
              try {
                  f.setMaximum(true);
              }
              catch (Exception e1) {
                  e1.printStackTrace();
              }
              return;
          }
          
          anzCol = (int)Math.round(Math.sqrt(n)); // Wurzel aus Anzahl
          // bestimme Anzahl der unteren (vollen) Zeilen
          anzRowUnten = n / anzCol;  // trunc
            // Abfrage nach Rest
          if (n > (anzRowUnten * anzCol)) {
              anzRow = anzRowUnten + 1;
              bZweiBreiten = true;
          }
          else {
              anzRow = anzRowUnten;
              bZweiBreiten = false;
          }
          //  AnzRow zeigt die Anzahl aller Zeilen

          // nun werden zwei Breiten und eine Höhe ausgerechnet
          // 1. Breite  gilt für die vollen Reihen
          // 2. Breite  gilt für oberste  Reihe, falls sie nicht voll ist
          hoehe = desktopPane.getHeight();
          h = desktopPane.getHeight() / anzRow;
          b1 = desktopPane.getWidth() / anzCol; // volle Breite
          if (bZweiBreiten)
             b2 = desktopPane.getWidth() / (n - anzCol * anzRowUnten); // untere Breite
          else
             b2 = b1;

          // Rückwärts
          anz = 0;
          left = 0;
          top = hoehe - h;
          indexCol = 0;
          for (i = ff.length - 1; i >= 0; i--) {
              f = (JInternalFrame)ff[i];
              //f.setSize(100,100);
              try {
                  f.setMaximum(false);
              }
              catch (Exception e2) {
                  e2.printStackTrace();
              }
              anz++;
              indexCol++;
              if (indexCol > anzCol) {
                  // neue Reihe anfangen
                  left = 0;
                  top -= h;
                  indexCol = 1;
              }
              // Position im Fenster setzen
              f.setLocation(left, top);
              // Breite Höhe setzen
              // Check, ob man in der obersten Zeile sich befindet ?
              if (anz > (anzRowUnten * anzCol)) {
                  f.setSize(b2, h); // width height
                  left += b2;
              }
              else {
                  f.setSize(b1, h); // width height
                  left += b1;
              }
          }
      }
  } // MnTile



  public static void mnTileHorizontal(JDesktopPane desktopPane) {
      JInternalFrame[] ff;    // Array for all internal frames
      JInternalFrame f; //
      int hoehe, breite, top;
      int i, n;
      ff = desktopPane.getAllFrames();
        // Count > 0 ?
      if (ff.length > 0) {
          n = ff.length;
          breite = desktopPane.getWidth() ;
          hoehe = desktopPane.getHeight()/ n;
          if (ff.length==1 ) {
              f = (JInternalFrame)ff[0];
              try {
                  f.setMaximum(false);
                  f.setSize(desktopPane.getWidth(), hoehe);
                  f.setLocation(0,0);
                  return;
              }
              catch (Exception e2) {
                  e2.printStackTrace();
              }            
          }
          top=0;
          for (i = ff.length - 1; i >= 0; i--) {
              f = (JInternalFrame)ff[i];
              //f.setSize(100,100);
              try {
                  f.setMaximum(false);
                  f.setSize(breite, hoehe);
                  f.setLocation(0,top);  // x/y
                  top+=hoehe;
              }
              catch (Exception e2) {
                  e2.printStackTrace();
              }
          }
      }
    
  }



  public static void mnTileVertical(JDesktopPane desktopPane) {
      JInternalFrame[] ff;    // Array for all internal frames
      JInternalFrame f; //
      int hoehe, breite, left, top;
      int i, n;
      ff = desktopPane.getAllFrames();
        // Count > 0 ?
      if (ff.length > 0) {
          n = ff.length;
          breite = desktopPane.getWidth() / n;
          hoehe = desktopPane.getHeight();
          if (ff.length==1 ) {
              f = (JInternalFrame)ff[0];
              try {
                  f.setMaximum(false);
                  f.setSize(desktopPane.getWidth(), hoehe);
                  f.setLocation(0,0);
                  return;
              }
              catch (Exception e2) {
                  e2.printStackTrace();
              }            
          }
          left=0;
          for (i = ff.length - 1; i >= 0; i--) {
              f = (JInternalFrame)ff[i];
              //f.setSize(100,100);
              try {
                  f.setMaximum(false);
                  f.setSize(breite, hoehe);
                  f.setLocation(left,0);  // x/y
                  left+=breite;
              }
              catch (Exception e2) {
                  e2.printStackTrace();
              }
          }
      }
    
  }
  
  
}

