home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1996 October / PCO_10.ISO / filesbbs / clearweb.arj / CVIEW.CMP / APPLET.ZIP / Outline.class (.txt) < prev    next >
Encoding:
Java Class File  |  1996-08-15  |  13.3 KB  |  565 lines

  1. import java.awt.BorderLayout;
  2. import java.awt.Color;
  3. import java.awt.Component;
  4. import java.awt.Container;
  5. import java.awt.Dimension;
  6. import java.awt.Event;
  7. import java.awt.Graphics;
  8. import java.awt.Image;
  9. import java.awt.Panel;
  10. import java.awt.Scrollbar;
  11. import java.util.Vector;
  12.  
  13. public class Outline extends Panel {
  14.    public static final int FIRST_CHILD = 0;
  15.    public static final int LAST_CHILD = 1;
  16.    public static final int OLDER_SIBLING = 2;
  17.    public static final int YOUNGER_SIBLING = 3;
  18.    public static final int EXPAND_BOX = 0;
  19.    public static final int ICON_BOX = 1;
  20.    public static final int TEXT_BOX = 2;
  21.    public static String DEFAULT_FONT = new String("Courier");
  22.    public static int DEFAULT_FONT_SIZE = 12;
  23.    public static Color DEFAULT_BK_COLOR;
  24.    public static Color DEFAULT_FR_COLOR;
  25.    public static Color DEFAULT_SC_COLOR;
  26.    public static Color DEFAULT_SL_BK_COLOR;
  27.    public static Color DEFAULT_SL_FR_COLOR;
  28.    private static boolean IS_BROKEN_SCROLL_BAR;
  29.    OutlineOwner Owner;
  30.    OutlineNode RootNode;
  31.    int NumNodes;
  32.    Vector VisibleNodes;
  33.    OutlineNode CurrentNode;
  34.    boolean DoUpdate;
  35.    int NodeHeight;
  36.    int NodesInCanvas;
  37.    int TopNode;
  38.    int HorzShift;
  39.    private OutlineCanvas OutlinePane;
  40.    private Scrollbar VertScroll;
  41.    private Scrollbar HorzScroll;
  42.    private Thread mainThread;
  43.  
  44.    public Outline(OutlineOwner owner) {
  45.       IS_BROKEN_SCROLL_BAR = System.getProperty("os.name").indexOf("indows") != -1 && System.getProperty("java.version").compareTo("1.0.2") > 0;
  46.       this.Owner = owner;
  47.       this.RootNode = new OutlineNode(this);
  48.       this.NumNodes = 0;
  49.       this.TopNode = 0;
  50.       this.HorzShift = 0;
  51.       this.DoUpdate = true;
  52.       this.VisibleNodes = new Vector();
  53.       this.CurrentNode = null;
  54.       ((Container)this).setLayout(new BorderLayout());
  55.       this.OutlinePane = new OutlineCanvas(this);
  56.       this.VertScroll = new Scrollbar(1);
  57.       this.HorzScroll = new Scrollbar(0);
  58.       ((Container)this).add("East", this.VertScroll);
  59.       ((Container)this).add("South", this.HorzScroll);
  60.       ((Container)this).add("Center", this.OutlinePane);
  61.       this.setFont(DEFAULT_FONT, DEFAULT_FONT_SIZE);
  62.       this.setColors(DEFAULT_BK_COLOR, DEFAULT_FR_COLOR, DEFAULT_SL_BK_COLOR, DEFAULT_SL_FR_COLOR, DEFAULT_SC_COLOR);
  63.    }
  64.  
  65.    public int getNodes() {
  66.       return this.NumNodes;
  67.    }
  68.  
  69.    public int getCurrentNode() {
  70.       return this.CurrentNode == null ? -1 : this.CurrentNode.getIndex();
  71.    }
  72.  
  73.    public int getTopmostNode() {
  74.       return this.TopNode;
  75.    }
  76.  
  77.    public int getPageSize() {
  78.       return this.NodesInCanvas;
  79.    }
  80.  
  81.    public boolean setUpdating(boolean update) {
  82.       boolean temp = this.DoUpdate;
  83.       this.DoUpdate = update;
  84.       if (this.DoUpdate && !temp) {
  85.          this.OutlinePane.repaint();
  86.       }
  87.  
  88.       return temp;
  89.    }
  90.  
  91.    public void expandWholeOutline() {
  92.       ((Component)this).disable();
  93.       boolean updating = this.setUpdating(false);
  94.  
  95.       for(int i = 0; i < this.NumNodes; ++i) {
  96.          this.expandNode(i, true);
  97.       }
  98.  
  99.       ((Component)this).enable();
  100.       this.setUpdating(updating);
  101.    }
  102.  
  103.    public void clearOutline() {
  104.       for(int i = this.getFirstChild(-1); i != -1; i = this.getFirstChild(-1)) {
  105.          this.deleteNode(i);
  106.       }
  107.  
  108.    }
  109.  
  110.    public void addNode(int RelativeIdx, int relation, OutlineNodeData Data) {
  111.       if (RelativeIdx >= -1 && RelativeIdx < this.NumNodes) {
  112.          if (RelativeIdx != -1 || relation <= 1) {
  113.             OutlineNode relative = this.getNodeByIndex(RelativeIdx);
  114.             OutlineNode node = new OutlineNode(this, Data);
  115.             node.attach(relative, relation);
  116.             this.reindex();
  117.             this.createVisibleList();
  118.             this.updateOutline();
  119.          }
  120.       }
  121.    }
  122.  
  123.    public void deleteNode(int idx) {
  124.       if (idx >= 0 && idx < this.NumNodes) {
  125.          OutlineNode nd = this.getNodeByIndex(idx);
  126.          nd.detach();
  127.          nd.delete();
  128.          this.reindex();
  129.          this.createVisibleList();
  130.          this.updateOutline();
  131.       }
  132.    }
  133.  
  134.    public void expandNode(int idx, boolean expand) {
  135.       OutlineNode nd = this.getNodeByIndex(idx);
  136.       if (nd != null) {
  137.          boolean exp = nd.expanded();
  138.          if (exp != expand) {
  139.             nd.expand(expand);
  140.             if (exp != nd.expanded()) {
  141.                if (nd.expanded()) {
  142.                   this.Owner.nodeExpanded(this, idx);
  143.                } else {
  144.                   this.Owner.nodeCollapsed(this, idx);
  145.                }
  146.  
  147.                this.createVisibleList();
  148.                this.updateOutline();
  149.             }
  150.          }
  151.       }
  152.  
  153.    }
  154.  
  155.    public boolean setCurrentNode(int idx) {
  156.       OutlineNode nd = this.getNodeByIndex(idx);
  157.       if (nd == null) {
  158.          return false;
  159.       } else if (this.CurrentNode != null && this.CurrentNode.getIndex() == idx) {
  160.          return false;
  161.       } else {
  162.          this.Owner.nodeSelected(this, idx);
  163.          int visIdx = this.VisibleNodes.indexOf(nd);
  164.          if (visIdx == -1) {
  165.             this.CurrentNode = nd;
  166.             boolean updating = this.setUpdating(false);
  167.  
  168.             for(OutlineNode var6 = this.CurrentNode.ParentNode; var6.ParentNode != null; var6 = var6.ParentNode) {
  169.                var6.expand(true);
  170.             }
  171.  
  172.             this.createVisibleList();
  173.             this.adjustScrolling();
  174.             this.setUpdating(updating);
  175.          } else {
  176.             if (!this.OutlinePane.FontSet) {
  177.                this.CurrentNode = nd;
  178.                return true;
  179.             }
  180.  
  181.             Graphics g = this.OutlinePane.getGraphics();
  182.             if (g == null) {
  183.                return true;
  184.             }
  185.  
  186.             this.OutlinePane.selectColorsFonts(g);
  187.             if (this.CurrentNode != null) {
  188.                this.drawCurrent(g, this.CurrentNode.getIndex(), false);
  189.             }
  190.  
  191.             this.CurrentNode = nd;
  192.             this.drawCurrent(g, this.CurrentNode.getIndex(), true);
  193.             g.dispose();
  194.          }
  195.  
  196.          this.getCurrentNodeInCanvas();
  197.          return true;
  198.       }
  199.    }
  200.  
  201.    public void getCurrentNodeInCanvas() {
  202.       int visIdx = this.VisibleNodes.indexOf(this.CurrentNode);
  203.       if (visIdx < this.TopNode) {
  204.          this.TopNode = visIdx;
  205.       } else {
  206.          if (visIdx < this.TopNode + this.NodesInCanvas) {
  207.             return;
  208.          }
  209.  
  210.          this.TopNode = visIdx - this.NodesInCanvas + 1;
  211.          if (this.TopNode > this.VisibleNodes.size() - this.NodesInCanvas + 1) {
  212.             this.TopNode = this.VisibleNodes.size() - this.NodesInCanvas + 1;
  213.          }
  214.       }
  215.  
  216.       this.updateOutline();
  217.    }
  218.  
  219.    public boolean expanded(int idx) {
  220.       return this.getNodeByIndex(idx).expanded();
  221.    }
  222.  
  223.    public int getParent(int idx) {
  224.       return this.getNodeByIndex(idx).getParent();
  225.    }
  226.  
  227.    public int getFirstChild(int idx) {
  228.       return this.getNodeByIndex(idx).getFirstChild();
  229.    }
  230.  
  231.    public int getOlderSibling(int idx) {
  232.       return this.getNodeByIndex(idx).getOlderSibling();
  233.    }
  234.  
  235.    public int getYoungerSibling(int idx) {
  236.       return this.getNodeByIndex(idx).getYoungerSibling();
  237.    }
  238.  
  239.    public int getNodeDepth(int idx) {
  240.       return this.getNodeByIndex(idx).getDepth();
  241.    }
  242.  
  243.    public OutlineNodeData getNodeData(int idx) {
  244.       return this.getNodeByIndex(idx).getData();
  245.    }
  246.  
  247.    public void setFont(String name, int size) {
  248.       this.OutlinePane.FontName = new String(name);
  249.       this.OutlinePane.FontSize = size;
  250.       this.OutlinePane.FontSet = false;
  251.    }
  252.  
  253.    public void setColors(Color bk, Color fr, Color bksel, Color frsel, Color frsc) {
  254.       this.OutlinePane.setBackground(bk);
  255.       this.OutlinePane.backColor = new Color(bk.getRGB());
  256.       this.OutlinePane.foreColor = new Color(fr.getRGB());
  257.       this.OutlinePane.foreScColor = new Color(frsc.getRGB());
  258.       this.OutlinePane.backSelColor = new Color(bksel.getRGB());
  259.       this.OutlinePane.foreSelColor = new Color(frsel.getRGB());
  260.    }
  261.  
  262.    public void PrintOutline() {
  263.       for(int i = 0; i < this.NumNodes; ++i) {
  264.          OutlineNode node = this.getNodeByIndex(i);
  265.          System.out.println("" + node.NodeDepth + " " + node.NodeData.NodeTitle());
  266.       }
  267.  
  268.    }
  269.  
  270.    public boolean handleEvent(Event evt) {
  271.       return evt.id != 605 && evt.id != 602 && evt.id != 601 && evt.id != 604 && evt.id != 603 ? super.handleEvent(evt) : this.handleScroll(evt);
  272.    }
  273.  
  274.    private boolean handleScroll(Event evt) {
  275.       if (evt.target == this.VertScroll) {
  276.          this.TopNode = this.VertScroll.getValue();
  277.          this.repaintOutline();
  278.       }
  279.  
  280.       if (evt.target == this.HorzScroll) {
  281.          this.HorzShift = this.HorzScroll.getValue();
  282.          this.repaintOutline();
  283.       }
  284.  
  285.       return true;
  286.    }
  287.  
  288.    public void resize(int width, int height) {
  289.       super.resize(width, height);
  290.       this.updateOutline();
  291.    }
  292.  
  293.    public void resize(Dimension d) {
  294.       super.resize(d);
  295.       ((Container)this).layout();
  296.       this.repaintOutline();
  297.    }
  298.  
  299.    public void reshape(int x, int y, int width, int height) {
  300.       super.reshape(x, y, width, height);
  301.       ((Container)this).layout();
  302.       this.updateOutline();
  303.    }
  304.  
  305.    public boolean keyDown(Event evt, int key) {
  306.       if (this.CurrentNode == null) {
  307.          return true;
  308.       } else {
  309.          int visIdx = this.VisibleNodes.indexOf(this.CurrentNode);
  310.          if (key == 1005) {
  311.             if (visIdx == this.VisibleNodes.size() - 1) {
  312.                return true;
  313.             } else {
  314.                int idx = ((OutlineNode)this.VisibleNodes.elementAt(visIdx + 1)).getIndex();
  315.                this.setCurrentNode(idx);
  316.                return true;
  317.             }
  318.          } else if (key == 1004) {
  319.             if (visIdx == 0) {
  320.                return true;
  321.             } else {
  322.                int idx = ((OutlineNode)this.VisibleNodes.elementAt(visIdx - 1)).getIndex();
  323.                this.setCurrentNode(idx);
  324.                return true;
  325.             }
  326.          } else if (key != 1003 && key != 32) {
  327.             if (key != 1002 && key != 8) {
  328.                if (key == 1007) {
  329.                   if (this.HorzScroll.getValue() >= this.HorzScroll.getMaximum() - this.HorzScroll.getVisible()) {
  330.                      return true;
  331.                   } else {
  332.                      this.HorzScroll.setValue(this.HorzScroll.getValue() + 1);
  333.                      this.HorzShift = this.HorzScroll.getValue();
  334.                      this.repaintOutline();
  335.                      return true;
  336.                   }
  337.                } else if (key == 1006) {
  338.                   this.HorzScroll.setValue(this.HorzScroll.getValue() - 1);
  339.                   this.HorzShift = this.HorzScroll.getValue();
  340.                   this.repaintOutline();
  341.                   return true;
  342.                } else if (key == 43) {
  343.                   this.expandNode(this.CurrentNode.getIndex(), true);
  344.                   return true;
  345.                } else if (key == 45) {
  346.                   this.expandNode(this.CurrentNode.getIndex(), false);
  347.                   return true;
  348.                } else if (key == 10) {
  349.                   this.Owner.nodeDoubleClicked(this, this.CurrentNode.getIndex(), 2);
  350.                   return true;
  351.                } else {
  352.                   return super.keyDown(evt, key);
  353.                }
  354.             } else if (visIdx < this.NodesInCanvas) {
  355.                return true;
  356.             } else {
  357.                int idx = ((OutlineNode)this.VisibleNodes.elementAt(visIdx - this.NodesInCanvas)).getIndex();
  358.                this.setCurrentNode(idx);
  359.                return true;
  360.             }
  361.          } else if (visIdx >= this.VisibleNodes.size() - this.NodesInCanvas) {
  362.             return true;
  363.          } else {
  364.             int idx = ((OutlineNode)this.VisibleNodes.elementAt(visIdx + this.NodesInCanvas)).getIndex();
  365.             this.setCurrentNode(idx);
  366.             return true;
  367.          }
  368.       }
  369.    }
  370.  
  371.    void outlineClick(int x, int y, int numClicks) {
  372.       int idx = this.getNodeAtPos(x, y);
  373.       if (idx != -1) {
  374.          System.out.println("Click event. " + numClicks + " clicks");
  375.          if (this.setCurrentNode(idx)) {
  376.             numClicks = 1;
  377.          }
  378.  
  379.          int clickPos = x / this.NodeHeight;
  380.          clickPos += this.HorzShift;
  381.          if (clickPos == this.getNodeDepth(idx)) {
  382.             if (numClicks % 2 == 1) {
  383.                this.expandNode(idx, !this.expanded(idx));
  384.                return;
  385.             }
  386.          } else if (clickPos == this.getNodeDepth(idx) + 1) {
  387.             if (this.getNodeData(idx).NodeIcon() != null) {
  388.                if (numClicks > 1) {
  389.                   this.Owner.nodeDoubleClicked(this, idx, 1);
  390.                   return;
  391.                }
  392.  
  393.                return;
  394.             }
  395.  
  396.             if (numClicks > 1) {
  397.                this.Owner.nodeDoubleClicked(this, idx, 2);
  398.                return;
  399.             }
  400.          } else if (clickPos > this.getNodeDepth(idx) + 1 && numClicks > 1) {
  401.             this.Owner.nodeDoubleClicked(this, idx, 2);
  402.          }
  403.  
  404.       }
  405.    }
  406.  
  407.    void drawOutline(Graphics g) {
  408.       if (this.DoUpdate) {
  409.          int selIdx;
  410.          if (this.CurrentNode != null) {
  411.             selIdx = this.VisibleNodes.indexOf(this.CurrentNode);
  412.          } else {
  413.             selIdx = -1;
  414.          }
  415.  
  416.          int topIdx = this.NodesInCanvas + this.TopNode;
  417.  
  418.          for(int i = this.TopNode; i < topIdx && i < this.VisibleNodes.size(); ++i) {
  419.             this.drawNode(g, i, i == selIdx);
  420.          }
  421.  
  422.       }
  423.    }
  424.  
  425.    private void updateOutline() {
  426.       this.adjustScrolling();
  427.       this.repaintOutline();
  428.    }
  429.  
  430.    private void repaintOutline() {
  431.       if (this.DoUpdate) {
  432.          this.OutlinePane.repaint();
  433.       }
  434.  
  435.    }
  436.  
  437.    private synchronized void drawNode(Graphics g, int idx, boolean select) {
  438.       if (this.DoUpdate) {
  439.          if (idx >= this.TopNode && idx < this.TopNode + this.NodesInCanvas) {
  440.             OutlineNode nd = (OutlineNode)this.VisibleNodes.elementAt(idx);
  441.             Dimension d = new Dimension(this.OutlinePane.bounds().width, this.NodeHeight);
  442.             if (select || !nd.getData().IsSecondary()) {
  443.                nd.drawNode(g, idx - this.TopNode, d, select, this.OutlinePane.foreSelColor, this.OutlinePane.backSelColor);
  444.                return;
  445.             }
  446.  
  447.             nd.drawNode(g, idx - this.TopNode, d, true, this.OutlinePane.foreScColor, this.OutlinePane.backColor);
  448.          }
  449.  
  450.       }
  451.    }
  452.  
  453.    private void drawCurrent(Graphics g, int idx, boolean select) {
  454.       if (this.DoUpdate) {
  455.          OutlineNode nd = this.getNodeByIndex(idx);
  456.          int visIdx = this.VisibleNodes.indexOf(nd);
  457.          if (visIdx >= this.TopNode && visIdx < this.TopNode + this.NodesInCanvas) {
  458.             Dimension d = new Dimension(this.OutlinePane.bounds().width, this.NodeHeight);
  459.             if (select) {
  460.                nd.drawNode(g, visIdx - this.TopNode, d, true, this.OutlinePane.foreSelColor, this.OutlinePane.backSelColor);
  461.             } else if (nd.getData().IsSecondary()) {
  462.                nd.drawNode(g, visIdx - this.TopNode, d, true, this.OutlinePane.foreScColor, this.OutlinePane.backColor);
  463.             } else {
  464.                nd.drawNode(g, visIdx - this.TopNode, d, true, this.OutlinePane.foreColor, this.OutlinePane.backColor);
  465.             }
  466.          }
  467.       }
  468.    }
  469.  
  470.    private OutlineNode getNodeByIndex(int idx) {
  471.       return idx >= -1 && idx < this.NumNodes ? this.RootNode.getDescendantWithIndex(idx) : null;
  472.    }
  473.  
  474.    private void reindex() {
  475.       this.NumNodes = this.RootNode.reindexChildren(-1);
  476.    }
  477.  
  478.    private void createVisibleList() {
  479.       this.VisibleNodes = new Vector(this.NumNodes);
  480.       this.RootNode.getVisibleDescendants(this.VisibleNodes);
  481.       this.VisibleNodes.trimToSize();
  482.    }
  483.  
  484.    void adjustScrolling() {
  485.       int paneHeight = this.OutlinePane.bounds().height;
  486.       if (this.NodeHeight == 0) {
  487.          this.NodesInCanvas = 0;
  488.       } else {
  489.          this.NodesInCanvas = paneHeight / this.NodeHeight;
  490.       }
  491.  
  492.       if (this.VisibleNodes.size() > this.NodesInCanvas && this.NodesInCanvas != 0) {
  493.          this.VertScroll.enable();
  494.          if (this.TopNode + this.NodesInCanvas >= this.VisibleNodes.size()) {
  495.             this.TopNode = this.VisibleNodes.size() - this.NodesInCanvas;
  496.          }
  497.  
  498.          int thumbSize;
  499.          if (IS_BROKEN_SCROLL_BAR) {
  500.             thumbSize = 0;
  501.          } else {
  502.             thumbSize = this.NodesInCanvas;
  503.          }
  504.  
  505.          this.VertScroll.setValues(this.TopNode, thumbSize, 0, this.VisibleNodes.size() - this.NodesInCanvas);
  506.          this.VertScroll.setPageIncrement(this.NodesInCanvas);
  507.       } else {
  508.          this.TopNode = 0;
  509.          this.VertScroll.disable();
  510.       }
  511.  
  512.       if (this.OutlinePane.TextFontMetrics != null) {
  513.          int maxWidth = 0;
  514.  
  515.          for(int i = 0; i < this.VisibleNodes.size(); ++i) {
  516.             OutlineNode nd = (OutlineNode)this.VisibleNodes.elementAt(i);
  517.             String text = nd.getData().NodeTitle();
  518.             int width = this.OutlinePane.TextFontMetrics.stringWidth(text);
  519.             width += (nd.getDepth() + 1) * this.NodeHeight;
  520.             if (nd.getData().NodeIcon() != null) {
  521.                width += this.NodeHeight;
  522.             }
  523.  
  524.             if (width > maxWidth) {
  525.                maxWidth = width;
  526.             }
  527.          }
  528.  
  529.          if (maxWidth >= this.OutlinePane.bounds().width && this.NodeHeight != 0) {
  530.             this.HorzScroll.enable();
  531.             int scrWidth = this.OutlinePane.bounds().width / this.NodeHeight;
  532.             maxWidth /= this.NodeHeight;
  533.             int thumbSize;
  534.             if (IS_BROKEN_SCROLL_BAR) {
  535.                thumbSize = 0;
  536.             } else {
  537.                thumbSize = scrWidth;
  538.             }
  539.  
  540.             this.HorzScroll.setValues(this.HorzScroll.getValue(), thumbSize, 0, maxWidth - scrWidth);
  541.             this.HorzScroll.setPageIncrement(scrWidth);
  542.          } else {
  543.             this.HorzScroll.disable();
  544.          }
  545.       }
  546.    }
  547.  
  548.    public int getNodeAtPos(int x, int y) {
  549.       int listPos = y / this.NodeHeight + this.TopNode;
  550.       return listPos >= this.VisibleNodes.size() ? -1 : ((OutlineNode)this.VisibleNodes.elementAt(listPos)).getIndex();
  551.    }
  552.  
  553.    public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) {
  554.       return this.OutlinePane.imageUpdate(img, flags, x, y, w, h);
  555.    }
  556.  
  557.    static {
  558.       DEFAULT_BK_COLOR = Color.white;
  559.       DEFAULT_FR_COLOR = Color.black;
  560.       DEFAULT_SC_COLOR = Color.red;
  561.       DEFAULT_SL_BK_COLOR = Color.blue.darker();
  562.       DEFAULT_SL_FR_COLOR = Color.white;
  563.    }
  564. }
  565.