Swing JFC Java

import java.applet.Applet;
import java.awt.Button;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Label;
import java.awt.LayoutManager;
import java.awt.List;
import java.awt.Rectangle;
import java.awt.TextField;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
 * Applet GUI demo of Gamelan TreeLayout layout manager. Constructs a tree and,
 * for each entry, makes a button that jumps to it.
 * 
 * The input language is a file like this: R Java Resources # root L - Resources
 * at Sun # label B http://www.sun.com/foo/bar Interesting Stuff # URLbutton B
 * http://javasoft.com/b/c More Stuff # URLbutton
 * 
 * The result is (supposedly) a beautiful(?) tree. Each L is a top-level label,
 * and each B is in the tree below it.
 * 
 * Could be made much fancier with getParameter("FontName"), "FontSize",
 * adjusting width with fontMetrics, etc. Works adequately for now.
 */
public class TreeLinkTest extends Applet {
  TreeLayout tl;
  public void init() {
    tl = new TreeLayout();
    setLayout(tl);
    Button root = new Button("This is the root");
    add("Root", root);
    tl.setRoot(root);
    Component x = new Label("A random label");
    add("label", x);
    tl.setParent(x, root);
    Component y;
    y = new TextField("Add any component");
    add("comp", y);
    tl.setParent(y, root);
    x = new List();
    ((List) x).add("List entry");
    ((List) x).add("Similarly useless list entry");
    add("list", x);
    tl.setParent(x, root);
    x = new Button("Extremely long and unnecessary button title");
    add("button", x);
    tl.setParent(x, y);
    x = new MyCanvas(getImage(getDocumentBase(), "icons/tools.gif"));
    add("image", x);
    tl.setParent(x, y);
  }
  public void paint(Graphics g) {
    super.paint(g);
    tl.paintLines(g, getBackground());
  }
  class MyCanvas extends Canvas {
    Image img;
    MyCanvas(Image img) {
      this.img = img;
    }
    public Dimension getPreferredSize() {
      return new Dimension(64, 64);
    }
    public void update(Graphics g) {
      paint(g);
    }
    public void paint(Graphics g) {
      g.drawImage(img, 0, getSize().height / 2 - 16, 32, 32, this);
    }
  }
}
/**
 * Simple layout manager that arranges its children in a tree. The tree always
 * expands to fill the available area, and the internal components are resized
 * to fit the area proportional to their preferred size and the actual available
 * size.
 * 
 * This layout manager requires several method calls beyond the normal layout
 * manager. Please notice the following: * Components must be added using the
 * add(String, Component) method. The strings don't have to be unique, but must
 * be present. * Each instance must have exactly one root object, which must be
 * add()ed, then  setRoot()ed. * Each component after the root must first
 * be added and then must be connected into the tree using setParent(child,
 * parent). * If you want lines between parents and children, you must
 * 
 call paintLines() from your applet's paint() method.
 * 
 * @author name unknown, xxx@blackdown.org
 */
class TreeLayout implements LayoutManager {
  TreeNode root;
  Hashtable nodes;
  public TreeLayout() {
    nodes = new Hashtable();
  }
  public void addLayoutComponent(String name, Component comp) {
    TreeNode tn = new TreeNode(comp);
    nodes.put(comp, tn);
  }
  public void removeLayoutComponent(Component comp) {
    nodes.remove(comp);
  }
  /**
   * You must make this call, otherwise none of the components will
   * be layed out.
   */
  public void setRoot(Component c) {
    root = (TreeNode) nodes.get(c);
  }
  /**
   * Sets the tree parent of a child. The components must have been
   * previously added. If either component has not previously been added, this
   * injunction is silently ignored. Cycles are not checked.
   */
  public void setParent(Component child, Component parent) {
    TreeNode p = (TreeNode) nodes.get(parent);
    TreeNode c = (TreeNode) nodes.get(child);
    if ((p != null) && (c != null))
      p.addChild(c);
  }
  public Dimension minimumLayoutSize(Container target) {
    Dimension d = root.getMinimumSize();
    Insets insets = target.getInsets();
    d.width += insets.left + insets.right;
    d.height += insets.top + insets.bottom;
    return d;
  }
  public Dimension preferredLayoutSize(Container target) {
    Dimension d = root.getPreferredSize();
    Insets insets = target.getInsets();
    d.width += insets.left + insets.right;
    d.height += insets.top + insets.bottom;
    return d;
  }
  public void layoutContainer(Container target) {
    Insets insets = target.getInsets();
    Dimension d = target.getSize();
    Dimension root_pref = root.getPreferredSize();
    double xscale = ((double) (d.width - insets.left - insets.right) / (double) (root_pref.width));
    double yscale = ((double) (d.height - insets.top - insets.bottom) / (double) (root_pref.height));
    root.doLayout(xscale, yscale, insets.left, insets.top);
  }
  /**
   * This piece of hackery is needed since one cant really draw things from a
   * layout manager. Call this if you want to draw lines between components.
   */
  public void paintLines(Graphics g, Color bg) {
    Color dk = bg.darker();
    Color br = bg.brighter();
    root.paintLines(g, dk, br);
  }
}
class TreeNode {
  Component comp;
  Vector children;
  Dimension prefSz, minSz;
  TreeNode(Component comp) {
    super();
    this.comp = comp;
    children = new Vector();
  }
  Dimension getMinimumSize() {
    if (!comp.isVisible())
      return new Dimension(0, 0);
    if (minSz == null) {
      Dimension d = comp.getMinimumSize();
      minSz = new Dimension(d.width, d.height);
      if (children.size() > 0) {
        for (Enumeration e = children.elements(); e.hasMoreElements();) {
          TreeNode t = (TreeNode) (e.nextElement());
          if (t.comp.isVisible()) {
            d = t.getMinimumSize();
            minSz.height += d.height;
            minSz.width = Math.max(d.width, minSz.width);
          }
        }
      }
    }
    return minSz;
  }
  Dimension getPreferredSize() {
    if (!comp.isVisible())
      return new Dimension(0, 0);
    if (prefSz == null) {
      Dimension d = comp.getPreferredSize();
      prefSz = new Dimension(d.width, d.height);
      if (children.size() > 0) {
        int wmax = 0;
        for (Enumeration e = children.elements(); e.hasMoreElements();) {
          TreeNode t = (TreeNode) (e.nextElement());
          if (t.comp.isVisible()) {
            d = t.getPreferredSize();
            prefSz.height += d.height;
            if (wmax < d.width) {
              wmax = d.width;
            }
          }
        }
        prefSz.width += wmax;
      }
    }
    return prefSz;
  }
  void addChild(TreeNode t) {
    children.addElement(t);
    prefSz = null;
    minSz = null;
  }
  void removeChild(TreeNode t) {
    children.removeElement(t);
    prefSz = null;
    minSz = null;
  }
  void paintLines(Graphics g, Color dk, Color br) {
    if (comp.isVisible()) {
      Rectangle b = comp.getBounds();
      int x1off = b.x + b.width / 2;
      int x2off = b.x + b.width;
      int y1off = b.y;
      for (Enumeration e = children.elements(); e.hasMoreElements();) {
        TreeNode tn = (TreeNode) (e.nextElement());
        if (tn.comp.isVisible()) {
          Rectangle bn = tn.comp.getBounds();
          int y2off = bn.y + bn.height / 2;
          g.setColor(dk);
          g.drawLine(x1off, y1off, x1off, y2off);
          g.drawLine(x1off, y2off - 1, x2off, y2off - 1);
          g.setColor(br);
          g.drawLine(x1off + 1, y1off, x1off + 1, y2off);
          g.drawLine(x1off, y2off, x2off, y2off);
          tn.paintLines(g, dk, br);
        }
      }
    }
  }
  void doLayout(double xscale, double yscale, int x, int y) {
    // x and y are the offsets into the
    // Container where we start doing the
    // goodies for this Node
    if (comp.isVisible()) {
      Dimension pref = comp.getPreferredSize();
      int ht = (int) Math.round(yscale * pref.height);
      int wd = (int) Math.round(xscale * pref.width);
      ht = (pref.height < ht) ? pref.height : ht;
      wd = (pref.width < wd) ? pref.width : wd;
      comp.setBounds(x, y, wd, ht);
      y += ht;
      x += wd;
      for (Enumeration e = children.elements(); e.hasMoreElements();) {
        TreeNode tn = (TreeNode) (e.nextElement());
        if (tn.comp.isVisible()) {
          pref = tn.getPreferredSize();
          tn.doLayout(xscale, yscale, x, y);
          y += (int) Math.round(yscale * pref.height);
        }
      }
    }
  }
}