code: private void layoutComponents(int[] x, int[] y) {
          Rectangle cellBounds = new Rectangle();
          for (Object element : constraintMap.entrySet()) {
              Map.Entry entry = (Map.Entry) element;
              Component component = (Component) entry.getKey();
              CellConstraints constraints = (CellConstraints) entry.getValue();
  
              int gridX = constraints.gridX - 1;
              int gridY = constraints.gridY - 1;
              int gridWidth = constraints.gridWidth;
              int gridHeight = constraints.gridHeight;
              cellBounds.x = x[gridX];
              cellBounds.y = y[gridY];
              cellBounds.width = x[gridX + gridWidth] - cellBounds.x;
              cellBounds.height = y[gridY + gridHeight] - cellBounds.y;
  
              constraints.setBounds(component, this, cellBounds,
                      minimumWidthMeasure, minimumHeightMeasure,
                      preferredWidthMeasure, preferredHeightMeasure);
          }
      }
docs: Lays out the components using the given x and y origins, the column and row specifications,
  and the component constraints.<p>
  
  The actual computation is done by each component's form constraint object. We just compute
  the cell, the cell bounds and then hand over the component, cell bounds, and measure to the
  form constraints. This will allow potential subclasses of {@code CellConstraints} to do
  special micro-layout corrections. For example, such a subclass could map JComponent classes
  to visual layout bounds that may lead to a slightly different bounds.
  
  @param x an int array of the horizontal origins
  @param y an int array of the vertical origins