/*
*  SimpleGridBag
*  -------------
*/

import java.awt.*;
import java.util.StringTokenizer;

/** 
 * Ein Layout-Manager, der das Java-GridBagLayout etwas leichter bedienbar
 * macht. Wenn man Komponenten zu einem von GridBagLayout verwalteten 
 * Container hinzufügt, muß überlicherweise ein eigenes 
 * GridBagConstraints-Objekt erzeugt werden, in dem alle Layout-Parameter
 * stehen. 
 * <p>
 * Dieser Layout-Manager erlaubt es, stattdessen auch einen String zu
 * übergeben, in dem die meisten Parameter in Textform angegeben werden
 * können. Das macht den Quelltext sehr viel übersichtlicher.
 * <p>
 * Quelle: <tt>http://www.remote.org/frederik/projects/software/</tt>
 *  
 * @author Frederik Ramm <frederik@remote.org>
 * @version 1.1 (Oktober 1998) 
 */

public final class SimpleGridBag extends GridBagLayout {

   private int lastrow = 0;


/* ---------------------------------------------------------------------- *//**
 * Die einzige Methode dieser Klasse; sie kann als "constraints" neben 
 * dem für GridBagLayout üblichen GridBagConstraints-Objekt auch einen 
 * String übergeben bekommen. Er kann, durch Leerzeichen oder Kommata 
 * getrennt, folgende Parameter enthalten:
 *
 * <pre>
 * x=zahl       Komponente soll in Spalte <zahl> (wenn nicht angegeben:
 *              rechts neben der letzten Komponente)
 * y=zahl       Zeile - wenn nicht angegeben: gleiche wie die letzte
 * nl           "new line" - eine Zeile weiterzählen und in Spalte 0 gehen
 * w=zahl       Breite (default: 1 Spalte)
 * h=zahl       Höhe (default: 1 Zeile)
 * f=code       "Fill", code=v: VERTICAL, code=h: HORIZONTAL, code=b:BOTH
 * px=zahl      Padding
 * py=zahl      "
 * wx=zahl      Weight
 * wy=zahl      "
 * a=code       Align, code kann n, e, w, s sein (Himmelsrichtung) oder
 *              c (Center); die Mix-Alignments nw usw. sind nicht drin 
 * i[code]=zahl Insets; entweder i=5 (setzt alle vier Seiten auf 5 Pixel)
 *              oder einzeln mit it=x, ib=x, il=x, ir=x (top, left, bottom,
 *              right)
 * </pre>
 */
public void addLayoutComponent(Component comp, Object constraints) {

   if (constraints instanceof GridBagConstraints) {

      /* Normale Verwendung wie in der Methode, die wir hierdurch
       * überschrieben haben. Immer schön abwärtskompatibel bleiben:
       */
      setConstraints(comp, (GridBagConstraints)constraints);

   } else if (constraints instanceof String) {

      /* Verwendung mit einem Format-String wie oben */
   
      StringTokenizer s = new StringTokenizer((String)constraints, ' ');
      String token, code, value;
      int equal;
      GridBagConstraints c = new GridBagConstraints();
      c.gridx = GridBagConstraints.RELATIVE;
      c.gridy = lastrow;
      while (s.hasMoreTokens()) {
         token = s.nextToken();
         if ((equal = token.indexOf("="))>=0) {
            code  = token.substring(0,equal);
            value = token.substring(equal+1);
            if (code.equals("x")) {
                 c.gridx = Integer.parseInt(value);
            } else if (code.equals("y")) {
                 lastrow = c.gridy = Integer.parseInt(value);
            } else if (code.equals("h")) {
                 c.gridheight = Integer.parseInt(value);
            } else if (code.equals("w")) {
                 c.gridwidth = Integer.parseInt(value);
            } else if (code.equals("f")) {
                 switch(value.charAt(0)) {
                 case 'b': c.fill = GridBagConstraints.BOTH; break;
                 case 'h': c.fill = GridBagConstraints.HORIZONTAL; break;
                 case 'v': c.fill = GridBagConstraints.VERTICAL; break;
                 default:  c.fill = GridBagConstraints.NONE; 
                 }
            } else if (code.equals("px")) {
                 c.ipadx = Integer.parseInt(value);
            } else if (code.equals("py")) {
                 c.ipady = Integer.parseInt(value);
            } else if (code.charAt(0) == 'i') {
                  int i = Integer.parseInt(value);
                  if (code.length() == 1) {
                     c.insets = new Insets(i,i,i,i);
                  } else {
                     if (c.insets == null) c.insets = new Insets(0,0,0,0);
                     switch (code.charAt(1)) {
                     case 'l': c.insets.left = i; break;
                     case 't': c.insets.top = i; break;
                     case 'b': c.insets.bottom = i; break;
                     case 'r': c.insets.right = i; break;
                     }
                  }
            } else if (code.equals("wx")) {
                 c.weightx = Double.valueOf(value).doubleValue();
            } else if (code.equals("wy")) {
                 c.weighty = Double.valueOf(value).doubleValue();
            } else if (code.equals("a")) {
               switch(value.charAt(0)) {
               case 'e': c.anchor = GridBagConstraints.EAST; break;
               case 'w': c.anchor = GridBagConstraints.WEST; break;
               case 'n': c.anchor = GridBagConstraints.NORTH; break;
               case 's': c.anchor = GridBagConstraints.SOUTH; break;
               case 'c': c.anchor = GridBagConstraints.CENTER; break;
               }   
            }
         } else if (token.equals("nl")) {
            c.gridy = ++lastrow;
            c.gridx = 0;
         };
      }
      setConstraints(comp, c);

   } else if (constraints != null) {
   
      /* Wie in der hierdurch überschriebenen Methode */

      throw new IllegalArgumentException("cannot add to layout: constraint must be a GridBagConstraint or String"); 
   }
}

}



