//Titel:            Testbeispiel für MDI-Fenster
//Version:          1.1, 16.10.2010
//Copyright:        HS-Harz, FB AI
//Autor:            Dipl.-Inf. Dipl.-Ing. Michael Wilhelm
//Firma:


//Beschreibung:     Komplexes Beispiel für MDI-Steuerung
//                  MDI Beispiel mit Vererbung 
//                  Es existiert eine gemeinsame Basisklasse für die internen Fenster

// Interface für das InternalFrame



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

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

//für MyFileFilter4;
import java.awt.event.*;
import javax.swing.event.*;



import java.awt.Container;


public class MDI05 extends JFrame implements IParent, ActionListener {
  // Container für die Clientfenster
  private JDesktopPane desktopPane = new JDesktopPane();

  private static final String PREFERRED_LOOK_AND_FEEL = "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel";

  private static void installLnF() {
    try {
      String lnfClassname = PREFERRED_LOOK_AND_FEEL;
      if (lnfClassname == null)
        lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();
      UIManager.setLookAndFeel(lnfClassname);
    } catch (Exception e) {
      System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL
          + " on this platform:" + e.getMessage());
    }
  }


    // Menü Variablen
  private JMenuItem mnNew;

  private JMenuItem mnNew1;
  private JMenuItem mnNew2;
  private JMenuItem mnNew3;
  private JMenuItem mnNew4;

  private JMenuItem mnOpen;
  private JMenuItem mnClose;

  private JMenuItem mnCut;
  private JMenuItem mnCopy;
  private JMenuItem mnInsert;

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

  private JButton bnOpen = new JButton("Öffnen");
  private JButton bnNew = new JButton("Neu");


  // Variablen für die Steuerung der einzelnen Fenster
  // wenn ein Fenster mit der Maus aktiviert wurde, ruft es das
  //   mainfenster zur Registrierung auf.
  // Idee: Befehl save muss an das aktuelle Fenster 
  // JInternalFrame
  private MyInternalFrame0 _actualFrame=null;

   // Konstruktor
  public MDI05() {
    this.setSize(600, 400);
    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    setGUI();
    installLnF();
    this.setVisible(true);
  }

  public void mainAktion() {
   CBasis.Message("in main","mainAktion");
  }


  public void setGUI() {
    // mnNew.setmnemonic('N');
    this.getContentPane().setLayout(new BorderLayout() );

    setToolBars();

    this.getContentPane().add(desktopPane, BorderLayout.CENTER);
    
    setMenus();
  }  // jbInit

  private void setToolBars() {
    JToolBar toolBar = new JToolBar();

    toolBar.add(bnOpen);
    bnOpen.addActionListener(this);
    bnOpen.setActionCommand("OpenFile");

    bnNew.addActionListener(this);
    bnNew.setActionCommand("NewFile");
    toolBar.add(bnNew);
    this.getContentPane().add(toolBar, BorderLayout.NORTH);
  } // setToolBars



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

    JMenu mainFile = new JMenu("Datei");;
    mnNew = new JMenuItem("Neu");
    mnOpen = new JMenuItem("Öffnen");
    mnClose = new JMenuItem("Schließen");

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

     // Hauptmenü
    JMenu mnNeu14 = new JMenu("Neu 1-4");

    mnNew1 = new JMenuItem("Neu1");
    mnNew2 = new JMenuItem("Neu2");
    mnNew3 = new JMenuItem("Neu3");
    mnNew4 = new JMenuItem("Neu4");

    mnNew1.addActionListener(this);
    mnNew1.setActionCommand("NewFile1");
    mnNew2.addActionListener(this);
    mnNew2.setActionCommand("NewFile2");
    mnNew3.addActionListener(this);
    mnNew3.setActionCommand("NewFile3");
    mnNew4.addActionListener(this);
    mnNew4.setActionCommand("NewFile4");

    mnNeu14.add(mnNew1);
    mnNeu14.add(mnNew2);
    mnNeu14.add(mnNew3);
    mnNeu14.add(mnNew4);

    mainFile.add(mnNeu14);


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

    // --------------------------
    mnClose.addActionListener(this);
    mnClose.setActionCommand("Close");
    mainFile.add(mnClose);

    menuBar1.add(mainFile);

    // EDIT
    JMenu mainEdit= new JMenu("Bearbeiten");

    mnCut = new JMenuItem("Ausschneiden");
    mnCopy = new JMenuItem("Kopieren");
    mnInsert = new JMenuItem("Einfügen");

    mnCut.addActionListener(this);
    mnCut.setActionCommand("Cut");
    mnCopy.addActionListener(this);
    mnCut.setActionCommand("Copy");
    mnInsert.addActionListener(this);
    mnInsert.setActionCommand("Insert");

    mainEdit.add(mnCut);
    mainEdit.add(mnCopy);
    mainEdit.add(mnInsert);
    menuBar1.add(mainEdit);

    // ----------------
    // Windows
    JMenu mainWindows = new JMenu("Fenster");     // HauptMenü
    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));

      // Event definieren
    mnPrevWindows.addActionListener(this);
    mnNextWindows.addActionListener(this);
    mnCascade.addActionListener(this);
    mnTile.addActionListener(this);
    mnTileVertical.addActionListener(this);
    mnTileHorizontal.addActionListener(this);

    mnPrevWindows.setActionCommand("PrevWindows");
    mnNextWindows.setActionCommand("NextWindows");
    mnCascade.setActionCommand("Cascade");
    mnTile.setActionCommand("Tile");
    mnTileVertical.setActionCommand("TileVertical");
    mnTileHorizontal.setActionCommand("TileHorizontal");
      // 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);

    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


   // Methode fügt einen Frame ins DesktopPane
   // die Variablen width und height dienen der Positionierung
   // mit ff.length wird die Anzahl der schon existierenden Frames bestimmt
  void insertFrame(JInternalFrame frame) {
    int width, height; // Variablen für Clientfenster
    int i;
    width = desktopPane.getWidth();
    height = desktopPane.getHeight();
     // Array for all internal frames
    JInternalFrame[] ff = desktopPane.getAllFrames();
    i = ff.length*20;
        // nur Test
    frame.setTitle( "Frame "+Integer.toString(ff.length+1) );

       // zwei Varianten
    frame.setBounds( i, i, width-i-20, height-i-20);
    // frame.setBounds( i, i, 450, 300);
    // desktopPane.add(frame);
    desktopPane.add(frame);
    desktopPane.moveToFront(frame);
  }  // insertFrame



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

       if (cmd.equals("NewFile") ) {
            MyInternalFrame frame = new MyInternalFrame(null, desktopPane.getAllFrames().length+1);
            int pos = desktopPane.getAllFrames().length+1;
            frame.setBounds(pos*10, pos*10, 450, 300);
            desktopPane.add(frame);
            desktopPane.moveToFront(frame);
        }

       if (cmd.equals("NewFile1") )    mnNew1_click();
       if (cmd.equals("NewFile2") )    mnNew2_click();
       if (cmd.equals("NewFile3") )    mnNew3_click();
       if (cmd.equals("NewFile4") )    mnNew4_click();


       if (cmd.equals("OpenFile") ) {
          mnOpen_click();
       }
       if (cmd.equals("SaveFile") ) {
         mnSave_click();
       }
       if (cmd.equals("SaveAsFile") ) {
         mnSaveAs_click();
       }
       if (cmd.equals("Close") ) {
         mnClose_click();
       }
       if (cmd.equals("Cut") ) {
         mnCut_click();
       }
       if (cmd.equals("Copy") ) {
         mnCopy_click();
       }
       if (cmd.equals("Insert") ) {
          mnInsert_click();
       }


    
      
       if (cmd.equals("PrevWindows") ) {
          WindowLayout.mnPrevWindows(desktopPane);
       }
       if (cmd.equals("NextWindows") ) {
         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



    // erzeugt ein neues Fenster Frame1
  void mnNew1_click() {
    MyInternalFrame1 frame = new MyInternalFrame1(this, null);
    insertFrame(frame);
  }


  void mnNew2_click() {
    MyInternalFrame2 frame = new MyInternalFrame2(this, null);
    insertFrame(frame);
  }

  void mnNew3_click() {
    MyInternalFrame3 frame = new MyInternalFrame3(this, null);
    insertFrame(frame);
  }

    // erzeugt ein neues Fenster Frame4   DEFAULT-Einstellung
  void mnNew_click() {
    MyInternalFrame4 frame = new MyInternalFrame4(this, null);
    insertFrame(frame);
  }

  void mnNew4_click() {
    MyInternalFrame4 frame = new MyInternalFrame4(this, null);
    insertFrame(frame);
  }


    // öffnet eine Datei, DEFAULT-Fenster Frame4
    // eventuell auch die Extension abprüfen
  void mnOpen_click() {
   JFileChooser jFileChooser1 = new JFileChooser();
   String sFileName;

   MyFileFilter javaFilter, txtFilter;

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

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

    if (JFileChooser.APPROVE_OPTION == jFileChooser1.showOpenDialog(this)) {
      // Rufen Sie openFile auf, um Text aus einer Datei in die TextArea zu laden
      sFileName = jFileChooser1.getSelectedFile().getPath();
      MyInternalFrame4 frame = new MyInternalFrame4( this, sFileName );
      insertFrame(frame);
    }
  }  // mnOpen


   // mehrere Dateien können selektiert werden
  void mnOpen2_click() {
   JFileChooser jFileChooser1;
   String sFileName;
   File [] files;

   // int i = jFileChooser1.showDialog(this, "Auswahl");
   jFileChooser1 = new JFileChooser();
   jFileChooser1.setMultiSelectionEnabled(true);
   jFileChooser1.setCurrentDirectory(  new File(  (String) System.getProperties().get("user.dir")  )   );

    if (JFileChooser.APPROVE_OPTION == jFileChooser1.showOpenDialog(this)) {
      // Rufen Sie openFile auf, um Text aus einer Datei in die TextArea zu laden
      files = jFileChooser1.getSelectedFiles();
      int k;
      k = files.length;
      for (int i=0; i<files.length; i++) {
        sFileName = files[i].getPath();
        MyInternalFrame4 frame = new MyInternalFrame4( this, sFileName );
        insertFrame(frame);
      }
    }
  }  // mnOpen

  private void mnSave_click() {
  }

  private void mnSaveAs_click() {
  }


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


   // -----------------  EDIT Menü
  void mnCut_click() {
    System.out.println("Menüeintrag Cut");
    JInternalFrame[] ff = desktopPane.getAllFrames();
    if (ff.length>0) {
      MyFrameInterface fTop = (MyFrameInterface) ff[0];
      fTop.cut();
   }
  }

  void mnCopy_click() {
    System.out.println("Menüeintrag Copy");
  }
  void mnInsert_click() {
    System.out.println("Menüeintrag Insert");

  }



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

}

// --------------------------------
// "Basisklasse" für die Vererbung der unterschedlichen Internalframe

interface MyFrameInterface {
  public void cut();  // Aktion

  public String getCaption();  // isNoname, wenn "" oder null

}

interface IParent {
  public void mainAktion();  // Aktion
}


// --------------------------------
// Basisklasse für die Vererbung

abstract class MyInternalFrame0 extends JInternalFrame implements MyFrameInterface {
  protected String _sFileName;
  protected String _Caption;
  protected IParent _main;


  private static final String PREFERRED_LOOK_AND_FEEL = "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel";

  private static void installLnF() {
    try {
      String lnfClassname = PREFERRED_LOOK_AND_FEEL;
      if (lnfClassname == null)
        lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();
      UIManager.setLookAndFeel(lnfClassname);
    } catch (Exception e) {
      System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL
          + " on this platform:" + e.getMessage());
    }
  }


  public MyInternalFrame0(IParent main, String sFileName) {
    _sFileName = sFileName;
    _main = main;
    if (sFileName==null)
      _Caption = "noname";
    else
      _Caption = sFileName;
    setGUI();
    setVisible(true);  // nur einmal
    installLnF();
  }

  // wird aufgerufen wird Clientfenster, abgeleitet
  private void setGUI() {
    setClosable(true);
    setIconifiable(true);
    setMaximizable(true);
    setResizable(true);
    setTitle( getCaption() );
  }



    // wird aufgerufen vom mainFenster
  public String getCaption() {
   return _Caption;
  }

  abstract void createGUI();
  abstract void initGUIFromData();

}  // Internel Frame0




class MyInternalFrame1 extends MyInternalFrame0 {
  BorderLayout borderLayout1 = new BorderLayout();
  JTextArea jTextArea1 = new JTextArea();

  public MyInternalFrame1(IParent main, String sFileName) {
    super(main, "FrameTyp1");   // sFileName);
    // super.setGUI(this);  automatisch
    setGUI();
    this.setTitle( getCaption() );
  }

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

    JToolBar toolBar = new JToolBar();
    JButton BnOpen = new JButton("Open");
    JButton BnNew = new JButton("New");
    toolBar.add(BnOpen);
    toolBar.add(BnNew);


    this.getContentPane().add(toolBar, BorderLayout.NORTH);

     this.getContentPane().add(jTextArea1, BorderLayout.CENTER);

     createGUI();
    this.setClosable(true);
    this.setIconifiable(true);

  }  // setGUI


  void createGUI() {
    jTextArea1.setText("Editor" +"\n"+
             "Quelltext:"+'\n'+
             "JToolBar toolBar = new JToolBar();" + '\n'+
             "JButton BnOpen = new JButton('Open');" + '\n'+
             "JButton BnNew = new JButton('New');" + '\n'+
             "toolBar.add(BnOpen);"+'\n'+
             "toolBar.add(BnNew);"+'\n'+
             ""
    );
  }

  void initGUIFromData() {
  }

  public void cut() {
    CBasis.Message("Save","MyInternalFrame1");
  }

  // isNoname, wenn "" oder null
 

}  // MyInternalFrame1



class MyInternalFrame2 extends MyInternalFrame0 implements Runnable {
  BorderLayout borderLayout1 = new BorderLayout();
  JTextArea jTextArea1 = new JTextArea();
  JLabel jLabel1 = new JLabel();

  public MyInternalFrame2(IParent main, String sFileName) {
    super(main, "FrameTyp2");   // sFileName);
    // super.setGUI(this);  automatisch
    setGUI();
    this.setTitle( getCaption() );
  }

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

    JToolBar toolBar = new JToolBar();
    JButton BnCalc = new JButton("Calc");
    JButton BnNew = new JButton("New");
    toolBar.add(BnCalc);
    toolBar.add(BnNew);


    BnCalc.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        BnCalc_actionPerformed(e);  // !!!!!!
      }
    });

    this.getContentPane().add(toolBar, BorderLayout.NORTH);
    jLabel1.setText("jLabel1");
    jLabel1.setFont(new java.awt.Font("Dialog", 0, 30));
    this.getContentPane().add(jLabel1, BorderLayout.CENTER);
  }


  public static void delay(long time) {
    long t1;
    t1 =  System.currentTimeMillis()+time;
    while ( System.currentTimeMillis() < t1) {
    }
  }  // delay


  // Thread-Methode
  public void run() {
    int s=0;
    this.setTitle("Run");
    for (int i=0; i<1000; i++) {
      s=s+i;
      jLabel1.setText( Integer.toString(s) );
      jLabel1.paintImmediately(0,0, jLabel1.getWidth(), jLabel1.getHeight());

      try {
          Thread.sleep(10); // delay(100);
      }
      catch (InterruptedException e) {
      }
    }
    this.setTitle("Ready Run");
  }  // Run


  void BnCalc_actionPerformed(ActionEvent e) {
    Thread t;
    t = new Thread(this);
    t.start();
  }


  void createGUI() {
  }

  void initGUIFromData() {
  }

  public void cut() {
    CBasis.Message("Cut","MyInternalFrame2");
  }

}  // InternalFrame2


class MyInternalFrame3 extends MyInternalFrame0 {
  JTree jTree1;

  public MyInternalFrame3(IParent main, String sFileName) {
    super(main, "FrameTyp3");   // sFileName);
    // super.setGUI(this);  automatisch
    this.getContentPane().setLayout(new BorderLayout());
    setGUI();
  }

  public void setGUI() {
    createGUI();
    initGUIFromData();
  }


  void createGUI() {
    jTree1 = new JTree();
    this.getContentPane().add(jTree1, BorderLayout.CENTER);
  }

  void initGUIFromData() {
  }

  public void cut() {
    CBasis.Message("Cut","MyInternalFrame3");
  }

}  // Internalframe3


class MyInternalFrame4 extends MyInternalFrame0 {

  public MyInternalFrame4(IParent main, String sFileName) {
    super(main, "FrameTyp4");   // sFileName);
    // super.setGUI(this);  automatisch
    this.getContentPane().setLayout(new BorderLayout() );
    setGUI();
  }

  public void setGUI() {
    createGUI();
  }


  void createGUI() {
    JSplitPane jSplitPane1 = new JSplitPane();
    JTree jTree1 = new JTree();
    JTextArea jTextArea1 = new JTextArea();
    this.getContentPane().add(jSplitPane1, BorderLayout.CENTER);
    jSplitPane1.add(jTree1, JSplitPane.LEFT);
    jSplitPane1.add(jTextArea1, JSplitPane.RIGHT);
    jTextArea1.setText("2. Editor" +"\n"+
             "Quelltext:"+'\n'+
             "JToolBar toolBar = new JToolBar();" + '\n'+
             "JButton BnOpen = new JButton('Open');" + '\n'+
             "JButton BnNew = new JButton('New');" + '\n'+
             "toolBar.add(BnOpen);"+'\n'+
             "toolBar.add(BnNew);"+'\n'+
             ""
    );
  }

  void initGUIFromData() {
  }

  public void cut() {
    CBasis.Message("Cut","MyInternalFrame4");
  }


}  // Internalframe4



class MyFileFilter extends FileFilter {

    private static String TYPE_UNKNOWN = "Type Unknown";
    private static String HIDDEN_FILE = "Hidden File";

    private Hashtable filters = null;
    private String description = null;
    private String fullDescription = null;
    private boolean useExtensionsInDescription = true;

    /**
     * Creates a file filter. If no filters are added, then all
     * files are accepted.
     *
     * @see #addExtension
     */
    public MyFileFilter() {
     	this((String) null, (String) null);
    }

    /**
     * Creates a file filter that accepts files with the given extension.
     * Example: new ExampleFileFilter("jpg");
     *
     * @see #addExtension
     */
    public MyFileFilter(String extension) {
     	this(extension,null);
    }

    /**
     * Creates a file filter that accepts the given file type.
     * Example: new ExampleFileFilter("jpg", "JPEG Image Images");
     *
     * Note that the "." before the extension is not needed. If
     * provided, it will be ignored.
     *
     * @see #addExtension
     */
    public MyFileFilter(String extension, String description) {
     	this(new String[] {extension}, description);
    }

    /**
     * Creates a file filter from the given string array.
     * Example: new ExampleFileFilter(String {"gif", "jpg"});
     *
     * Note that the "." before the extension is not needed adn
     * will be ignored.
     *
     * @see #addExtension
     */
    public MyFileFilter(String[] filters) {
     	this(filters, null);
    }

    /**
     * Creates a file filter from the given string array and description.
     * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images");
     *
     * Note that the "." before the extension is not needed and will be ignored.
     *
     * @see #addExtension
     */
    public MyFileFilter(String[] filters, String description) {
      this.filters = new Hashtable(filters.length);
      for (int i = 0; i < filters.length; i++) {
          // add filters one by one
          addExtension(filters[i]);
      }
      setDescription(description);
    }

    /**
     * Return true if this file should be shown in the directory pane,
     * false if it shouldn't.
     *
     * Files that begin with "." are ignored.
     *
     * @see #getExtension
     * @see FileFilter#accepts
     */
    public boolean accept(File f) {
      if(f != null) {
          if(f.isDirectory()) {
        return true;
          }
          String extension = getExtension(f);
          if(extension != null && filters.get(getExtension(f)) != null) {
        return true;
          };
      }
      return false;
    }

    /**
     * Return the extension portion of the file's name .
     *
     * @see #getExtension
     * @see FileFilter#accept
     */
     public String getExtension(File f) {
        if(f != null) {
            String filename = f.getName();
            int i = filename.lastIndexOf('.');
            if(i>0 && i<filename.length()-1) {
          return filename.substring(i+1).toLowerCase();
            };
        }
        return null;
    }

    /**
     * Adds a filetype "dot" extension to filter against.
     *
     * For example: the following code will create a filter that filters
     * out all files except those that end in ".jpg" and ".tif":
     *
     *   ExampleFileFilter filter = new ExampleFileFilter();
     *   filter.addExtension("jpg");
     *   filter.addExtension("tif");
     *
     * Note that the "." before the extension is not needed and will be ignored.
     */
    public void addExtension(String extension) {
      if(filters == null) {
          filters = new Hashtable(5);
      }
      filters.put(extension.toLowerCase(), this);
      fullDescription = null;
    }


    /**
     * Returns the human readable description of this filter. For
     * example: "JPEG and GIF Image Files (*.jpg, *.gif)"
     *
     * @see setDescription
     * @see setExtensionListInDescription
     * @see isExtensionListInDescription
     * @see FileFilter#getDescription
     */
    public String getDescription() {
      if(fullDescription == null) {
          if(description == null || isExtensionListInDescription()) {
        if(description != null) {
            fullDescription = description;
        }
        fullDescription += " (";
        // build the description from the extension list
        Enumeration extensions = filters.keys();
        if(extensions != null) {
            fullDescription += "." + (String) extensions.nextElement();
            while (extensions.hasMoreElements()) {
          fullDescription += ", " + (String) extensions.nextElement();
            }
        }
        fullDescription += ")";
          } else {
        fullDescription = description;
          }
      }
      return fullDescription;
    }

    /**
     * Sets the human readable description of this filter. For
     * example: filter.setDescription("Gif and JPG Images");
     *
     * @see setDescription
     * @see setExtensionListInDescription
     * @see isExtensionListInDescription
     */
    public void setDescription(String description) {
   	  this.description = description;
    	fullDescription = null;
    }

    /**
     * Determines whether the extension list (.jpg, .gif, etc) should
     * show up in the human readable description.
     *
     * Only relevent if a description was provided in the constructor
     * or using setDescription();
     *
     * @see getDescription
     * @see setDescription
     * @see isExtensionListInDescription
     */
    public void setExtensionListInDescription(boolean b) {
      useExtensionsInDescription = b;
      fullDescription = null;
    }

    /**
     * Returns whether the extension list (.jpg, .gif, etc) should
     * show up in the human readable description.
     *
     * Only relevent if a description was provided in the constructor
     * or using setDescription();
     *
     * @see getDescription
     * @see setDescription
     * @see setExtensionListInDescription
     */
    public boolean isExtensionListInDescription() {
     	return useExtensionsInDescription;
    }
}  // MyFilter


class CBasis {

 public static void Message( String sTitle, String sMessage) {
    JOptionPane.showConfirmDialog(null,sMessage,sTitle,
      JOptionPane.DEFAULT_OPTION,
      JOptionPane.INFORMATION_MESSAGE);  // Symbol
    /*  Optionen der Schalter:
         DEFAULT_OPTION    Ok
         YES_NO_OPTION
         YES_NO_CANCEL_OPTION
         OK_CANCEL_OPTION
     */
     /*  Symbole:
      ERROR_MESSAGE
      INFORMATION_MESSAGE
      WARNING_MESSAGE
      QUESTION_MESSAGE
      PLAIN_MESSAGE
     */

  } // Message
}


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();
              }
          }
      }
    
  }
  
  
}
