/**
   * Adds nodes to the specified parent node recurrsively.
   *
   * @param parent_node the parent node.
   * @param list the list of child node names.
   */
  protected void addNode(DefaultMutableTreeNode parent_node, Vector list) {
    SortableArray array = null;

    if (mode == DATE_ORIENTED && parent_node.getLevel() <= 2) {
      array = new Array(list.size());

      for (int i = 0; i < list.size(); i++)
        ((Array) array).set(i, Integer.parseInt((String) list.elementAt(i)));
    } else {
      array = new StringArray(list.size());

      for (int i = 0; i < list.size(); i++)
        ((StringArray) array).set(i, (String) list.elementAt(i));
    }

    ArrayIndex index = array.sortAscendant();

    for (int i = 0; i < array.getArraySize(); i++) {
      String name = (String) list.elementAt(index.get(i));

      // Converts 1...12 to January...December.
      if (mode == DATE_ORIENTED && parent_node.getLevel() == 1) {
        int month = Integer.parseInt(name);
        name = JulianDay.getFullSpellMonthString(month);
      }

      DefaultMutableTreeNode node = new DefaultMutableTreeNode(name);
      parent_node.add(node);
    }
  }
  /**
   * Expands the sub folders and image informations under the specified node.
   *
   * @param node the node.
   */
  protected void expandNode(DefaultMutableTreeNode node) {
    try {
      Object[] paths = node.getPath();

      String path_str = "";
      Vector folder_list = new Vector();
      for (int i = 1; i < paths.length; i++) {
        String name = (String) ((DefaultMutableTreeNode) paths[i]).getUserObject();
        path_str += "/" + name;

        // Converts January...December to 1...12.
        if (mode == DATE_ORIENTED && i == 2) {
          for (int m = 1; m <= 12; m++) {
            if (JulianDay.getFullSpellMonthString(m).equals(name)) name = String.valueOf(m);
          }
        }

        folder_list.addElement(name);
      }

      // When to expand sub folders.
      Vector folders = new Vector();
      if (mode == DATE_ORIENTED) folders = db_manager.getDateOrientedFolders(folder_list);
      if (mode == PATH_ORIENTED) folders = db_manager.getPathOrientedFolders(folder_list);
      addNode(node, folders);

      // When to expand image informations.
      XmlDBAccessor accessor = null;
      if (mode == DATE_ORIENTED) accessor = db_manager.getDateOrientedAccessor(folder_list);
      if (mode == PATH_ORIENTED) accessor = db_manager.getPathOrientedAccessor(folder_list);
      if (accessor != null) {
        Vector name_list = new Vector();
        XmlInformation info = (XmlInformation) accessor.getFirstElement();
        while (info != null) {
          name_list.addElement(info.getPath());
          hash_info.put(path_str + "/" + info.getPath(), info);
          info = (XmlInformation) accessor.getNextElement();
        }
        addNode(node, name_list);
      }

      revalidate();
      repaint();
    } catch (IOException exception) {
      String message = "Failed to read the database.";
      JOptionPane.showMessageDialog(pane, message, "Error", JOptionPane.ERROR_MESSAGE);
    }
  }
  /**
   * Gets the sortable array of the specified column.
   *
   * @param header_value the header value of the column to sort.
   */
  protected SortableArray getSortableArray(String header_value) {
    if (header_value.length() == 0) return null;

    SortableArray array = null;
    if (header_value.equals("R.A.") || header_value.equals("Decl.") || header_value.equals("ID"))
      array = new StringArray(record_list.size());
    else array = new Array(record_list.size());

    for (int i = 0; i < record_list.size(); i++) {
      String value = getCellString(header_value, i);

      if (header_value.equals("R.A.")
          || header_value.equals("Decl.")
          || header_value.equals("ID")) {
        ((StringArray) array).set(i, value);
      } else if (header_value.equals("Max Mag") || header_value.equals("Min Mag")) {
        double mag_value = 0.0;
        if ('0' <= value.charAt(0) && value.charAt(0) <= '9'
            || value.charAt(0) == '-'
            || value.charAt(0) == '+') {
          mag_value = Format.doubleValueOf(value);
        } else {
          mag_value = 100 + Format.doubleValueOf(value.substring(1));
        }
        ((Array) array).set(i, mag_value);
      } else if (header_value.equals("First Date") || header_value.equals("Last Date")) {
        double jd = 0.0;
        if (value.length() > 0) jd = JulianDay.create(value).getJD();
        ((Array) array).set(i, jd);
      } else {
        ((Array) array).set(i, Double.parseDouble(value));
      }
    }

    return array;
  }