private int[] getMinOrPrefSizes(DimensionInfo info, boolean min) {
    int[] widths = new int[info.getCellCount()];

    int toProcess;
    for (toProcess = 0; toProcess < widths.length; ++toProcess) {
      widths[toProcess] = this.myMinCellSize;
    }

    for (toProcess = info.getComponentCount() - 1; toProcess >= 0; --toProcess) {
      if (info.getSpan(toProcess) == 1) {
        int i =
            min
                ? getMin2(info, toProcess)
                : Math.max(info.getMinimumWidth(toProcess), info.getPreferredWidth(toProcess));
        int size = info.getCell(toProcess);
        int span = countGap(info, size, info.getSpan(toProcess));
        i = Math.max(i - span, 0);
        widths[size] = Math.max(widths[size], i);
      }
    }

    updateSizesFromChildren(info, min, widths);
    boolean[] priority = new boolean[info.getCellCount()];
    for (int i = info.getComponentCount() - 1; i >= 0; --i) {
      int size =
          min ? getMin2(info, i) : Math.max(info.getMinimumWidth(i), info.getPreferredWidth(i));
      int span = info.getSpan(i);
      int cell = info.getCell(i);
      int gap = countGap(info, cell, span);
      size = Math.max(size - gap, 0);
      Arrays.fill(priority, false);
      int curSize = 0;

      for (int higherPriorityCells = 0; higherPriorityCells < span; ++higherPriorityCells) {
        curSize += widths[higherPriorityCells + cell];
        priority[higherPriorityCells + cell] = true;
      }

      if (curSize < size) {
        boolean[] higherPriorityCells = new boolean[priority.length];
        this.getCellsWithHigherPriorities(info, priority, higherPriorityCells, false, widths);
        distribute(higherPriorityCells, info, size - curSize, widths);
      }
    }

    return widths;
  }
  private static boolean isCellEmpty(DimensionInfo info, int cellIndex) {
    if (cellIndex >= 0 && cellIndex < info.getCellCount()) {
      for (int i = 0; i < info.getComponentCount(); ++i) {
        Component component = info.getComponent(i);
        if (info.getCell(i) == cellIndex && !(component instanceof Spacer)) {
          return false;
        }
      }

      return true;
    } else {
      throw new IllegalArgumentException(
          "wrong cellIndex: " + cellIndex + "; cellCount=" + info.getCellCount());
    }
  }
 private static void updateSizesFromChildren(DimensionInfo info, boolean min, int[] widths) {
   for (int i = info.getComponentCount() - 1; i >= 0; --i) {
     Component child = info.getComponent(i);
     GridConstraints c = info.getConstraints(i);
     if (c.isUseParentLayout() && child instanceof Container) {
       Container container = (Container) child;
       if (container.getLayout() instanceof GridLayoutManager) {
         updateSizesFromChild(info, min, widths, container, i);
       } else if (container.getComponentCount() == 1
           && container.getComponent(0) instanceof Container) {
         Container childContainer = (Container) container.getComponent(0);
         if (childContainer.getLayout() instanceof GridLayoutManager) {
           updateSizesFromChild(info, min, widths, childContainer, i);
         }
       }
     }
   }
 }
  private static boolean shouldAddGapAfterCell(DimensionInfo info, int cellIndex) {
    if (cellIndex >= 0 && cellIndex < info.getCellCount()) {
      boolean endsInThis = false;
      boolean startsInNext = false;
      int indexOfNextNotEmpty = -1;

      int i;
      for (i = cellIndex + 1; i < info.getCellCount(); ++i) {
        if (!isCellEmpty(info, i)) {
          indexOfNextNotEmpty = i;
          break;
        }
      }

      for (i = 0; i < info.getComponentCount(); ++i) {
        Component component = info.getComponent(i);
        if (!(component instanceof Spacer)) {
          if (info.componentBelongsCell(i, cellIndex)
              && DimensionInfo.findAlignedChild(component, info.getConstraints(i)) != null) {
            return true;
          }

          if (info.getCell(i) == indexOfNextNotEmpty) {
            startsInNext = true;
          }

          if (info.getCell(i) + info.getSpan(i) - 1 == cellIndex) {
            endsInThis = true;
          }
        }
      }

      return startsInNext && endsInThis;
    } else {
      throw new IllegalArgumentException(
          "wrong cellIndex: " + cellIndex + "; cellCount=" + info.getCellCount());
    }
  }