home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / VCafe / main.bin / TreeView.class (.txt) < prev    next >
Encoding:
Java Class File  |  1997-08-04  |  18.0 KB  |  914 lines

  1. package symantec.itools.awt;
  2.  
  3. import java.awt.Color;
  4. import java.awt.Component;
  5. import java.awt.Container;
  6. import java.awt.Dimension;
  7. import java.awt.Event;
  8. import java.awt.Font;
  9. import java.awt.FontMetrics;
  10. import java.awt.Graphics;
  11. import java.awt.Image;
  12. import java.awt.LayoutManager;
  13. import java.awt.Panel;
  14. import java.awt.Rectangle;
  15. import java.awt.Scrollbar;
  16. import java.util.Vector;
  17. import symantec.beans.Beans;
  18.  
  19. public strictfp class TreeView extends Panel {
  20.    public static final int CHILD = 0;
  21.    public static final int NEXT = 1;
  22.    public static final int LAST = 2;
  23.    public static final int SEL_CHANGED = 1006;
  24.    private TreeNode rootNode;
  25.    private TreeNode selectedNode;
  26.    private TreeNode topVisibleNode;
  27.    Scrollbar sbV;
  28.    int sbVPosition;
  29.    int sbVWidth;
  30.    private boolean sbVShow;
  31.    long sbVTimer;
  32.    Scrollbar sbH;
  33.    int sbHPosition;
  34.    int sbHHeight;
  35.    private int sbHSize;
  36.    private int newWidth;
  37.    private boolean sbHShow;
  38.    private int count;
  39.    private int viewCount;
  40.    private int sbHLineIncrement;
  41.    private Color bgHighlightColor;
  42.    private Color fgHighlightColor;
  43.    private int viewHeight;
  44.    private int viewWidth;
  45.    int cellSize;
  46.    int clickSize;
  47.    int imageInset;
  48.    int textInset;
  49.    int textBaseLine;
  50.    // $FF: renamed from: fm java.awt.FontMetrics
  51.    private FontMetrics field_0;
  52.    long timeMouseDown;
  53.    int doubleClickResolution;
  54.    protected boolean isSun1_1;
  55.    boolean forceRedraw;
  56.    protected Image im1;
  57.    // $FF: renamed from: g1 java.awt.Graphics
  58.    protected Graphics field_1;
  59.    // $FF: renamed from: e java.util.Vector
  60.    private Vector field_2;
  61.    // $FF: renamed from: v java.util.Vector
  62.    private Vector field_3;
  63.  
  64.    public TreeView() {
  65.       this.sbVShow = false;
  66.       this.sbVTimer = -1L;
  67.       this.sbHShow = false;
  68.       this.sbHLineIncrement = 4;
  69.       this.bgHighlightColor = Color.blue;
  70.       this.fgHighlightColor = Color.white;
  71.       this.viewHeight = 300;
  72.       this.viewWidth = 300;
  73.       this.cellSize = 16;
  74.       this.clickSize = 8;
  75.       this.imageInset = 3;
  76.       this.textInset = 6;
  77.       this.textBaseLine = 3;
  78.       this.doubleClickResolution = 333;
  79.       this.forceRedraw = false;
  80.       super.setLayout((LayoutManager)null);
  81.       this.sbV = new Scrollbar(1);
  82.       this.sbV.hide();
  83.       ((Container)this).add(this.sbV);
  84.       this.sbH = new Scrollbar(0);
  85.       this.sbH.hide();
  86.       ((Container)this).add(this.sbH);
  87.       this.isSun1_1 = System.getProperty("java.vendor").startsWith("Sun Microsystems Inc.") && (System.getProperty("java.version").startsWith("11") || System.getProperty("java.version").startsWith("1.1"));
  88.    }
  89.  
  90.    public TreeView(TreeNode head) {
  91.       this();
  92.       this.selectedNode = this.rootNode = head;
  93.       this.count = 1;
  94.    }
  95.  
  96.    public void setBackground(Color c) {
  97.       super.setBackground(c);
  98.       ((Component)this).repaint();
  99.    }
  100.  
  101.    public Color getBackground() {
  102.       return super.getBackground();
  103.    }
  104.  
  105.    public void setForeground(Color c) {
  106.       super.setForeground(c);
  107.       ((Component)this).repaint();
  108.    }
  109.  
  110.    public Color getForeground() {
  111.       return super.getForeground();
  112.    }
  113.  
  114.    public void setFgHilite(Color c) {
  115.       this.fgHighlightColor = c;
  116.       ((Component)this).repaint();
  117.    }
  118.  
  119.    public Color getFgHilite() {
  120.       return this.fgHighlightColor;
  121.    }
  122.  
  123.    public void setBgHilite(Color c) {
  124.       this.bgHighlightColor = c;
  125.       this.forceRedraw = true;
  126.       ((Component)this).repaint();
  127.    }
  128.  
  129.    public Color getBgHilite() {
  130.       return this.bgHighlightColor;
  131.    }
  132.  
  133.    public void insert(TreeNode newNode, TreeNode relativeNode, int position) {
  134.       if (newNode != null && relativeNode != null) {
  135.          if (this.exists(relativeNode)) {
  136.             switch (position) {
  137.                case 0:
  138.                   this.addChild(newNode, relativeNode);
  139.                   return;
  140.                case 1:
  141.                   this.addSibling(newNode, relativeNode, false);
  142.                   return;
  143.                case 2:
  144.                   this.addSibling(newNode, relativeNode, true);
  145.                   return;
  146.                default:
  147.             }
  148.          }
  149.       }
  150.    }
  151.  
  152.    public TreeNode getRootNode() {
  153.       return this.rootNode;
  154.    }
  155.  
  156.    public int getCount() {
  157.       return this.count;
  158.    }
  159.  
  160.    public int getViewCount() {
  161.       return this.viewCount;
  162.    }
  163.  
  164.    boolean viewable(TreeNode node) {
  165.       for(int i = 0; i < this.viewCount; ++i) {
  166.          if (node == this.field_3.elementAt(i)) {
  167.             return true;
  168.          }
  169.       }
  170.  
  171.       return false;
  172.    }
  173.  
  174.    boolean viewable(String s) {
  175.       if (s == null) {
  176.          return false;
  177.       } else {
  178.          for(int i = 0; i < this.viewCount; ++i) {
  179.             TreeNode tn = (TreeNode)this.field_3.elementAt(i);
  180.             if (tn.text != null && s.equals(tn.text)) {
  181.                return true;
  182.             }
  183.          }
  184.  
  185.          return false;
  186.       }
  187.    }
  188.  
  189.    public boolean exists(TreeNode node) {
  190.       this.recount();
  191.  
  192.       for(int i = 0; i < this.count; ++i) {
  193.          if (node == this.field_2.elementAt(i)) {
  194.             return true;
  195.          }
  196.       }
  197.  
  198.       return false;
  199.    }
  200.  
  201.    public boolean exists(String s) {
  202.       this.recount();
  203.       if (s == null) {
  204.          return false;
  205.       } else {
  206.          for(int i = 0; i < this.count; ++i) {
  207.             TreeNode tn = (TreeNode)this.field_2.elementAt(i);
  208.             if (tn.text != null && s.equals(tn.text)) {
  209.                return true;
  210.             }
  211.          }
  212.  
  213.          return false;
  214.       }
  215.    }
  216.  
  217.    public void append(TreeNode newNode) {
  218.       if (this.rootNode == null) {
  219.          this.rootNode = newNode;
  220.          this.selectedNode = this.rootNode;
  221.          this.count = 1;
  222.          this.forceRedraw = true;
  223.       } else {
  224.          this.addSibling(newNode, this.rootNode, true);
  225.       }
  226.    }
  227.  
  228.    void addChild(TreeNode newNode, TreeNode relativeNode) {
  229.       if (relativeNode.child == null) {
  230.          relativeNode.child = newNode;
  231.          newNode.parent = relativeNode;
  232.          ++this.count;
  233.          this.forceRedraw = true;
  234.       } else {
  235.          this.addSibling(newNode, relativeNode.child, true);
  236.       }
  237.  
  238.       ++relativeNode.numberOfChildren;
  239.    }
  240.  
  241.    void addSibling(TreeNode newNode, TreeNode siblingNode) {
  242.       this.addSibling(newNode, siblingNode, true);
  243.    }
  244.  
  245.    void addSibling(TreeNode newNode, TreeNode siblingNode, boolean asLastSibling) {
  246.       if (asLastSibling) {
  247.          TreeNode tempNode;
  248.          for(tempNode = siblingNode; tempNode.sibling != null; tempNode = tempNode.sibling) {
  249.          }
  250.  
  251.          tempNode.sibling = newNode;
  252.       } else {
  253.          newNode.sibling = siblingNode.sibling;
  254.          siblingNode.sibling = newNode;
  255.       }
  256.  
  257.       newNode.parent = siblingNode.parent;
  258.       ++this.count;
  259.       this.forceRedraw = true;
  260.    }
  261.  
  262.    public TreeNode remove(String s) {
  263.       this.recount();
  264.  
  265.       for(int i = 0; i < this.count; ++i) {
  266.          TreeNode tn = (TreeNode)this.field_2.elementAt(i);
  267.          if (tn.text != null && s.equals(tn.text)) {
  268.             this.remove(tn);
  269.             this.forceRedraw = true;
  270.             return tn;
  271.          }
  272.       }
  273.  
  274.       return null;
  275.    }
  276.  
  277.    public void removeSelected() {
  278.       if (this.selectedNode != null) {
  279.          this.remove(this.selectedNode);
  280.       }
  281.  
  282.    }
  283.  
  284.    public void remove(TreeNode node) {
  285.       if (this.exists(node)) {
  286.          if (node == this.selectedNode) {
  287.             int index = this.field_3.indexOf(this.selectedNode);
  288.             if (index == -1) {
  289.                index = this.field_2.indexOf(this.selectedNode);
  290.             }
  291.  
  292.             if (index > this.viewCount - 1) {
  293.                index = this.viewCount - 1;
  294.             }
  295.  
  296.             if (index > 0) {
  297.                this.changeSelection((TreeNode)this.field_3.elementAt(index - 1));
  298.             } else if (this.viewCount > 1) {
  299.                this.changeSelection((TreeNode)this.field_3.elementAt(1));
  300.             }
  301.          }
  302.  
  303.          if (node.parent != null) {
  304.             if (node.parent.child == node) {
  305.                if (node.sibling != null) {
  306.                   node.parent.child = node.sibling;
  307.                } else {
  308.                   node.parent.child = null;
  309.                   node.parent.collapse();
  310.                }
  311.             } else {
  312.                TreeNode tn;
  313.                for(tn = node.parent.child; tn.sibling != node; tn = tn.sibling) {
  314.                }
  315.  
  316.                if (node.sibling != null) {
  317.                   tn.sibling = node.sibling;
  318.                } else {
  319.                   tn.sibling = null;
  320.                }
  321.             }
  322.          } else if (node == this.rootNode) {
  323.             if (node.sibling == null) {
  324.                this.rootNode = null;
  325.             } else {
  326.                this.rootNode = node.sibling;
  327.             }
  328.          } else {
  329.             TreeNode tn;
  330.             for(tn = this.rootNode; tn.sibling != node; tn = tn.sibling) {
  331.             }
  332.  
  333.             if (node.sibling != null) {
  334.                tn.sibling = node.sibling;
  335.             } else {
  336.                tn.sibling = null;
  337.             }
  338.          }
  339.  
  340.          this.recount();
  341.          this.forceRedraw = true;
  342.       }
  343.    }
  344.  
  345.    public void printTree(TreeNode node) {
  346.       if (node != null) {
  347.          System.out.println(node.text);
  348.          this.printTree(node.child);
  349.          this.printTree(node.sibling);
  350.       }
  351.    }
  352.  
  353.    private void recount() {
  354.       this.count = 0;
  355.       this.field_2 = new Vector();
  356.       if (this.rootNode != null) {
  357.          this.rootNode.depth = 0;
  358.          this.traverse(this.rootNode);
  359.       }
  360.  
  361.    }
  362.  
  363.    private void traverse(TreeNode node) {
  364.       ++this.count;
  365.       this.field_2.addElement(node);
  366.       if (node.child != null) {
  367.          node.child.depth = node.depth + 1;
  368.          this.traverse(node.child);
  369.       }
  370.  
  371.       if (node.sibling != null) {
  372.          node.sibling.depth = node.depth;
  373.          this.traverse(node.sibling);
  374.       }
  375.  
  376.    }
  377.  
  378.    private void resetVector() {
  379.       this.field_3 = new Vector(this.count);
  380.       if (this.count < 1) {
  381.          this.viewCount = 0;
  382.       } else {
  383.          this.rootNode.depth = 0;
  384.          this.vectorize(this.rootNode, true, this.field_3);
  385.          this.viewCount = this.field_3.size();
  386.       }
  387.    }
  388.  
  389.    private void vectorize(TreeNode node, boolean respectExpanded, Vector nodeVector) {
  390.       if (node != null) {
  391.          nodeVector.addElement(node);
  392.          if (!respectExpanded && node.child != null || node.isExpanded()) {
  393.             node.child.depth = node.depth + 1;
  394.             this.vectorize(node.child, respectExpanded, nodeVector);
  395.          }
  396.  
  397.          if (node.sibling != null) {
  398.             node.sibling.depth = node.depth;
  399.             this.vectorize(node.sibling, respectExpanded, nodeVector);
  400.          }
  401.  
  402.       }
  403.    }
  404.  
  405.    private void debugVector() {
  406.       this.field_3.size();
  407.  
  408.       for(int i = 0; i < this.count; ++i) {
  409.          TreeNode node = (TreeNode)this.field_3.elementAt(i);
  410.          System.out.println(node.text);
  411.       }
  412.  
  413.    }
  414.  
  415.    public boolean handleEvent(Event e) {
  416.       if (e.target == this.sbV && e.arg != null && this.sbVPosition != this.sbV.getValue()) {
  417.          this.sbVPosition = this.sbV.getValue();
  418.          this.forceRedraw = true;
  419.          ((Component)this).repaint();
  420.       }
  421.  
  422.       if (e.target == this.sbH && e.arg != null && this.sbHPosition != this.sbH.getValue()) {
  423.          this.sbHPosition = this.sbH.getValue();
  424.          ((Component)this).repaint();
  425.       }
  426.  
  427.       return (e.target == this.sbV || e.target == this.sbH) && e.id == 501 ? true : super.handleEvent(e);
  428.    }
  429.  
  430.    public boolean mouseDown(Event event, int x, int y) {
  431.       ((Component)this).requestFocus();
  432.       int index = y / this.cellSize + this.sbVPosition;
  433.       if (index > this.viewCount - 1) {
  434.          return false;
  435.       } else {
  436.          TreeNode oldNode = this.selectedNode;
  437.          TreeNode newNode = (TreeNode)this.field_3.elementAt(index);
  438.          int newDepth = newNode.getDepth();
  439.          this.changeSelection(newNode);
  440.          Rectangle toggleBox = new Rectangle(this.cellSize * newDepth + this.cellSize / 4, (index - this.sbVPosition) * this.cellSize + this.clickSize / 2, this.clickSize, this.clickSize);
  441.          if (toggleBox.inside(x + this.sbHPosition, y)) {
  442.             newNode.toggle();
  443.             this.sendActionEvent(event);
  444.             this.forceRedraw = true;
  445.             ((Component)this).repaint();
  446.          } else {
  447.             if (newNode == oldNode && event.when - this.timeMouseDown < (long)this.doubleClickResolution) {
  448.                newNode.toggle();
  449.                this.sendActionEvent(event);
  450.                this.forceRedraw = true;
  451.                ((Component)this).repaint();
  452.                return false;
  453.             }
  454.  
  455.             this.timeMouseDown = event.when;
  456.          }
  457.  
  458.          return true;
  459.       }
  460.    }
  461.  
  462.    public boolean keyDown(Event event, int key) {
  463.       int index = this.field_3.indexOf(this.selectedNode);
  464.       switch (key) {
  465.          case 10:
  466.          case 13:
  467.             this.sendActionEvent(event);
  468.             ((Component)this).requestFocus();
  469.             break;
  470.          case 1006:
  471.             if (event.modifiers == 2) {
  472.                if (this.sbHPosition > 0) {
  473.                   this.sbH.setValue(Math.max(this.sbHPosition -= this.sbHLineIncrement, 0));
  474.                   ((Component)this).repaint();
  475.                }
  476.                break;
  477.             } else if (this.selectedNode.isExpanded()) {
  478.                this.selectedNode.toggle();
  479.                this.forceRedraw = true;
  480.                ((Component)this).repaint();
  481.                break;
  482.             }
  483.          case 1004:
  484.             if (index > 0) {
  485.                --index;
  486.                this.changeSelection((TreeNode)this.field_3.elementAt(index));
  487.                ((Component)this).requestFocus();
  488.             }
  489.             break;
  490.          case 1007:
  491.             if (event.modifiers == 2) {
  492.                int max = this.sbH.getMaximum() - (this.isSun1_1 ? ((Component)this).size().width - this.sbVWidth : 0);
  493.                if (this.sbHShow && this.sbHPosition < max) {
  494.                   this.sbH.setValue(Math.min(this.sbHPosition += this.sbHLineIncrement, max));
  495.                   ((Component)this).repaint();
  496.                }
  497.                break;
  498.             } else if (this.selectedNode.isExpandable() && !this.selectedNode.isExpanded()) {
  499.                this.selectedNode.toggle();
  500.                this.sendActionEvent(event);
  501.                this.forceRedraw = true;
  502.                ((Component)this).repaint();
  503.                break;
  504.             } else if (!this.selectedNode.isExpandable()) {
  505.                break;
  506.             }
  507.          case 1005:
  508.             if (index < this.viewCount - 1) {
  509.                ++index;
  510.                this.changeSelection((TreeNode)this.field_3.elementAt(index));
  511.                ((Component)this).requestFocus();
  512.             }
  513.       }
  514.  
  515.       return false;
  516.    }
  517.  
  518.    private void sendActionEvent(Event event) {
  519.       int id = event.id;
  520.       Object arg = event.arg;
  521.       event.id = 1001;
  522.       event.arg = new String(this.selectedNode.getText());
  523.       ((Component)this).postEvent(event);
  524.       event.id = id;
  525.       event.arg = arg;
  526.    }
  527.  
  528.    public TreeNode getSelectedNode() {
  529.       return this.selectedNode;
  530.    }
  531.  
  532.    public String getSelectedText() {
  533.       return this.selectedNode == null ? null : this.selectedNode.getText();
  534.    }
  535.  
  536.    private void changeSelection(TreeNode node) {
  537.       if (node != this.selectedNode) {
  538.          TreeNode oldNode = this.selectedNode;
  539.          this.selectedNode = node;
  540.          this.drawNodeText(oldNode, (this.field_3.indexOf(oldNode) - this.sbVPosition) * this.cellSize, true);
  541.          this.drawNodeText(node, (this.field_3.indexOf(node) - this.sbVPosition) * this.cellSize, true);
  542.          int index = this.field_3.indexOf(this.selectedNode);
  543.          ((Component)this).postEvent(new Event(this, 1006, this.selectedNode));
  544.          if (index < this.sbVPosition) {
  545.             --this.sbVPosition;
  546.             this.sbV.setValue(this.sbVPosition);
  547.             this.forceRedraw = true;
  548.             ((Component)this).repaint();
  549.          } else if (index >= this.sbVPosition + (this.viewHeight - this.sbHHeight) / this.cellSize) {
  550.             ++this.sbVPosition;
  551.             this.sbV.setValue(this.sbVPosition);
  552.             this.forceRedraw = true;
  553.             ((Component)this).repaint();
  554.          } else {
  555.             ((Component)this).repaint();
  556.          }
  557.       }
  558.    }
  559.  
  560.    public void update(Graphics g) {
  561.       this.paint(g);
  562.    }
  563.  
  564.    public void paint(Graphics g) {
  565.       Dimension s = ((Component)this).size();
  566.       if (s.width == this.viewWidth && s.height == this.viewHeight && !this.forceRedraw) {
  567.          if (Beans.isDesignTime()) {
  568.             this.resetVector();
  569.             this.newWidth = this.compWidth(g);
  570.             this.drawTree();
  571.          }
  572.       } else {
  573.          this.redraw(g);
  574.       }
  575.  
  576.       g.translate(-this.sbHPosition, 0);
  577.       g.clearRect(this.sbHPosition, 0, s.width - this.sbVWidth, s.height - this.sbHHeight);
  578.       if (this.sbVShow && this.sbHShow) {
  579.          g.setColor(Color.lightGray);
  580.          g.fillRect(this.sbHPosition + s.width - this.sbVWidth, s.height - this.sbHHeight, this.sbVWidth, this.sbHHeight);
  581.       }
  582.  
  583.       g.clipRect(this.sbHPosition, 0, s.width - this.sbVWidth, s.height - this.sbHHeight);
  584.       g.drawImage(this.im1, 0, 0, this);
  585.       g.setColor(Color.black);
  586.       g.drawRect(this.sbHPosition, 0, s.width - this.sbVWidth - 1, s.height - this.sbHHeight - 1);
  587.    }
  588.  
  589.    public void redraw() {
  590.       this.forceRedraw = true;
  591.       ((Component)this).repaint();
  592.    }
  593.  
  594.    private void redraw(Graphics g) {
  595.       Dimension s = ((Component)this).size();
  596.       this.forceRedraw = false;
  597.       this.resetVector();
  598.       this.newWidth = this.compWidth(g);
  599.       int inRectCount = (s.height - this.sbHHeight) / this.cellSize;
  600.       if (this.viewCount > inRectCount) {
  601.          this.sbVShow = true;
  602.          this.sbVWidth = this.sbV.preferredSize().width;
  603.       } else {
  604.          this.sbVShow = false;
  605.          this.sbVWidth = 0;
  606.          this.sbVPosition = 0;
  607.       }
  608.  
  609.       if (this.newWidth > s.width - this.sbVWidth) {
  610.          this.sbHShow = true;
  611.          this.sbHHeight = this.sbH.preferredSize().height;
  612.       } else {
  613.          this.sbHShow = false;
  614.          this.sbHHeight = 0;
  615.          this.sbHPosition = 0;
  616.       }
  617.  
  618.       this.drawTree();
  619.       if (this.sbVShow) {
  620.          this.sbV.reshape(s.width - this.sbVWidth, 0, this.sbVWidth, s.height - this.sbHHeight);
  621.          this.sbV.setValues(this.sbVPosition, inRectCount, 0, this.viewCount - (this.isSun1_1 ? 0 : inRectCount));
  622.          this.sbV.setPageIncrement(inRectCount - 1);
  623.          this.sbV.show();
  624.       } else {
  625.          this.sbV.hide();
  626.       }
  627.  
  628.       if (this.sbHShow) {
  629.          this.sbH.reshape(0, s.height - this.sbHHeight, s.width - this.sbVWidth, this.sbHHeight);
  630.          this.sbH.setValues(this.sbHPosition, s.width - this.sbVWidth, 0, this.sbHSize - (this.isSun1_1 ? 0 : s.width - this.sbVWidth));
  631.          this.sbH.setPageIncrement(s.width - this.sbVWidth);
  632.          this.sbH.setLineIncrement(this.sbHLineIncrement);
  633.          this.sbH.show();
  634.       } else {
  635.          this.sbH.hide();
  636.       }
  637.    }
  638.  
  639.    private int compWidth(Graphics gg) {
  640.       int size = 0;
  641.       Font f = ((Component)this).getFont();
  642.       if (f == null) {
  643.          f = new Font("TimesRoman", 0, 13);
  644.          gg.setFont(f);
  645.          ((Component)this).setFont(f);
  646.       }
  647.  
  648.       this.field_0 = gg.getFontMetrics();
  649.  
  650.       for(int i = 0; i < this.field_3.size(); ++i) {
  651.          TreeNode node = (TreeNode)this.field_3.elementAt(i);
  652.          int textOffset = (node.depth + 1) * this.cellSize + this.cellSize + this.textInset - (node.getImage() == null ? 12 : 0);
  653.          if (size < textOffset + this.field_0.stringWidth(node.text) + 6) {
  654.             size = textOffset + this.field_0.stringWidth(node.text) + 6;
  655.          }
  656.       }
  657.  
  658.       return size;
  659.    }
  660.  
  661.    public void drawTree() {
  662.       Dimension d = ((Component)this).size();
  663.       int lastOne = this.sbVPosition + (d.height - this.sbHHeight) / this.cellSize + 1;
  664.       if (lastOne > this.viewCount) {
  665.          lastOne = this.viewCount;
  666.       }
  667.  
  668.       if (d.width != this.viewWidth || d.height != this.viewHeight || this.field_1 == null || this.sbHSize != this.newWidth) {
  669.          this.im1 = ((Component)this).createImage(Math.max(this.sbHSize = this.newWidth, d.width), d.height);
  670.          if (this.field_1 != null) {
  671.             this.field_1.dispose();
  672.          }
  673.  
  674.          this.field_1 = this.im1.getGraphics();
  675.          this.viewWidth = d.width;
  676.          this.viewHeight = d.height;
  677.       }
  678.  
  679.       Font f = ((Component)this).getFont();
  680.       if (f == null) {
  681.          f = new Font("TimesRoman", 0, 13);
  682.          ((Component)this).setFont(f);
  683.       }
  684.  
  685.       if (f != null && this.field_1.getFont() == null) {
  686.          this.field_1.setFont(f);
  687.       }
  688.  
  689.       this.field_0 = this.field_1.getFontMetrics();
  690.       this.field_1.setColor(this.getBackground());
  691.       this.field_1.fillRect(0, 0, this.im1.getWidth(this), d.height);
  692.       TreeNode outerNode = null;
  693.       if (!this.field_3.isEmpty()) {
  694.          outerNode = (TreeNode)this.field_3.elementAt(this.sbVPosition);
  695.       }
  696.  
  697.       for(int i = this.sbVPosition; i < lastOne; ++i) {
  698.          TreeNode node = (TreeNode)this.field_3.elementAt(i);
  699.          int x = this.cellSize * (node.depth + 1);
  700.          int y = (i - this.sbVPosition) * this.cellSize;
  701.          this.field_1.setColor(this.getForeground());
  702.          if (node.sibling != null) {
  703.             int k = this.field_3.indexOf(node.sibling) - i;
  704.             if (k > lastOne) {
  705.                k = lastOne;
  706.             }
  707.  
  708.             this.drawDotLine(x - this.cellSize / 2, y + this.cellSize / 2, x - this.cellSize / 2, y + this.cellSize / 2 + k * this.cellSize);
  709.          }
  710.  
  711.          for(int m = 0; m < i; ++m) {
  712.             TreeNode sib = (TreeNode)this.field_3.elementAt(m);
  713.             if (sib.sibling == node && m < this.sbVPosition) {
  714.                this.drawDotLine(x - this.cellSize / 2, 0, x - this.cellSize / 2, y + this.cellSize / 2);
  715.             }
  716.          }
  717.  
  718.          if (node.isExpanded()) {
  719.             this.drawDotLine(x + this.cellSize / 2, y + this.cellSize - 2, x + this.cellSize / 2, y + this.cellSize + this.cellSize / 2);
  720.          }
  721.  
  722.          this.field_1.setColor(this.getForeground());
  723.          this.drawDotLine(x - this.cellSize / 2, y + this.cellSize / 2, x + this.cellSize / 2, y + this.cellSize / 2);
  724.          if (node.isExpandable()) {
  725.             this.field_1.setColor(this.getBackground());
  726.             this.field_1.fillRect(this.cellSize * node.depth + this.cellSize / 4, y + this.clickSize / 2, this.clickSize, this.clickSize);
  727.             this.field_1.setColor(this.getForeground());
  728.             this.field_1.drawRect(this.cellSize * node.depth + this.cellSize / 4, y + this.clickSize / 2, this.clickSize, this.clickSize);
  729.             this.field_1.drawLine(this.cellSize * node.depth + this.cellSize / 4 + 2, y + this.cellSize / 2, this.cellSize * node.depth + this.cellSize / 4 + this.clickSize - 2, y + this.cellSize / 2);
  730.             if (!node.isExpanded()) {
  731.                this.field_1.drawLine(this.cellSize * node.depth + this.cellSize / 2, y + this.clickSize / 2 + 2, this.cellSize * node.depth + this.cellSize / 2, y + this.clickSize / 2 + this.clickSize - 2);
  732.             }
  733.          }
  734.  
  735.          Image nodeImage = node.getImage();
  736.          if (nodeImage != null) {
  737.             this.field_1.drawImage(nodeImage, x + this.imageInset, y, this);
  738.          }
  739.  
  740.          if (node.text != null) {
  741.             this.drawNodeText(node, y, node == this.selectedNode);
  742.          }
  743.  
  744.          if (outerNode.depth > node.depth) {
  745.             outerNode = node;
  746.          }
  747.       }
  748.  
  749.       if (outerNode != null) {
  750.          while((outerNode = outerNode.parent) != null) {
  751.             if (outerNode.sibling != null) {
  752.                this.drawDotLine(this.cellSize * (outerNode.depth + 1) - this.cellSize / 2, 0, this.cellSize * (outerNode.depth + 1) - this.cellSize / 2, d.height);
  753.             }
  754.          }
  755.       }
  756.  
  757.    }
  758.  
  759.    private void drawNodeText(TreeNode node, int yPosition, boolean eraseBackground) {
  760.       int depth = node.depth;
  761.       Image nodeImage = node.getImage();
  762.       int textOffset = (depth + 1) * this.cellSize + this.cellSize + this.textInset - (nodeImage == null ? 12 : 0);
  763.       Color fg;
  764.       Color bg;
  765.       if (node == this.selectedNode) {
  766.          fg = this.fgHighlightColor;
  767.          bg = this.bgHighlightColor;
  768.       } else {
  769.          fg = this.getForeground();
  770.          bg = this.getBackground();
  771.       }
  772.  
  773.       if (eraseBackground) {
  774.          this.field_1.setColor(bg);
  775.          this.field_1.fillRect(textOffset - 1, yPosition + 1, this.field_0.stringWidth(node.text) + 4, this.cellSize - 1);
  776.       }
  777.  
  778.       this.field_1.setColor(fg);
  779.       this.field_1.drawString(node.text, textOffset, yPosition + this.cellSize - this.textBaseLine);
  780.    }
  781.  
  782.    private void drawDotLine(int x0, int y0, int x1, int y1) {
  783.       if (y0 == y1) {
  784.          for(int i = x0; i < x1; i += 2) {
  785.             this.field_1.drawLine(i, y0, i, y1);
  786.          }
  787.  
  788.       } else {
  789.          for(int i = y0; i < y1; i += 2) {
  790.             this.field_1.drawLine(x0, i, x1, i);
  791.          }
  792.  
  793.       }
  794.    }
  795.  
  796.    public void setTreeStructure(String[] s) {
  797.       this.rootNode = this.selectedNode = null;
  798.  
  799.       try {
  800.          this.parseTreeStructure(s);
  801.       } catch (InvalidTreeNodeException e) {
  802.          System.out.println(e);
  803.       }
  804.  
  805.       this.forceRedraw = true;
  806.       ((Component)this).repaint();
  807.    }
  808.  
  809.    public String[] getTreeStructure() {
  810.       if (this.rootNode == null) {
  811.          return null;
  812.       } else {
  813.          Vector nodesVector = new Vector(this.count);
  814.          this.rootNode.depth = 0;
  815.          this.vectorize(this.rootNode, false, nodesVector);
  816.          int numNodes = nodesVector.size();
  817.          String[] treeStructure = new String[numNodes];
  818.  
  819.          for(int i = 0; i < numNodes; ++i) {
  820.             TreeNode thisNode = (TreeNode)nodesVector.elementAt(i);
  821.             String treeString = "";
  822.  
  823.             for(int numBlanks = 0; numBlanks < thisNode.depth; ++numBlanks) {
  824.                treeString = treeString + ' ';
  825.             }
  826.  
  827.             treeString = treeString + thisNode.text;
  828.             treeStructure[i] = treeString;
  829.          }
  830.  
  831.          return treeStructure;
  832.       }
  833.    }
  834.  
  835.    private void parseTreeStructure(String[] tempStructure) throws InvalidTreeNodeException {
  836.       for(int i = 0; i < tempStructure.length; ++i) {
  837.          String entry = tempStructure[i];
  838.          int indentLevel = this.findLastPreSpace(entry);
  839.          if (indentLevel == -1) {
  840.             throw new InvalidTreeNodeException();
  841.          }
  842.  
  843.          if (this.rootNode == null) {
  844.             if (indentLevel != 0) {
  845.                throw new InvalidTreeNodeException();
  846.             }
  847.  
  848.             TreeNode node = new TreeNode(entry.trim());
  849.             node.setDepth(indentLevel);
  850.             this.append(node);
  851.          } else {
  852.             TreeNode currentNode;
  853.             for(currentNode = this.rootNode; currentNode.sibling != null; currentNode = currentNode.sibling) {
  854.             }
  855.  
  856.             for(int j = 1; j < indentLevel; ++j) {
  857.                int numberOfChildren = currentNode.numberOfChildren;
  858.                TreeNode tempNode = null;
  859.                if (numberOfChildren > 0) {
  860.                   for(tempNode = currentNode.child; tempNode.sibling != null; tempNode = tempNode.sibling) {
  861.                   }
  862.                }
  863.  
  864.                if (tempNode == null) {
  865.                   break;
  866.                }
  867.  
  868.                currentNode = tempNode;
  869.             }
  870.  
  871.             int diff = indentLevel - currentNode.getDepth();
  872.             if (diff > 1) {
  873.                throw new InvalidTreeNodeException();
  874.             }
  875.  
  876.             TreeNode node = new TreeNode(entry.trim());
  877.             node.setDepth(indentLevel);
  878.             if (diff == 1) {
  879.                this.insert(node, currentNode, 0);
  880.             } else {
  881.                this.insert(node, currentNode, 1);
  882.             }
  883.          }
  884.       }
  885.  
  886.    }
  887.  
  888.    private int findLastPreSpace(String s) {
  889.       int length = s.length();
  890.       if (s.charAt(0) != ' ' && s.charAt(0) != '\t') {
  891.          return 0;
  892.       } else {
  893.          for(int i = 1; i < length; ++i) {
  894.             if (s.charAt(i) != ' ' && s.charAt(i) != '\t') {
  895.                return i;
  896.             }
  897.          }
  898.  
  899.          return -1;
  900.       }
  901.    }
  902.  
  903.    public synchronized Dimension preferredSize() {
  904.       return new Dimension(175, 125);
  905.    }
  906.  
  907.    public synchronized Dimension minimumSize() {
  908.       return new Dimension(50, 50);
  909.    }
  910.  
  911.    public void setLayout(LayoutManager lm) {
  912.    }
  913. }
  914.