home *** CD-ROM | disk | FTP | other *** search
/ Late Night VRML 2.0 with Java CD-ROM / code.zip / Ch12 / ui / tree / treeCanvas.java < prev    next >
Text File  |  1997-01-02  |  7KB  |  274 lines

  1. package ui.tree;
  2.  
  3. import java.awt.*;
  4. import ui.tree.*;
  5.  
  6. public class treeCanvas extends Canvas implements TreeToolObserver
  7. {
  8.     protected int   width = 20;
  9.     protected int   height = 20;
  10.     protected int   xPos = 0;
  11.     protected int   yPos = 0;
  12.     protected TreeNode  root = null;
  13.  
  14.     protected ScrollerInterface scroller = null;
  15.  
  16.     protected TreeTool  tool = null;;
  17.     public TreeNode     selected = null;
  18.     public Dimension    psize = null; // preferred size
  19.     public Dimension    tsize = null; // total (tree) size
  20.     // draw to offscreen graphics from example GraphLayout (SUN)
  21.     protected Image     offscreen = null;
  22.     private Dimension offscreensize = null;
  23.     protected Graphics offgraphics = null;
  24.     // some layout constants
  25.     public int horizontal_offset = 30;
  26.     public int vertical_offset = 20;
  27.     public Color line_color = Color.black;
  28.     public Color background_color =  Color.white;
  29.  
  30.  
  31.     public treeCanvas(TreeTool t)
  32.     {
  33.         // constructor for root node
  34.         offscreensize = new Dimension(0,0); // intitial size is zero
  35.         tsize = new Dimension(-1, -1);
  36.         tool = t!=null?t:tool;
  37.         startObserving();
  38.     }
  39.  
  40.     public int getImageHeight()
  41.     {
  42.         return(tsize.height);
  43.     }
  44.  
  45.     public int getImageWidth()
  46.     {
  47.         return(tsize.width);
  48.     }
  49.  
  50.     public Dimension preferredSize() {
  51.         // System.out.println("TreeViewPanel::preferredSize() is "+psize);
  52.         return tsize;
  53.     }
  54.  
  55.     public void startObserving() {
  56.         recomputeTree();
  57.         tool.addObserver(this);
  58.     }
  59.  
  60.     public void stopObserving() {
  61.         tool.removeObserver(this);
  62.     }
  63.  
  64.     public void nodeSelected(TreeNode node) {
  65.         selected = node;
  66.         //System.out.println("Node selected = " + selected.toString());
  67.         repaint();
  68.     }
  69.  
  70.     public void nodeUnSelected(TreeNode node) {
  71.         selected = null;
  72.         repaint();
  73.     }
  74.  
  75.     public void nodeOpened(TreeNode node) {
  76.         //System.out.println("Node opened");
  77.         fullUpdate();
  78.     }
  79.  
  80.     public void nodeClosed(TreeNode node) {
  81.         //System.out.println("Node closed");
  82.         fullUpdate();
  83.     }
  84.  
  85.     public void nodeAdded(TreeNode where,TreeNode node) {
  86.         fullUpdate();
  87.     }
  88.  
  89.     public void nodeRemoved(TreeNode node) {
  90.         fullUpdate();
  91.     }
  92.  
  93.     public void fullUpdate() {
  94.         // System.out.println("TreeViewPanel::fullUpdate()");
  95.         recomputeTree();
  96.         repaint();
  97.     }
  98.  
  99.     // Used to remove subtrees from the tree structure
  100.     public void removeNode(TreeNode n)
  101.     {
  102.         tool.tree.removeNode(n);
  103.         fullUpdate();
  104.     }
  105.  
  106.     public Dimension computeTree(TreeNode node,int x,int y)
  107.     {
  108.         // System.out.println("TreeViewPanel::computeTree("+node+","+x+","+y+")");
  109.         Dimension child_extent = null;
  110.         node.x = x;
  111.         node.y = y;
  112.         int hei = node.hei;
  113.         int wid = node.wid;
  114.         int xc = x+horizontal_offset;
  115.         int yc = y+hei+vertical_offset;
  116.         int num = 0;
  117.         if (node.isOpen())
  118.             num = node.numberChilds();
  119.  
  120.         for (int i=0;i<num;i++)
  121.         {
  122.             TreeNode child = node.getChild(i);
  123.             child_extent = computeTree(child,xc,yc);
  124.             if (child_extent.width+horizontal_offset>wid)
  125.                 wid = child_extent.width+horizontal_offset;
  126.             yc += child_extent.height+vertical_offset;
  127.         }
  128.         hei = yc - y - vertical_offset;
  129.         return new Dimension(wid,hei);
  130.     }
  131.  
  132.     public void recomputeTree() {
  133.         //System.out.println("TreeViewPanel::recomputeTree()");
  134.         int x = horizontal_offset;
  135.         int y = vertical_offset;
  136.         int width;
  137.         int height;
  138.  
  139.         Dimension extent = computeTree(tool.tree.root,x,y);
  140.  
  141.         width = x+extent.width+horizontal_offset;
  142.         height= y+extent.height+vertical_offset;
  143.         //System.out.println("offscreensize.width = " + offscreensize.width + " offscreensize.height = " + offscreensize.height);
  144.         tsize.width = width;
  145.         tsize.height = height;
  146.         //System.out.println("Tsize.width = " + tsize.width + " tsize.height = " + tsize.height);
  147.         //System.out.println("offscreensize.width = " + offscreensize.width + " offscreensize.height = " + offscreensize.height);
  148.         //System.out.println("    ");
  149.         //System.out.println("tree computed, extent is " + tsize.width + "  " + tsize.height);
  150.     }
  151.  
  152.     public void drawTree(Graphics g,TreeNode node) {
  153.         // System.out.println("TreeViewPanel::drawTree("+node+")");
  154.         node.draw(g);
  155.         int lx = node.x+(horizontal_offset/2);
  156.         int ly = node.y+node.hei;
  157.         int yp = -1;
  158.         int num = 0;
  159.         if (node.isOpen())
  160.             num = node.numberChilds();
  161.  
  162.         for (int i=0;i<num;i++)
  163.         {
  164.             TreeNode child = node.getChild(i);
  165.             // draw horizontal line
  166.             yp = child.y+(child.hei/2);
  167.             g.setColor(line_color);
  168.             g.drawLine(lx,yp,child.x,yp);
  169.             // draw sub-tree
  170.             drawTree(g,child);
  171.         }
  172.         if (yp>0) { // draw vertical line
  173.         g.setColor(line_color);
  174.         g.drawLine(lx,ly,lx,yp);
  175.         }
  176.     }
  177.  
  178.     public void update(Graphics g) {
  179.         // System.out.println("TreeViewPanel::update()");
  180.         // force redraw :
  181.         offscreen = null;
  182.         paint(g);
  183.     }
  184.  
  185.     public void paint(Graphics g)
  186.     {
  187.         Dimension d = size();
  188.         if ((offscreen == null) || (d.width != offscreensize.width) || (d.height != offscreensize.height))
  189.         {
  190.             offscreen = createImage(d.width,d.height);
  191.             offscreensize = tsize;
  192.             offgraphics = offscreen.getGraphics();
  193.             offgraphics.setFont(getFont());
  194.             offgraphics.setColor(background_color);
  195.             offgraphics.fillRect(0, 0, d.width, d.height);
  196.         }
  197.         offgraphics.translate(-1 * ((scrollPanel)getParent()).imgX,-1 * ((scrollPanel)getParent()).imgY);
  198.         drawTree(offgraphics,tool.tree.root);
  199.         g.drawImage( offscreen,0,0,null ) ;
  200.     }
  201.  
  202.     public Dimension getImageSize()
  203.     {
  204.         return(tsize);
  205.     }
  206.  
  207.     public TreeNode findNode(TreeNode start,int x,int y)
  208.     {
  209.         // since we know all the node's positions , this could be
  210.         // done in a much faster way, but for now : simply brute force !
  211.         // System.out.println("TreeViewPanel::findNode("+start+")");
  212.         if (start.inside(x,y))
  213.             return start;
  214.         else
  215.         {
  216.             if (start.isLeaf())
  217.                 return null;
  218.             else
  219.             {
  220.                 int num = start.numberChilds();
  221.                 int i=0;
  222.                 TreeNode found = null;
  223.                 while ((found==null) && (i<num))
  224.                 {
  225.                     TreeNode ch = start.getChild(i);
  226.                     if (ch.isOpen()) // dont check closed subtrees !
  227.                     found = findNode(ch,x,y);
  228.                     else
  229.                     {
  230.                         if (ch.inside(x,y))
  231.                             found = ch;
  232.                         else found = null;
  233.                     }
  234.                     i++;
  235.                 }
  236.             return found;
  237.             }
  238.         }
  239.     }
  240.  
  241.     public boolean mouseDown(Event evt,int x,int y)
  242.     {
  243.         // System.out.println("TreeViewPanel::mouseDown("+x+","+y+")");
  244.         //if (scroller!=null)
  245.         //{
  246.         //    int h_val = scroller.getHorizontalScrollerVal();
  247.         //    int v_val = scroller.getVerticalScrollerVal();
  248.         //    x += h_val;
  249.         //    y += v_val;
  250.         //}
  251.         TreeNode found = findNode(tool.tree.root,x,y);
  252.         if (found==null)
  253.         { // no node found -> unselect all
  254.             if (selected!=null)
  255.                 tool.unSelectNode(selected);
  256.             return true;
  257.         }
  258.  
  259.         if (found==selected)
  260.         { // double click -> toggle open/close
  261.             if (found.isOpen())
  262.                 tool.closeNode(found);
  263.             else
  264.                 tool.openNode(found);
  265.         }
  266.         else
  267.         { // new selection -> unselect old and select new one
  268.             if (selected!=null)
  269.                 tool.unSelectNode(selected);
  270.             tool.selectNode(found);
  271.         }
  272.         return true;
  273.     }
  274. }