Example #1
0
  /**
   * Calculate the minimum or preferred size of every row or column.
   *
   * @param dim the minimum or preferred size of every child
   * @param row true if row sizes should be calculated, false if column sizes should be calculated
   * @return the size required for every row or column
   */
  private int[] calculateRequiredSizes(Dimension dim[], boolean row) {
    // Build a linked list of size requirements of every child.

    LinkedList<int[]> requiredList = new LinkedList<int[]>();
    for (int i = 0; i < dim.length; i++) {
      ChildInfo info = child.get(i);
      if (row) requiredList.addLast(new int[] {info.y, info.height, dim[i].height});
      else requiredList.addLast(new int[] {info.x, info.width, dim[i].width});
    }

    // Find the required size for each row or column.

    int width[] = new int[row ? rowWeight.length : colWeight.length];
    double weight[] = (row ? rowWeight : colWeight);
    for (int currentWidth = 1; requiredList.size() > 0; currentWidth++) {
      // Apply constraints for all children which occupy currentWidth rows or columns.

      Iterator<int[]> iter = requiredList.iterator();
      while (iter.hasNext()) {
        int req[] = iter.next();
        if (req[1] != currentWidth) continue;
        iter.remove();
        if (currentWidth == 1) {
          width[req[0]] = Math.max(width[req[0]], req[2]);
          continue;
        }

        // Find how much space is currently available.

        int total = 0;
        for (int i = 0; i < currentWidth; i++) total += width[req[0] + i];
        if (total >= req[2]) continue; // It is already wide enough.

        // Allocate additional space to the rows or columns, based on their weights.

        double totalWeight = 0.0;
        for (int i = 0; i < currentWidth; i++) totalWeight += weight[req[0] + i];
        int extra[] = new int[currentWidth];
        int totalExtra = 0;
        for (int i = 0; i < currentWidth - 1; i++) {
          double w = (totalWeight > 0.0 ? weight[req[0] + i] / totalWeight : 1.0 / currentWidth);
          extra[i] += w * (req[2] - total);
          totalExtra += extra[i];
        }
        extra[extra.length - 1] = req[2] - total - totalExtra;
        for (int i = 0; i < currentWidth; i++) width[req[0] + i] += extra[i];
      }
    }
    return width;
  }