//Titel:            Testbeispiel für Look and Feel
//Version:          2,0 07.11.2010
//Copyright:        HS-Harz, FB AI
//Autor:            Dipl.-Inf. Dipl.-Ing. Michael Wilhelm



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


import javax.swing.event.*;

import javax.swing.plaf.metal.*;  // look and Feel

import javax.swing.plaf.synth.*;


public class Look_and_Feel_01 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 MnClose;

  private JMenu MainLook_Feel;
  private JMenuItem MnLook_Feel_Windows;
  private JMenuItem MnLook_Feel_Motif;
  private JMenuItem MnLook_Feel_Metal;
  private JMenuItem MnLook_Feel_Macintosh;
  private JMenuItem MnLook_Feel_Nimbus;
  private JMenuItem MnLook_Feel_Ocean;


  private JMenu MainWindows;
  private JMenuItem MnPrevWindows;
  private JMenuItem MnNextWindows;
  private JMenuItem MnTile;
  private JMenuItem MnCascade;


   // Konstruktor
  public Look_and_Feel_01() {
    setGUI();
    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    this.setSize( 800, 600);
  }

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

    setToolBars();

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

    setMenus();
  }  // setGUI


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


    JButton BnNew = new JButton("Neu");
    BnNew.setFont( new Font("Arial", Font.BOLD,18)  );

    BnNew.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        MnNew_click();  // Aufruf der gemeinsamen Methode
      }
    });
    toolBar.add(BnNew);
    this.getContentPane().add(toolBar, BorderLayout.NORTH);
  } // setToolBars



    // 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_actionPerformed(e);
      }
    });
    MainFile.add(MnClose);


    menuBar1.add(MainFile);

    // --------------------------------------
    
    MainLook_Feel = new JMenu("Look & Feel");
    //MainLook_Feel.setFont( new Font("Arial", Font.BOLD,18)  );

    MnLook_Feel_Windows = new JMenuItem("Windows");
    //MnLook_Feel_Windows.setFont( new Font("Arial", Font.BOLD,18)  );

    MainLook_Feel.add(MnLook_Feel_Windows);
    //MainLook_Feel.setFont( new Font("Arial", Font.BOLD,18)  );

    MnLook_Feel_Motif = new JMenuItem("Motif");
    //MnLook_Feel_Motif.setFont( new Font("Arial", Font.BOLD,18)  );
    MainLook_Feel.add(MnLook_Feel_Motif);

    MnLook_Feel_Metal = new JMenuItem("Metal");
    MainLook_Feel.add(MnLook_Feel_Metal);
    //MnLook_Feel_Metal.setFont( new Font("Arial", Font.BOLD,18)  );

    MnLook_Feel_Macintosh = new JMenuItem("Macintosh");
    //MnLook_Feel_Macintosh.setFont( new Font("Arial", Font.BOLD,18)  );
    MainLook_Feel.add(MnLook_Feel_Macintosh);

    MnLook_Feel_Nimbus = new JMenuItem("Nimbus");
    //MnLook_Feel_Macintosh.setFont( new Font("Arial", Font.BOLD,18)  );
    MainLook_Feel.add(MnLook_Feel_Nimbus);

    MnLook_Feel_Ocean = new JMenuItem("Ocean");
    //MnLook_Feel_Macintosh.setFont( new Font("Arial", Font.BOLD,18)  );
    MainLook_Feel.add(MnLook_Feel_Ocean);



    menuBar1.add(MainLook_Feel);

    MnLook_Feel_Windows.addActionListener(new ActionListener()  {

      public void actionPerformed(ActionEvent e) {
        MnLook_and_Feel(e);
      }
    });
    MnLook_Feel_Motif.addActionListener(new ActionListener()  {
      public void actionPerformed(ActionEvent e) {
        MnLook_and_Feel(e);
      }
    });
    
    MnLook_Feel_Metal.addActionListener(new ActionListener()  {
      public void actionPerformed(ActionEvent e) {
        MnLook_and_Feel(e);
      }
    });
    MnLook_Feel_Macintosh.addActionListener(new ActionListener()  {
      public void actionPerformed(ActionEvent e) {
        MnLook_and_Feel(e);
      }
    });

    MnLook_Feel_Nimbus.addActionListener(new ActionListener()  {
      public void actionPerformed(ActionEvent e) {
        MnLook_and_Feel(e);
      }
    });


    //MnClose.setFont( new Font("Arial", Font.BOLD,18)  );
    //menuBar1.setFont( new Font("Arial", Font.BOLD,18)  );
    
    // ----------------
    // Windows
    MainWindows = new JMenu("Fenster");
    MnPrevWindows = new JMenuItem("Vorheriges Fenster");
    MnNextWindows = new JMenuItem("Nächstes Fenster");
    MnCascade = new JMenuItem("Kaskade");
    MnTile = new JMenuItem("Aufteilen");

    MnCascade.addActionListener(new ActionListener()  {
      public void actionPerformed(ActionEvent e) {
        MnCascade_actionPerformed(e);
      }
    });
    MnTile.addActionListener(new ActionListener()  {
      public void actionPerformed(ActionEvent e) {
        MnTile_actionPerformed(e);
      }
    });
    MainWindows.add(MnPrevWindows);
    MainWindows.add(MnNextWindows);
    MainWindows.addSeparator();
    MainWindows.add(MnCascade);
    MainWindows.add(MnTile);
    menuBar1.add(MainWindows);

      // setzen aller Menüeintraege mit einem Font
    int m = menuBar1.getMenuCount();
    //System.out.println(m);
    for (int i=0; i<m; i++) {
      JMenu main = menuBar1.getMenu(i);
      main.setFont( new Font("Arial", Font.BOLD,18)  );
      int n = main.getItemCount();
      JMenuItem mn;
      for (int j=0; j<n; j++) {
        mn = main.getItem(j);
        // Abfrage auf Separator, sonst Absturz
        if ( mn instanceof JMenuItem )
          mn.setFont( new Font("Arial", Font.BOLD,18)  );
      }
    }

    this.setJMenuBar(menuBar1);
  } // 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;

       // zwei Varianten
    // frame.setBounds( i, i, width-i-20, height-i-20);
    frame.setBounds( i, i, 450, 300);
    frame.setVisible(true);
    _desktopPane.add(frame);
    frame.toFront();
  }  // insertFrame


    // erzeugt ein neues Fenster Frame1   DEFAULT-Einstellung
  void MnNew_click() {
    MyInternalFrame1 frame = new MyInternalFrame1(null);
    insertFrame(frame);
  }

  void MnClose_actionPerformed(ActionEvent e) {
    System.exit(0);
  }


   public void MnLook_and_Feel(ActionEvent e) {
      String slookAndFeel="";
      try {
        if (e.getSource() ==  MnLook_Feel_Windows ) {
            slookAndFeel="com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
        }
        if (e.getSource() ==  MnLook_Feel_Metal ) {
           slookAndFeel="javax.swing.plaf.metal.MetalLookAndFeel";
        }
        if (e.getSource() ==  MnLook_Feel_Motif ) {
            slookAndFeel="com.sun.java.swing.plaf.motif.MotifLookAndFeel";
        }
        if (e.getSource() ==  MnLook_Feel_Macintosh ) {
            slookAndFeel="javax.swing.plaf.mac.MacLookAndFeel";
        }
        if (e.getSource() ==  MnLook_Feel_Nimbus ) {
            slookAndFeel="com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel";
        }

        if (slookAndFeel.length()>0) {
            UIManager.setLookAndFeel(slookAndFeel);
            SwingUtilities.updateComponentTreeUI(this.getContentPane() );  // alles neuzeichnen
        }



      } catch (Exception exc) {
      }

 }  // MnLook_and_Feel


   // -----------------  Window Menü
  void MnCascade_actionPerformed(ActionEvent e) {
      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
      // calc the distace 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;
          // 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_actionPerformed(ActionEvent e) {



  void MnTile_actionPerformed(ActionEvent e) {
    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;
              }
          }
      }
  }



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

}



class MyInternalFrame1 extends JInternalFrame {
  JTextArea _editor = new JTextArea();
  String _sFileName;

  public MyInternalFrame1(String sFileName) {
    _sFileName = sFileName;
    setGUI();
    setClosable(true);
    setIconifiable(true);
    setMaximizable(true);
    setResizable(true);

    setTitle( sFileName );
  }  // MyInternalFrame1


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

    JToolBar toolBar = new JToolBar();
    JButton BnOpen = new JButton("Open");
    BnOpen.setFont( new Font("Arial", Font.BOLD,18)  );
    JButton BnNew = new JButton("New");
    BnNew.setFont( new Font("Arial", Font.BOLD,18)  );
    toolBar.add(BnOpen);
    toolBar.add(BnNew);


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

    _editor.setFont( new Font("Arial", Font.BOLD,18)  );

     this.getContentPane().add(new JScrollPane(_editor), BorderLayout.CENTER);

     createGUI();
    this.setClosable(true);
    this.setIconifiable(true);
  }  // setGUI


  void createGUI() {
    _editor.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'+
             ""
    );
  }


}  // InternalFrame1





