private void initTreeUI() {
    final int adTreeId = adInfoWindowBL.getAD_Tree_ID(infoWindow);
    if (adTreeId <= 0) {
      return;
    }

    final VTreePanel treePanel = new VTreePanel(Env.getWindowNo(this), false, false);
    treePanel.setBorder(BorderFactory.createEmptyBorder(2, 3, 2, 3));

    treePanel.initTree(adTreeId);
    treePanel.addPropertyChangeListener(VTreePanel.PROPERTY_ExecuteNode, treeNodeSelectedListener);
    treePanel.setPreferredSize(new Dimension(200, treePanel.getPreferredSize().height));

    setTreePanel(treePanel, 200);
  }
  /**
   * Get where clause constructed from query fields
   *
   * @param params
   * @return
   */
  protected String getSQLWhere(final List<Object> params) {
    final StringBuilder where = new StringBuilder(); // clause form by query fields

    final List<Object> criteriasParams = new ArrayList<Object>();
    final String criteriasWhereClause = getCriteriasSQLWhere(criteriasParams);

    where.append(criteriasWhereClause);
    params.addAll(criteriasParams);

    final StringBuilder whereClause = new StringBuilder(); // general clause
    if (!Check.isEmpty(infoWindow.getOtherClause()) && where.length() > 0) {
      whereClause.append(" AND ");
    }

    // category id
    if (treeSelectedNode != null && treeSelectedNode.getNode_ID() != 0) {
      // need to iterate category and all subcategories
      if (where.length() > 0) {
        where.append(" AND ");
      }
      where.append(" ( ");
      where.append(" ").append(getTableName()).append(".");
      where.append(adInfoWindowBL.getTreeColumnName(infoWindow));
      where.append(" IN (");

      for (final int id : getSubtreeIds(treeSelectedNode)) {
        where.append(id);
        where.append(',');
      }
      // remote the last ','
      where.setLength(where.length() - 1);
      where.append(")");
      where.append(" ) ");
    }
    //
    if (where.length() > 0) {
      whereClause.append(" ( ").append(where).append(" ) ");
    }

    final int p_WindowNo = getWindowNo();
    return Env.parseContext(ctx, p_WindowNo, whereClause.toString(), false);
  }
  protected void init(
      final boolean modal,
      final int WindowNo,
      final I_AD_InfoWindow infoWindow,
      final String keyColumn,
      final String value,
      final boolean multiSelection,
      final String whereClause) {
    setCtxAttribute(ATTR_SearchText, value);

    super.init(
        modal,
        WindowNo,
        adInfoWindowBL.getTableName(infoWindow),
        keyColumn,
        multiSelection,
        whereClause);

    this.infoWindow = infoWindow;
    searchText = value;

    final I_AD_InfoWindow infoWindowTrl =
        InterfaceWrapperHelper.translate(infoWindow, I_AD_InfoWindow.class);
    setTitle(infoWindowTrl.getName());
    initAttributes();
    initParametersUI();
    initParameters();
    initInfo();
    initTree();
    initTreeUI();
    // metas begin
    // loaded OK
    p_loadedOK = true;
    // window sized to fit the preferred size and layouts of its subcomponents
    getWindow().pack();
    // metas end
  }
  private void initInfo() {
    displayedInfoColumns = adInfoWindowDAO.retrieveDisplayedColumns(infoWindow);

    final Info_Column[] layout = new Info_Column[displayedInfoColumns.size()];

    //
    // Setup Layout
    int keyColumnIndex = -1;
    for (int i = 0; i < displayedInfoColumns.size(); i++) {
      final I_AD_InfoColumn field = displayedInfoColumns.get(i);
      layout[i] = createColumnInfo(field);
      if (layout[i].getColClass() == IDColumn.class && !field.isTree()) {
        keyColumnIndex = i;
      }
    }

    // No KeyColumnIndex found. Pick the first ID column
    if (keyColumnIndex < 0) {
      int count = 0;
      for (final Info_Column infoColumn : layout) {
        if (infoColumn.isIDcol()) {
          keyColumnIndex = count;
          break;
        } else {
          count++;
        }
      }
    }

    //
    // Setup dependent columns
    // NOTE: we need to do this after we initialized the layout
    for (int i = 0; i < displayedInfoColumns.size(); i++) {
      final Info_Column infoColumn = layout[i];
      final IInfoColumnController columnController = infoColumn.getColumnController();
      if (columnController == null) {
        continue;
      }
      final List<String> dependsOnColumnNames = columnController.getDependsOnColumnNames();
      if (dependsOnColumnNames == null || dependsOnColumnNames.isEmpty()) {
        continue;
      }

      for (final String dependsOnColumnName : dependsOnColumnNames) {
        final int dependsOnColumnIndex =
            getIndexByColumnName(displayedInfoColumns, dependsOnColumnName);
        if (dependsOnColumnIndex < 0) {
          log.log(
              Level.WARNING,
              "Cannot find column name '"
                  + dependsOnColumnName
                  + "' required as dependency for "
                  + columnController);
          continue;
        }

        final List<Info_Column> dependentColumns =
            layout[dependsOnColumnIndex].getDependentColumns();
        if (!dependentColumns.contains(infoColumn)) {
          dependentColumns.add(infoColumn);
        }
      }
    }

    // Create Grid
    final StringBuffer where = new StringBuffer();
    where.append(infoWindow.getOtherClause());
    if (!Check.isEmpty(p_whereClause, true)) {
      if (!Check.isEmpty(where.toString())) {
        where.append(" AND ");
      }
      where.append("(").append(p_whereClause).append(")");
    }

    //
    final String sqlFromClause = adInfoWindowBL.getSqlFrom(infoWindow);
    prepareTable(layout, sqlFromClause, where.toString(), infoWindow.getOrderByClause());
    setKeyColumnIndex(keyColumnIndex);
    setShowTotals(adInfoWindowBL.isShowTotals(infoWindow));

    initAddonPanel();

    //
    // Notify controllers that Info window was initialized
    for (final Info_Column infoColumn : p_layout) {
      final IInfoColumnController controller = infoColumn.getColumnController();
      if (controller == null) {
        continue;
      }

      controller.afterInfoWindowInit(this);
    }
  } // initInfo