home *** CD-ROM | disk | FTP | other *** search
/ Dynamic HTML in Action / Dynamicke-HTML-v-akci-covermount.bin / XML / PARSER / XMLINST.EXE / viewer / XMLTreeView.java < prev    next >
Encoding:
Java Source  |  1997-10-31  |  49.2 KB  |  1,454 lines

  1. //******************************************************************************
  2. // XMLTreeView
  3. //
  4. //******************************************************************************
  5. import java.awt.*;
  6. import java.awt.Choice;
  7.  
  8. import java.util.Enumeration;
  9.  
  10. import com.ms.xml.parser.*;
  11. import com.ms.xml.om.*;
  12. import com.ms.xml.util.*;
  13.  
  14. import java.net.URL;
  15.  
  16.  
  17. import Scroller;
  18.  
  19. class SpecialEnumeration implements Enumeration
  20. {
  21.     public SpecialEnumeration(Element e)
  22.     {
  23.         this.en = new ElementEnumeration(e);
  24.         next();
  25.     }
  26.  
  27.     public boolean hasMoreElements()
  28.     {
  29.         return (next != null);
  30.     }
  31.  
  32.     public Object nextElement()
  33.     {
  34.         Element result = next;
  35.         next();
  36.         return result;
  37.     }
  38.  
  39.     void next()
  40.     {
  41.         while (en.hasMoreElements())
  42.         {
  43.             next = (Element)en.nextElement();
  44.             if (next.getType() != Element.WHITESPACE)
  45.                 return;
  46.         }
  47.         next = null;
  48.     }
  49.  
  50.     Element next;
  51.     Enumeration en;
  52. }
  53.  
  54.  
  55. class XMLTreeView extends BufferedCanvas
  56. {
  57.     public Image openFolder;
  58.     public Image closedFolder;
  59.  
  60.     XMLTreeView() {
  61.     }
  62.  
  63.     public void setDocument(Document d)
  64.     {
  65.         this.d = d;
  66.         viewText = false;
  67.  
  68.         maxBranch = 0;
  69.         head = null;
  70.         getMaxBranch(this.d, 0); // This is needed so we can draw the proper tree lines later on.
  71.         setViewChoice( this.d.getRoot() );
  72.         
  73.         focus = head;
  74.         focusY = 0;
  75.         if (focus != null)
  76.             focus.setAttribute( kFocus, "TRUE" );
  77.  
  78.         newGraphics();  // Reset the graphic image to insure that everything is okay.
  79.  
  80.         repaint();
  81.     }
  82.  
  83.     public void showText(String text)
  84.     {
  85.         viewText = true;
  86.         reorient();
  87.         this.buffer = text;
  88.         invalidateBuffer();
  89.         repaint();
  90.     }
  91.  
  92.     public void getMaxBranch( Element e, int branch )
  93.     {
  94.         if( e.numElements() > 0)
  95.         {
  96.             for( Enumeration en = new SpecialEnumeration(e); en.hasMoreElements(); ) 
  97.             {
  98.                 Element child = ( Element )en.nextElement();             
  99.                 getMaxBranch( child, branch + 1 );                             
  100.             }
  101.         } 
  102.         else
  103.         {
  104.             if( branch > maxBranch )            
  105.                 maxBranch = branch;
  106.         }
  107.     }
  108.  
  109.     public String elementPos( Element e )
  110.     {
  111.         String elPos = new String("");
  112.         Element curr = e;
  113.         while( curr!=null && curr!=this.d )
  114.         {   
  115.             Name currTagName = curr.getTagName();
  116.             if( currTagName != null )
  117.                 elPos = currTagName.toString() + "\\" + elPos;
  118.             curr = curr.getParent();
  119.         }
  120.  
  121.         return elPos;
  122.     }
  123.  
  124.     public void setViewChoiceHelp( Element e )
  125.     {
  126.         if( e!=null && e!=this.d )
  127.         {
  128.             setViewChoiceHelp( e.getParent() );
  129.             choice.addItem( elementPos(e) );
  130.         }
  131.     }
  132.  
  133.     public void setViewChoice( Element e )
  134.     {
  135.         sizeChange = true;
  136.         
  137.         if( jdk11 )  // There is NO WAY to remove items from choice box before jdk11!
  138.         {
  139.             choice.removeAll();
  140.             setViewChoiceHelp( e );
  141.             int num = choice.countItems();
  142.             if( num == 0 )
  143.                 return;
  144.  
  145.             choice.select( num-1 );
  146.         }
  147.  
  148.         head = e;
  149.  
  150.         found = null;
  151.         findElement( this.d, head, 15, 0 );
  152.         if( found != null )
  153.         {
  154.             headX = foundX;
  155.             headY = foundY;
  156.         }
  157.         else
  158.         {
  159.             headX = 0;
  160.             headY = 0;
  161.         }
  162.  
  163.         if( focus != null )
  164.             focus.removeAttribute( kFocus );
  165.         focus = head;
  166.         focus.setAttribute( kFocus, "TRUE" );
  167.         focusY = headY;
  168.  
  169.         reorient();
  170.         postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null));                         
  171.         invalidateBuffer();
  172.     }
  173.  
  174.     //--------------------------------------------------------------------------
  175.     public void paintBuffer( Graphics g )
  176.     {
  177.         int treeHeightLines = 0;
  178.         maxWidth = 0;
  179.  
  180.         g.setColor(Color.white);
  181.         Dimension dim = size();
  182.         Rectangle clip = g.getClipRect();
  183.         g.fillRect(clip.x, clip.y, 
  184.             clip.width, clip.height);
  185.         g.setColor(Color.black);
  186.  
  187.         if( !viewText )
  188.         {
  189.             treeLines = new int[maxBranch];
  190.             currLines = 0;
  191.             doneDraw = false;
  192.             stopDraw = false;
  193.  
  194.             try {
  195.                 if( head != null && head != this.d )
  196.                 {
  197.                     treeHeightLines = drawTree(g, head, 15, 0 );
  198.                 }                
  199.                 else
  200.                 {
  201.                     treeHeightLines = drawTree(g, this.d, 15, 0);
  202.                 }
  203.             } catch( Exception e ) {
  204.                 treeHeightLines = 0;
  205.                 g.setColor(Color.black);
  206.                 g.drawString(e.toString(),10,15);
  207.             }
  208.  
  209.             if (inside != null && pressed == null)
  210.             {
  211.                 drawAttributes(g, inside, ax, ay);
  212.             }
  213.         }
  214.         else
  215.         {
  216.             int lines = viewDoc(g);
  217.             if (lines != treeHeightLines)
  218.                 sizeChange = true;
  219.             treeHeightLines = lines;
  220.         }
  221.  
  222.         if( sizeChange )
  223.         {            
  224.             if( getDisplayHeightLines() != treeHeightLines + 1 )
  225.             {
  226.                 displayHeight = YPOS(treeHeightLines + 1);
  227.             }
  228.             if( displayWidth != maxWidth )
  229.             {
  230.                 displayWidth = maxWidth;
  231.             }
  232.               
  233.             sizeChange = false;       
  234.             postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null));
  235.         }   
  236.     }
  237.  
  238.     //--------------------------------------------------------------------------
  239.     public int viewDoc(Graphics g) 
  240.     {
  241.         int y = 1;
  242.         y = drawText( g, buffer, 10, y, getCanvasWidth(), false, buffer.length(), false, true );        
  243.         return y;
  244.     }
  245.  
  246.     //--------------------------------------------------------------------------
  247.     public void drawTreeLines( Graphics g, int y, boolean hasChildren, boolean hidden, boolean isHead )
  248.     {
  249.         if( isHead )
  250.         {
  251.             if( hasChildren )
  252.             {
  253.                 g.drawLine(headX + 20 + 5,  YPOS(y) + (fm.getMaxAscent()/2),
  254.                            headX + 20 + 9,  YPOS(y) + (fm.getMaxAscent()/2));
  255.                 // Line coming out of folder
  256.                 if(!hidden)
  257.                     g.drawLine(headX + 20 + LEVELINDENT+INDENT, YPOS(y) + 12,
  258.                                headX + 20 + LEVELINDENT+INDENT, YPOS(y) + (LINE_SIZE));
  259.             }
  260.             return;
  261.         } 
  262.  
  263.         for( int i = 0; i < currLines-1; i++ )
  264.         {
  265.             if( treeLines[i] >= 0 )
  266.                 g.drawLine(treeLines[i],YPOS(y),
  267.                            treeLines[i],YPOS(y)+(LINE_SIZE));
  268.         }
  269.  
  270.         if( currLines != 0 ) 
  271.         {
  272.             boolean lastChild = false;
  273.             int x = treeLines[currLines-1];
  274.             if( x < 0 )
  275.             {
  276.                x *= -1;
  277.                lastChild = true;
  278.             }
  279.                             
  280.             if( !hasChildren )
  281.             {             
  282.                 if( !lastChild )
  283.                    g.drawLine(x, YPOS(y),
  284.                               x, YPOS(y) + (LINE_SIZE));
  285.                 else                
  286.                     g.drawLine(x, YPOS(y),
  287.                                x, YPOS(y) + (fm.getMaxAscent()/2));                    
  288.                 g.drawLine(x,      YPOS(y) + (fm.getMaxAscent()/2),
  289.                            x + 15, YPOS(y) + (fm.getMaxAscent()/2));
  290.             }             
  291.             else
  292.             {             
  293.                 // Need to avoid click box
  294.                 g.drawLine(x, YPOS(y),                
  295.                            x, YPOS(y) + 1 );
  296.                 if( !lastChild )             
  297.                     g.drawLine(x, YPOS(y) + 1 + RECT_SIZE,
  298.                                x, YPOS(y) + (LINE_SIZE));                    
  299.                 g.drawLine(x + 5,  YPOS(y) + (fm.getMaxAscent()/2),
  300.                            x + 9,  YPOS(y) + (fm.getMaxAscent()/2));
  301.                 // Line coming out of folder
  302.                 if( !hidden )
  303.                     g.drawLine(x + LEVELINDENT+INDENT, YPOS(y) + 12,
  304.                                x + LEVELINDENT+INDENT, YPOS(y) + (LINE_SIZE));
  305.             }
  306.         }        
  307.  
  308.         int b = 10000;
  309.     }           
  310.  
  311.     //--------------------------------------------------------------------------
  312.     public void drawTextLines( Graphics g, int y, int height )
  313.     {
  314.         for( int i = 0; i < currLines-1; i++ )
  315.         {
  316.             if( treeLines[i] >= 0 )
  317.                 g.drawLine(treeLines[i],YPOS(y),
  318.                            treeLines[i],YPOS(y)+YPOS(height+1));
  319.         }
  320.  
  321.         if( currLines != 0 ) 
  322.         {
  323.             boolean lastChild = false;
  324.             int x = treeLines[currLines-1];
  325.             if( x < 0 )
  326.             {
  327.                x *= -1;
  328.                lastChild = true;
  329.             }
  330.                             
  331.             if( !lastChild )
  332.                 g.drawLine(x, YPOS(y),
  333.                            x, YPOS(y) + YPOS(height+1));
  334.             else                
  335.                 g.drawLine(x, YPOS(y),
  336.                            x, YPOS(y) + (fm.getMaxAscent()/2));                    
  337.             g.drawLine(x, YPOS(y) + (fm.getMaxAscent()/2),
  338.                        x + 4, YPOS(y) + (fm.getMaxAscent()/2));                       
  339.         }
  340.     }           
  341.  
  342.     //--------------------------------------------------------------------------
  343.     public void drawElement( Graphics g, Element child, int x, int y )
  344.     {
  345.         int width = fm.stringWidth( child.getTagName().toString() );
  346.  
  347.         String pressed = (String)child.getAttribute( kPressed );
  348.         String inside  = (String)child.getAttribute( kInside );
  349.         String focus   = (String)child.getAttribute( kFocus );
  350.         String hidden  = (String)child.getAttribute( kHidden );
  351.  
  352.         if (inside != null && inside.equals("TRUE"))
  353.             g.setColor(Color.blue);  // Only set new color for INSIDE
  354.         boolean hasChildren = (child.numElements() > 0);
  355.         if (hasChildren) {
  356.             g.drawRect( x+1,YPOS(y)+1,RECT_SIZE,RECT_SIZE );
  357.             if (pressed != null && pressed == inside) {
  358.                 g.drawRect(x+2,YPOS(y)+2,RECT_SIZE-2,RECT_SIZE-2); //Smaller rect inside larger
  359.             }            
  360.         } else {
  361.             g.drawOval(x+20,YPOS(y),OVAL_SIZE,OVAL_SIZE);
  362.         }                            
  363.         if( focus != null )
  364.         {
  365.             if( hasFocus )
  366.             {
  367.                 g.setColor( Color.blue );
  368.                 g.fillRect( x+(OVAL_SIZE+FOLDER_SIZE+(INDENT*2))-SPACING, YPOS(y)-SPACING,
  369.                             width+(SPACING*2), fm.getMaxAscent()+(SPACING*2) );
  370.                 g.setColor( Color.white );
  371.                 g.drawString(child.getTagName().toString(),
  372.                              x+OVAL_SIZE+FOLDER_SIZE+(INDENT*2),YPOS(y)+fm.getMaxAscent());
  373.                 g.setColor( Color.black );
  374.             }
  375.             else
  376.             {
  377.                 g.drawRect( x+(OVAL_SIZE+FOLDER_SIZE+(INDENT*2))-SPACING, YPOS(y)-SPACING,
  378.                             width+(SPACING*2), fm.getMaxAscent()+(SPACING*2) );
  379.                 g.drawString(child.getTagName().toString(),
  380.                              x+OVAL_SIZE+FOLDER_SIZE+(INDENT*2),YPOS(y)+fm.getMaxAscent());
  381.             }
  382.         }
  383.         else
  384.             g.drawString(child.getTagName().toString(),
  385.                 x+OVAL_SIZE+FOLDER_SIZE+(INDENT*2),YPOS(y)+fm.getMaxAscent());
  386.  
  387.         if (child.numAttributes() > 0 && child == this.inside && pressed == null) {
  388.             ax = x + 15 + 10;
  389.             ay = y + 2;
  390.         } 
  391.         if( hasChildren ) {
  392.             if( hidden != null && hidden.equals("TRUE") ) {
  393.                 g.drawLine(x+5,YPOS(y)+3,x+5,YPOS(y)+7);
  394.                 g.drawLine(x+3,YPOS(y)+5,x+7,YPOS(y)+5);
  395.                 g.drawImage(closedFolder, x+OVAL_SIZE+INDENT, YPOS(y)-SPACING, this);
  396.             } else {
  397.                 g.drawLine(x+3,YPOS(y)+5,x+7,YPOS(y)+5);
  398.                 g.drawImage(openFolder, x+OVAL_SIZE+INDENT, YPOS(y)-SPACING, this);
  399.             }
  400.         }
  401.         if (inside != null && inside.equals("TRUE"))
  402.             g.setColor(Color.black);  // Set color back to black after INSIDE
  403.         drawTreeLines(g,y,hasChildren, (hidden != null && hidden.equals("TRUE")), (child == head));    
  404.     }
  405.  
  406.     //--------------------------------------------------------------------------
  407.     public int drawTree(Graphics g, Element e, int x, int y)
  408.     {       
  409.         if( stopDraw || e == null ) 
  410.             return y;
  411.  
  412.         if( isElement(e))         
  413.         {                                                 
  414.             boolean eHasChildren = (e.numElements() > 0);                
  415.  
  416.             Rectangle onScreen = g.getClipRect();        
  417.             int width = fm.stringWidth(e.getTagName().toString())+OVAL_SIZE+FOLDER_SIZE+(INDENT*2);
  418.             if( width + x > maxWidth )
  419.                 maxWidth = width + x;
  420.             Rectangle elDraw = new Rectangle( x,YPOS(y), width, LINE_SIZE );        
  421.             if( elDraw.intersects( onScreen ) ) { // We need to draw!
  422.                 doneDraw = true;
  423.                 drawElement( g, e, x, y );
  424.             }
  425.             else if( doneDraw && !sizeChange )
  426.             {
  427.                 stopDraw = true;
  428.                 return y;
  429.             }
  430.  
  431.             if( eHasChildren && e.getAttribute(kHidden) == null )
  432.             {
  433.                 // Turn lines on
  434.                 treeLines[currLines] = x+20;
  435.                 int tmpLines = currLines;
  436.                 currLines++;
  437.  
  438.                 //  Recurse down the tree
  439.                 for( Enumeration en = new SpecialEnumeration(e); en.hasMoreElements(); ) 
  440.                 {
  441.                     Element child = (Element)en.nextElement();
  442.                     
  443.                     if( !en.hasMoreElements() )  // Negative number implies this is last child.
  444.                         treeLines[tmpLines] *= -1;  
  445.                     y = drawTree( g,child,x+LEVELINDENT+INDENT,y+1 );
  446.                     
  447.                     if( stopDraw )
  448.                         return y;
  449.                 }   
  450.  
  451.                 // Turn lines off completely
  452.                 currLines--;            
  453.             }
  454.         }
  455.         else if (e.getText() != null)          
  456.         {             
  457.             String sHeight = (String)e.getAttribute( kHeight );
  458.             int height;
  459.             if( sHeight == null || sizeChange)
  460.             {         
  461.                 // measure only
  462.                 height = drawText(g, e.getText(),x+LEVELINDENT,
  463.                                     y,
  464.                                     getCanvasWidth() - x - 20,
  465.                                     true, 0, false, false) - y;                        
  466.                 e.setAttribute(kHeight, Integer.toString(height));
  467.             }             
  468.             else
  469.             {
  470.                 height = Integer.valueOf(sHeight).intValue();
  471.             }
  472.                  
  473.             Rectangle onScreen = g.getClipRect();
  474.             // We add one to height because text lines reach down below the text.
  475.             Rectangle elDraw = new Rectangle( x,YPOS(y),             
  476.                                     getCanvasWidth() - x - 20, YPOS(height+1) );
  477.             if( elDraw.intersects( onScreen ) )
  478.             {             
  479.                 Color c = Color.black;
  480.                 switch (e.getType()) {             
  481.                 case Element.PI:                            
  482.                     c = Color.magenta;                    
  483.                     break;                    
  484.                 case Element.ENTITY:                
  485.                     c = Color.green;   
  486.                     c.darker();
  487.                     break;                    
  488.                 case Element.CDATA:                
  489.                     c = Color.gray;                    
  490.                     break;                    
  491.                 case Element.PCDATA:                
  492.                     c = Color.black;                    
  493.                     break;                   
  494.                 case Element.COMMENT:                
  495.                     c = Color.red;                    
  496.                     break;                   
  497.                 }    
  498.                 g.setColor(c);
  499.     
  500.                 // draw the text                
  501.                 int y2 = drawText(g,
  502.                     e.getText(),x+10,                   
  503.                     y,                    
  504.                     getCanvasWidth() - x - 20,                    
  505.                     true, 0, false, true);  
  506.                 e.setAttribute(kHeight, Integer.toString(y2-y));                
  507.  
  508.                 // Draw the tree lines
  509.                 g.setColor(Color.black);                
  510.                 drawTextLines(g,y,(y2-y));    
  511.  
  512.                 y = y2;                        
  513.             } else {            
  514.                 // measure only
  515.                 int y2 = drawText(g, e.getText(),x+10,                
  516.                     y,                    
  517.                     getCanvasWidth() - x - 20,                    
  518.                     true, 0, false, false);                                            
  519.                 e.setAttribute(kHeight, Integer.toString(y2-y));                                        
  520.                 y = y2;                                    
  521.             }            
  522.         }
  523.         
  524.         return y;
  525.     }
  526.  
  527.     //--------------------------------------------------------------------------
  528.     public void drawAttributes(Graphics g, Element e, int x, int y)
  529.     {
  530.         int na = e.numAttributes();
  531.         String names = new String();
  532.         String values = new String();
  533.         int height = 0;
  534.         int col1 = 0;
  535.         int col2 = 0;
  536.         if (na > 0) {
  537.             boolean first = true;
  538.             for (Enumeration ena = e.getAttributes(); ena.hasMoreElements(); ) {
  539.                 Attribute a = (Attribute)ena.nextElement();
  540.                 if( a.getName() != null && a.getName().toString().length() > 0 && a.getName().toString().charAt(0) != '_' ) {
  541.                     int w = fm.stringWidth(a.getName().toString());
  542.                     if (w > col1) col1 = w;
  543.                     String value = a.getValue().toString();
  544.                     w = fm.stringWidth(value);
  545.                     if (w > col2) col2 = w;
  546.                     // The attribute height will never change, so we just need to find it once.
  547.                     String sHeight = (String)e.getAttribute( kHeight );
  548.                     int tHeight;
  549.                     if( sHeight == null ) {  
  550.                         tHeight = (drawText(g,value,x,(y+height)+1,col2+3,true,0,true, false) - (y+height));
  551.                         e.setAttribute(kHeight, Integer.toString(tHeight));
  552.                     } else {
  553.                         tHeight = Integer.valueOf(sHeight).intValue();
  554.                     }
  555.                     height += tHeight;
  556.                     names += a.getName() + "\n";
  557.                     values += value + "\n";
  558.                 }
  559.             }
  560.         }
  561.  
  562.         if( y+height+1 > getVertLines() + getCanvasHeightLines() )
  563.         {
  564.             y = y - height - 3;  // Put the attribute above the Element rather then below
  565.         }
  566.         
  567.         if (height > 0) {
  568.             g.setColor(Color.yellow);
  569.             int w = 3+col1+6+col2+3;
  570.             int h = 3+YPOS(height)+3;
  571.             g.fillRect(x,YPOS(y-1)+fm.getMaxAscent(),w,h);
  572.             g.setColor(Color.black);
  573.             g.drawRect(x,YPOS(y-1)+fm.getMaxAscent(),w,h);
  574.             int x2 = x+3+col1+3;
  575.             g.drawLine(x2,YPOS(y-1)+fm.getMaxAscent(),x2,YPOS(y-1)+fm.getMaxAscent()+h);
  576.             x += 3;
  577.             drawText(g, names, x, y, col1 + 3, true, 0, true, true);
  578.             x += col1+6;
  579.             drawText(g, values, x, y, col2 + 3, true, 0, true, true);
  580.         }
  581.     }
  582.  
  583.     //--------------------------------------------------------------------------
  584.     public int drawText(Graphics g, String text, int x, int y, int max, 
  585.                         boolean skipWhiteSpace, int l, boolean attribute,
  586.                         boolean draw) // whether to actually draw the text
  587.     {
  588.         if( text == null || text.length() == 0 )
  589.             return y;
  590.         if (max < 5) // make sure we have room to draw text.
  591.             return y;
  592.         int i = 0;
  593.         int len;
  594.         int w = 0;
  595.  
  596.         if( l == 0 )
  597.             len = text.length();
  598.         else
  599.             len = l;
  600.         
  601.         // skip leading white space.
  602.         while (i < len && skipWhiteSpace && isWhiteSpace(text.charAt(i)))
  603.             i++;
  604.         
  605.         int j = i;
  606.         int k = i;
  607.         while (i < len) {
  608.             char ch = text.charAt(i);
  609.             int cw = fm.charWidth(ch);
  610.             w += cw;
  611.             if (w > max || ch == '\n') {
  612.                 char prev = text.charAt(i-1);
  613.                 if( ch == '\n' && prev == 0x0D )
  614.                     j = i-1;
  615.                 else if (attribute || k == j)
  616.                     j = i;
  617.                 if (draw) {
  618.                     String sub = text.substring(k,j);
  619.                     g.drawString(sub,x,YPOS(y)+fm.getMaxAscent());
  620.                 }
  621.                 y++;
  622.                 // skip white space.
  623.                 if( ch == '\n' && prev == 0x0D )
  624.                     j = i;
  625.                 if (ch == '\n')
  626.                     j++;
  627.                 while (skipWhiteSpace && j < len && isWhiteSpace(text.charAt(j)))
  628.                     j++;
  629.                 i = j;
  630.                 k = j;
  631.                 w = 0;
  632.             } else {
  633.                 if (skipWhiteSpace && isWhiteSpace(ch)) {
  634.                     j = i;
  635.                 }
  636.                 i++;
  637.             }
  638.         }
  639.         if (draw) {
  640.             String remaining = text.substring(k);
  641.             g.drawString(remaining,x,YPOS(y)+fm.getMaxAscent());
  642.         }
  643.         return y;
  644.     }
  645.  
  646.     public boolean isWhiteSpace(char ch)
  647.     {
  648.         return Character.isSpace(ch) || ch == 13 || ch == 10;
  649.     }
  650.  
  651.     public boolean isElement(Element e)
  652.     {
  653.         return e.getType() == Element.ELEMENT;
  654.             // || e.getType() == Element.ENTITY ;
  655.     }
  656.  
  657.     //--------------------------------------------------------------------------
  658.     public int findElementAt( Element e, int x, int y, int x1, int y1 )
  659.     {
  660.         if ( isElement(e) )         
  661.         {
  662.             boolean eHasChildren = (e.numElements() > 0);                
  663.             
  664.             Rectangle r = new Rectangle( x1,YPOS(y1),OVAL_SIZE,OVAL_SIZE );
  665.             int width = FOLDER_SIZE + INDENT + fm.stringWidth( e.getTagName().toString() );
  666.             Rectangle r2 = new Rectangle( x1+OVAL_SIZE+INDENT,YPOS(y1)-SPACING,
  667.                                           width, fm.getMaxAscent()+(SPACING*2));           
  668.             if( r.inside(x,y) )  // inside the check box
  669.             {
  670.                 boxClick = true;
  671.                 found = e;
  672.                 return y1;
  673.             }
  674.             if( r2.inside(x,y) )  // inside the tag
  675.             {
  676.                 boxClick = false;
  677.                 found = e;
  678.                 return y1;
  679.             }
  680.  
  681.             if( eHasChildren && e.getAttribute(kHidden) == null )
  682.             {
  683.                 // Recurse down tree
  684.                 for( Enumeration en = new SpecialEnumeration(e); en.hasMoreElements(); ) 
  685.                 {
  686.                     Element child = ( Element )en.nextElement();
  687.                     
  688.                     int y2 = findElementAt( child,x,y,x1+LEVELINDENT+INDENT,y1+1 );                
  689.                     if ( found != null )              
  690.                             return y2;
  691.                     y1 = y2;
  692.                 }
  693.             }
  694.         }
  695.         else 
  696.         {
  697.             String s = (String)e.getAttribute(kHeight);
  698.             if (s != null)
  699.                y1 += Integer.valueOf(s).intValue();
  700.         }
  701.                    
  702.         return y1;
  703.     }
  704.  
  705.     //--------------------------------------------------------------------------
  706.     public int findElementAtLine( Element e, int line, int x1, int y1 )
  707.     {
  708.         if( line == y1 )        
  709.         {                            
  710.             if ( isElement(e) )
  711.             {
  712.                 found = e;
  713.                 return y1;
  714.             }
  715.             else
  716.             {
  717.                  found = prevVisibleElement( e );
  718.                  Element temp = found;
  719.                  found = null;
  720.                  return findElement(head, temp, 15 + headX, headY);
  721.             }
  722.         }    
  723.         
  724.         if( isElement(e) )
  725.         {
  726.             if( e.numElements() > 0 && e.getAttribute(kHidden) == null ) 
  727.             {
  728.                 for( Enumeration en = new SpecialEnumeration(e); en.hasMoreElements(); ) 
  729.                 {            
  730.                     Element child = ( Element )en.nextElement();
  731.                     
  732.                     int y2 = findElementAtLine( child,line,x1+LEVELINDENT+INDENT,y1+1 );
  733.                     if ( found != null ) 
  734.                         return y2;
  735.                     y1 = y2;                                            
  736.                 }
  737.             }
  738.         }
  739.         else
  740.         {                    
  741.             String s = (String)e.getAttribute(kHeight);
  742.             if (s != null)
  743.                 y1 += Integer.valueOf(s).intValue();
  744.         }
  745.  
  746.         return y1;
  747.     }
  748.  
  749.     //--------------------------------------------------------------------------
  750.     public int findElement( Element e, Element find, int x1, int y1 )
  751.     {
  752.         if ( isElement(e) ) 
  753.         {
  754.             if( e == find )
  755.             {
  756.                found = e;
  757.                foundX = x1;
  758.                foundY = y1;
  759.                return y1;
  760.             }
  761.  
  762.             if( e.numElements() > 0 && e.getAttribute(kHidden) == null )
  763.             {
  764.                 // Recurse down the tree
  765.                 for( Enumeration en = new SpecialEnumeration(e); en.hasMoreElements(); ) 
  766.                 {
  767.                     Element child = ( Element )en.nextElement();
  768.                     
  769.                     int y2 = findElement( child,find,
  770.                                           x1+LEVELINDENT+INDENT,y1+1 );
  771.                     if ( found != null ) 
  772.                         return y2;
  773.                     y1 = y2;
  774.                 }
  775.             }
  776.         }
  777.         else 
  778.         {
  779.             String s = (String)e.getAttribute(kHeight);
  780.             if (s != null)
  781.                 y1 += Integer.valueOf(s).intValue();
  782.         }
  783.         
  784.         return y1;
  785.     }
  786.  
  787.  
  788.     //--------------------------------------------------------------------------
  789.     public boolean mouseMove(Event  evt, int  x, int  y)
  790.     {
  791.         if( viewText )
  792.             return false;
  793.  
  794.         if( x == prevX && y == prevY )
  795.             return false;
  796.         
  797.         prevX = x;
  798.         prevY = y;
  799.  
  800.         found = null;
  801.         x += (getHorz() - (BUFFER*2));
  802.         y += (getVert() - (BUFFER*2));
  803.         findElementAt( head,x,y,15 + headX, headY );
  804.         if( found != inside && inside != null ) 
  805.         {   
  806.             inside.removeAttribute( kInside );
  807.             inside = null;            
  808.             
  809.             invalidateBuffer();
  810.             repaint();
  811.         }
  812.         if( found != null ) 
  813.         {
  814.             found.setAttribute( kInside,"TRUE" );
  815.             inside = found;            
  816.  
  817.             invalidateBuffer();              
  818.             repaint();
  819.         }
  820.         return true;
  821.     }
  822.  
  823.     public boolean mouseDrag( Event  evt, int  x, int  y )
  824.     {
  825.         if( viewText )
  826.             return false;
  827.  
  828.         found = null;
  829.         x += (getHorz() - (BUFFER*2));
  830.         y += (getVert() - (BUFFER*2));
  831.         findElementAt( head,x,y,15 + headX, headY );
  832.         if( found != inside && inside != null ) 
  833.         {
  834.             // inside should be redrawNew
  835.             inside.removeAttribute(kInside);
  836.             inside = null;
  837.  
  838.             invalidateBuffer();
  839.             repaint();
  840.         }
  841.         if( found != null && found == pressed ) 
  842.         {
  843.             found.setAttribute( kInside,"TRUE" );
  844.             inside = found;
  845.  
  846.             invalidateBuffer();
  847.             repaint();
  848.         }
  849.         return true;
  850.     }
  851.  
  852.     public boolean mouseDown(Event  evt, int  x, int  y)
  853.     {
  854.         if( viewText )
  855.             return false;
  856.  
  857.         found = null;
  858.         boxClick = false;
  859.         x += (getHorz() - (BUFFER*2));
  860.         y += (getVert() - (BUFFER*2));
  861.         int foundY;
  862.         foundY = findElementAt( head,x,y,15 + headX, headY );
  863.         if( found != null ) 
  864.         {
  865.             hasFocus = true;
  866.  
  867.             if( focus != null )  // We need to remove the previous focus 
  868.             {
  869.                 focus.removeAttribute( kFocus );
  870.                 focus = null;
  871.             }
  872.             if (inside != null) 
  873.             {
  874.                 inside.removeAttribute(kInside);
  875.                 inside = null;
  876.             }
  877.  
  878.             if( evt.clickCount > 1 )
  879.             {
  880.                 setViewChoice( found );
  881.                 repaint();
  882.                 return true;
  883.             }
  884.  
  885.             if( boxClick )            
  886.             {                    
  887.                 found.setAttribute( kPressed,"TRUE" );             
  888.                 sizeChange = true;
  889.                 pressed = found;                
  890.             }                
  891.  
  892.             found.setAttribute( kFocus,"TRUE" );   
  893.             inside = found;
  894.             found.setAttribute( kInside,"TRUE" );                
  895.             focus = found;                
  896.             focusY = foundY;                            
  897.             invalidateBuffer();
  898.             repaint();
  899.         }
  900.         else if( hasFocus && focus != null )
  901.         {        
  902.             hasFocus = false;
  903.             invalidateBuffer();
  904.             repaint();
  905.         }
  906.         return true;
  907.     }
  908.  
  909.     public boolean mouseUp(Event  evt, int  x, int  y)
  910.     {
  911.         if( viewText )
  912.             return false;
  913.  
  914.         found = null;
  915.         boxClick = false;
  916.         x += (getHorz() - (BUFFER*2));
  917.         y += (getVert() - (BUFFER*2));
  918.         findElementAt( head,x,y,15 + headX, headY );
  919.         if( found == pressed && boxClick == true ) 
  920.         {
  921.             if( pressed.getAttribute(kHidden) != null ) 
  922.             {
  923.                 pressed.removeAttribute( kHidden );
  924.             } 
  925.             else  
  926.             {
  927.                 pressed.setAttribute( kHidden, "TRUE" );
  928.             }
  929.             sizeChange = true;
  930.             invalidateBuffer();
  931.             repaint();
  932.         }
  933.         if( pressed != null ) 
  934.         {
  935.             pressed.removeAttribute( kPressed );
  936.             pressed.removeAttribute( kInside );
  937.             pressed = null;
  938.             inside = null;
  939.  
  940.             invalidateBuffer();
  941.             repaint();
  942.         }       
  943.         return true;
  944.     }
  945.  
  946.     //--------------------------------------------------------------------------
  947.     public Element lastVisibleChild( Element parent )
  948.     {
  949.         boolean hasChildren = ( parent.numElements() > 0 );
  950.         if( !hasChildren || parent.getAttribute( kHidden ) != null )
  951.             return parent;
  952.       
  953.         Enumeration en = new SpecialEnumeration(parent);
  954.         Element child;
  955.         Element lastElement = null;
  956.         while( en.hasMoreElements() )
  957.         {
  958.             child = ( Element )en.nextElement();
  959.             if( isElement(child))
  960.                 lastElement = child;
  961.         }
  962.  
  963.         if( lastElement == null )
  964.             return parent;
  965.         else
  966.             return lastVisibleChild( lastElement );
  967.     }
  968.  
  969.     public Element prevVisibleElement( Element current )
  970.     {
  971.         Element parent = current.getParent();
  972.         if( parent == null )
  973.             return null;
  974.         
  975.         Element curr = null;
  976.         Element lastElement = null;
  977.         Enumeration en = new SpecialEnumeration(parent);
  978.         while( en.hasMoreElements() )
  979.         {
  980.             curr = ( Element )en.nextElement();
  981.             
  982.             if( curr == current )
  983.             {
  984.                 if( lastElement == null )
  985.                     return parent;
  986.                 else
  987.                 {
  988.                     return lastVisibleChild( lastElement );
  989.                 }
  990.             }
  991.             if( isElement(curr) ) 
  992.                 lastElement = curr;
  993.         }
  994.  
  995.         // Something went wrong...  
  996.         return null;
  997.     }
  998.  
  999.     public Element nextVisibleElement( Element current, Element original )
  1000.     {
  1001.         boolean seenOriginal = ( original == current );
  1002.         boolean hasChildren = ( current.numElements() > 0 );
  1003.         String hidden = (String)current.getAttribute( kHidden );
  1004.  
  1005.         if( hasChildren && ( hidden == null ) )
  1006.         {
  1007.             Enumeration en = new SpecialEnumeration(current);
  1008.             while( en.hasMoreElements() )
  1009.             {
  1010.                 Element child = ( Element )en.nextElement();
  1011.                 if( seenOriginal )
  1012.                 {
  1013.                     if( isElement(child) )
  1014.                     {
  1015.                         return child;
  1016.                     }
  1017.                 }
  1018.                 if( child == original )
  1019.                     seenOriginal = true;
  1020.             }
  1021.         }
  1022.         Element parent = current.getParent();
  1023.         if( parent == null )
  1024.             return null;               
  1025.         else
  1026.             return nextVisibleElement( parent, current );
  1027.     }
  1028.  
  1029.     //--------------------------------------------------------------------------
  1030.     public boolean keyDown( Event evt, int key )
  1031.     {
  1032.         if( viewText )
  1033.             return false;
  1034.  
  1035.         switch( key )                                     
  1036.         {                
  1037.         case Event.UP:                    
  1038.             {
  1039.                 if( focus == head )
  1040.                     return true;
  1041.  
  1042.                 Element newFocus = prevVisibleElement( focus );
  1043.                 if( newFocus != null && newFocus != this.d )
  1044.                 {
  1045.                     focus.removeAttribute( kFocus );
  1046.                     focus = newFocus;
  1047.  
  1048.                     // We need to reset position                    
  1049.                     found = null;
  1050.                     focusY = findElement( head, focus, 15 + headX, headY );
  1051.                     if( focusY < getVertLines() )
  1052.                     {
  1053.                         setTopLine( focusY );
  1054.                     }
  1055.                     else if( focusY >= getVertLines() + getCanvasHeightLines() )
  1056.                     {
  1057.                         setBottomLine( focusY );
  1058.                     }
  1059.  
  1060.                     focus.setAttribute( kFocus, "TRUE" );
  1061.                     hasFocus = true;
  1062.  
  1063.                     // We need to set a new inside
  1064.                     if( inside != null )
  1065.                         inside.removeAttribute( kInside );
  1066.                     inside = focus;
  1067.                     inside.setAttribute( kInside, "TRUE" );
  1068.  
  1069.                     postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null)); 
  1070.                     invalidateBuffer();
  1071.                     repaint();
  1072.                 }
  1073.             }
  1074.             return true;
  1075.         case Event.PGUP:
  1076.             {                    
  1077.                 if( focus == head )             
  1078.                     return true;
  1079.                 focus.removeAttribute( kFocus );                
  1080.                 found = null;
  1081.                 int tempY = findElementAtLine( head, getVertLines(), 15 + headX, headY );
  1082.                 if( focus == found )
  1083.                 {
  1084.                     found = null;
  1085.                     tempY = findElementAtLine( head, getVertLines() - getCanvasHeightLines(), 15 + headX, headY );
  1086.                 }
  1087.                 if( found != null && tempY > headY )
  1088.                 {
  1089.                     if( tempY >= getVertLines() + getCanvasHeightLines() )
  1090.                     {                    
  1091.                         setBottomLine( tempY );
  1092.                     }
  1093.                     else if( tempY < getVertLines() )
  1094.                     {                    
  1095.                         setTopLine( tempY );
  1096.                     }
  1097.                     focus = found;
  1098.                     focusY = tempY;
  1099.                 }
  1100.                 else // go to top of the list
  1101.                 {
  1102.                     focus = head;  // This will return first vis.
  1103.                     focusY = headY;
  1104.                     setTopLine( focusY );
  1105.                 }                    
  1106.                 focus.setAttribute( kFocus, "TRUE" );
  1107.                 hasFocus = true;
  1108.  
  1109.                 // We need to set a new inside
  1110.                 if( inside != null )
  1111.                     inside.removeAttribute( kInside );
  1112.                 inside = focus;
  1113.                 inside.setAttribute( kInside, "TRUE" );
  1114.  
  1115.                 invalidateBuffer();                
  1116.                 repaint();                                                                             
  1117.                 postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null));             
  1118.             }
  1119.             return true;
  1120.         case Event.DOWN:
  1121.             {
  1122.                 if( focus == lastVisibleChild( head ) )
  1123.                     return true;
  1124.  
  1125.                 Element newFocus = nextVisibleElement( focus, focus );                                                              
  1126.                 if( newFocus != null )
  1127.                 {
  1128.                     focus.removeAttribute( kFocus );
  1129.                     focus = newFocus;
  1130.  
  1131.                     // We need to reset position
  1132.                     found = null;
  1133.                     focusY = findElement( head, focus, 15 + headX, headY );
  1134.                     if( focusY >= getVertLines() + getCanvasHeightLines() )
  1135.                     {                    
  1136.                         setBottomLine( focusY );
  1137.                     }
  1138.                     else if( focusY < getVertLines() )
  1139.                     {                    
  1140.                         setTopLine( focusY );
  1141.                     }
  1142.  
  1143.                     focus.setAttribute( kFocus, "TRUE" );
  1144.                     hasFocus = true;
  1145.  
  1146.                     // We need to set a new inside
  1147.                     if( inside != null )
  1148.                         inside.removeAttribute( kInside );
  1149.                     inside = focus;
  1150.                     inside.setAttribute( kInside, "TRUE" );
  1151.  
  1152.                     postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null));
  1153.                     invalidateBuffer();
  1154.                     repaint();
  1155.                 }
  1156.             }
  1157.             return true;
  1158.         case Event.PGDN:                                              
  1159.             {
  1160.                 Element last = lastVisibleChild(head);
  1161.                 if( focus == last )
  1162.                     return true;
  1163.                 found = null;
  1164.                 int lastY = findElement( head, last, 15 + headX, headY );
  1165.  
  1166.                 focus.removeAttribute( kFocus );                                    
  1167.                 found = null;
  1168.                 int tmpY = findElementAtLine( head, getVertLines()+getCanvasHeightLines()-1, 15 + headX, headY );
  1169.                 if( focus == found )
  1170.                 {
  1171.                     found = null;
  1172.                     tmpY = findElementAtLine( head, getVertLines()+2*getCanvasHeightLines(), 15 + headX, headY );
  1173.                 }                
  1174.                 if( found != null && tmpY < lastY )
  1175.                 {
  1176.                     if( tmpY >= getVertLines() + getCanvasHeightLines() )
  1177.                     {                    
  1178.                         setBottomLine( tmpY );
  1179.                     }
  1180.                     else if( tmpY < getVertLines() )
  1181.                     {                    
  1182.                         setTopLine( tmpY );
  1183.                     }
  1184.                     focus = found;
  1185.                     focusY = tmpY;
  1186.                 }
  1187.                 else  // Just go to bottom of visible list
  1188.                 {
  1189.                     focus = last;
  1190.                     focusY = lastY;
  1191.                     setBottomLine( focusY );
  1192.                 }
  1193.                 focus.setAttribute( kFocus, "TRUE" );
  1194.                 hasFocus = true;
  1195.  
  1196.                 // We need to set a new inside
  1197.                 if( inside != null )
  1198.                     inside.removeAttribute( kInside );
  1199.                 inside = focus;
  1200.                 inside.setAttribute( kInside, "TRUE" );
  1201.  
  1202.                 invalidateBuffer();                
  1203.                 repaint();                                                                             
  1204.                 postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null));                         
  1205.             }
  1206.             return true;
  1207.  
  1208.         case '\n':
  1209.             setViewChoice( focus );    
  1210.             repaint();
  1211.             return true;
  1212.  
  1213.         case Event.RIGHT:        
  1214.             {
  1215.                 boolean hasChildren = ( focus.numElements() > 0 );
  1216.                 if( hasChildren )
  1217.                 {
  1218.                     if (focus.getAttribute( kHidden ) != null) 
  1219.                     {
  1220.                         keyDown( null, ' ' );
  1221.                     }
  1222.                     keyDown( null, Event.DOWN );
  1223.                 }
  1224.             }
  1225.             return true;
  1226.  
  1227.         case ' ':
  1228.             {
  1229.                 boolean hasChildren = ( focus.numElements() > 0 );
  1230.                 if(hasChildren) {
  1231.                     if (focus.getAttribute( kHidden ) == null )
  1232.                     {
  1233.                         focus.setAttribute( kHidden, "TRUE" );
  1234.                     } else {
  1235.                         focus.removeAttribute( kHidden );
  1236.                     }
  1237.                     sizeChange = true;
  1238.                     postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null));
  1239.                     invalidateBuffer();
  1240.                     repaint();
  1241.                 }
  1242.             }
  1243.             return true;
  1244.    
  1245.         case Event.LEFT:     
  1246.             {                    
  1247.                 // Otherwise do the standard left movement
  1248.                 Element parent = focus.getParent();
  1249.                 if( parent == null )
  1250.                     return true;
  1251.                 if( focus == head ) {
  1252.                     parent = head.getParent();
  1253.                     if( parent == null || parent == this.d )
  1254.                         return true;
  1255.                     setViewChoice( parent );
  1256.                     repaint();
  1257.  
  1258.                     // We need to set a new inside
  1259.                     if( inside != null )
  1260.                         inside.removeAttribute( kInside );
  1261.                     inside = focus;
  1262.                     inside.setAttribute( kInside, "TRUE" );                    
  1263.                     hasFocus = true;
  1264.                     return true;
  1265.                 }
  1266.                 focus.removeAttribute( kFocus );
  1267.                 focus = parent;
  1268.                 focus.setAttribute( kFocus, "TRUE" );
  1269.                 hasFocus = true;
  1270.  
  1271.                 // We need to reset position
  1272.                 found = null;
  1273.                 focusY = findElement( head, focus, 15 + headX, headY );
  1274.                 if( focusY < getVertLines() )
  1275.                 {
  1276.                     setTopLine( focusY );
  1277.                     sizeChange = true;
  1278.                     postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null));
  1279.                 }
  1280.                 else if( focusY >= getVertLines() + getCanvasHeightLines() )
  1281.                 {                    
  1282.                     setBottomLine( focusY );                        
  1283.                     sizeChange = true;
  1284.                     postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null));
  1285.                 }
  1286.  
  1287.                 // We need to set a new inside
  1288.                 if( inside != null )
  1289.                     inside.removeAttribute( kInside );
  1290.                 inside = focus;
  1291.                 inside.setAttribute( kInside, "TRUE" );
  1292.  
  1293.                 invalidateBuffer();
  1294.                 repaint();        
  1295.             }
  1296.             return true;
  1297.  
  1298.         case Event.HOME:
  1299.             {   
  1300.                 // Give head of list focus.
  1301.  
  1302.                 if( focus == head )             
  1303.                     return true;
  1304.  
  1305.                 focus.removeAttribute( kFocus );                
  1306.  
  1307.                 focus = head;
  1308.                 focusY = headY;                
  1309.                 setTopLine( focusY );
  1310.                 focus.setAttribute( kFocus, "TRUE" );
  1311.                 hasFocus = true;
  1312.  
  1313.                 // We need to set a new inside
  1314.                 if( inside != null )
  1315.                     inside.removeAttribute( kInside );
  1316.                 inside = focus;
  1317.                 inside.setAttribute( kInside, "TRUE" );
  1318.  
  1319.                 invalidateBuffer();                
  1320.                 repaint();                                                                             
  1321.                 postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null));             
  1322.             }
  1323.             return true;
  1324.         case Event.END:                                              
  1325.             {
  1326.                 // Give last item in list focus
  1327.  
  1328.                 Element last = lastVisibleChild(head);
  1329.                 if( focus == last )
  1330.                     return true;
  1331.                 found = null;
  1332.                 int lastY = findElement( head, last, 15 + headX, headY );
  1333.  
  1334.                 focus.removeAttribute( kFocus );                                    
  1335.  
  1336.                 focus = last;                
  1337.                 focusY = lastY;                
  1338.                 setBottomLine( focusY );
  1339.                 focus.setAttribute( kFocus, "TRUE" );
  1340.                 hasFocus = true;
  1341.  
  1342.                 // We need to set a new inside
  1343.                 if( inside != null )
  1344.                     inside.removeAttribute( kInside );
  1345.                 inside = focus;
  1346.                 inside.setAttribute( kInside, "TRUE" );
  1347.  
  1348.                 invalidateBuffer();                
  1349.                 repaint();                                                                             
  1350.                 postEvent(new Event(null, DISPLAY_SIZE_CHANGE, null));                         
  1351.             }
  1352.             return true;
  1353.         }
  1354.         
  1355.         return false;
  1356.     }
  1357.  
  1358.     public boolean action(Event  evt, Object  what)
  1359.     {
  1360.         if( evt.id == Event.ACTION_EVENT ) 
  1361.         {
  1362.             String s = (String)evt.arg;
  1363.             if (evt.target == choice ) 
  1364.             {            
  1365.                 choice.select( s );              
  1366.                 int pos = choice.getSelectedIndex();
  1367.                 Element newHead = head;
  1368.                 for( int i = choice.countItems(); i > pos+1; i-- )
  1369.                 {
  1370.                     if( newHead != null )  // This shouldn't ever be the case... but to be safe.
  1371.                           newHead = newHead.getParent();
  1372.                 }
  1373.                 if( newHead != head && newHead != null )
  1374.                 {
  1375.                      setViewChoice( newHead );
  1376.                      repaint();
  1377.                 }
  1378.             }
  1379.         }
  1380.         return false;
  1381.     }        
  1382.  
  1383.     public boolean handleEvent( Event evt )
  1384.     {
  1385.         switch( evt.id )
  1386.         {
  1387.         case Event.LOST_FOCUS:        
  1388.             {
  1389.                 if (inside != null) 
  1390.                 {
  1391.                     inside.removeAttribute( kInside );
  1392.                     inside = null;
  1393.                 }
  1394.                 hasFocus = false;
  1395.                 invalidateBuffer();
  1396.                 repaint();
  1397.             }                             
  1398.             break;
  1399.         case Event.GOT_FOCUS:        
  1400.             {
  1401.                 hasFocus = true;
  1402.                 invalidateBuffer();
  1403.                 repaint();
  1404.             }                             
  1405.             break;
  1406.         }          
  1407.  
  1408.         return super.handleEvent( evt );
  1409.     }
  1410.  
  1411.  
  1412.     Document d = new Document();
  1413.  
  1414.     Element head = null;  // the element that heads the view
  1415.     int headX, headY;
  1416.     Element pressed;      // the element that the mouse is currently pressing
  1417.     Element inside;       // the element that the mouse is over
  1418.     Element focus;        // the element with focus    
  1419.     int focusY;
  1420.     boolean hasFocus = false;  // This indicates if the focus has focus, not the window.
  1421.     Element found;
  1422.     int foundX, foundY;
  1423.  
  1424.     int prevX = 0;
  1425.     int prevY = 0;
  1426.  
  1427.     int maxWidth = 0;
  1428.  
  1429.     boolean boxClick;  // was the click on the box or on the tag
  1430.  
  1431.     int ax = 0; // position of attributes for "inside" element.
  1432.     int ay = 0;
  1433.  
  1434.     // Variables for keeping track of the tree branch drawing
  1435.     int maxBranch;
  1436.     int[] treeLines;
  1437.     int currLines;
  1438.  
  1439.     boolean viewText;
  1440.     String buffer;
  1441.  
  1442.     Choice choice;
  1443.  
  1444.     boolean sizeChange = true;
  1445.     boolean doneDraw = false;
  1446.     boolean stopDraw = false;
  1447.  
  1448.     Name kInside = Name.create("_INSIDE");
  1449.     Name kPressed = Name.create("_PRESSED");
  1450.     Name kHidden = Name.create("_HIDDEN");
  1451.     Name kFocus = Name.create("_FOCUS");
  1452.     Name kHeight = Name.create("_HEIGHT");
  1453. }
  1454.