@NotNull
 private MultiRowFlowPanel addRowIfNecessary(@NotNull MultiRowFlowPanel panel) {
   if (panel.getComponentCount() <= 0) {
     return panel;
   }
   add(
       panel,
       new GridBag()
           .anchor(GridBagConstraints.WEST)
           .weightx(1)
           .fillCellHorizontally()
           .coverLine());
   myRows.add(panel);
   return new MultiRowFlowPanel(
       FlowLayout.LEFT, ArrangementConstants.HORIZONTAL_GAP, ArrangementConstants.VERTICAL_GAP);
 }
 public void applyAvailableWidth(int width) {
   for (MultiRowFlowPanel row : myRows) {
     row.setForcedWidth(width - myLabelWidth);
   }
   validate();
 }
  private void addToken(@NotNull CompositeArrangementSettingsToken rowToken) {
    List<CompositeArrangementSettingsToken> tokens = ArrangementUtil.flatten(rowToken);
    GridBag labelConstraints =
        new GridBag()
            .anchor(GridBagConstraints.NORTHWEST)
            .insets(ArrangementConstants.VERTICAL_PADDING, 0, 0, 0);
    MultiRowFlowPanel panel =
        new MultiRowFlowPanel(
            FlowLayout.LEFT,
            ArrangementConstants.HORIZONTAL_GAP,
            ArrangementConstants.VERTICAL_GAP);
    List<ArrangementSettingsToken> prevTokens = ContainerUtilRt.newArrayList();
    StdArrangementTokenUiRole prevRole = null;
    ArrangementUiComponent component;
    JComponent uiComponent;
    for (CompositeArrangementSettingsToken token : tokens) {
      StdArrangementTokenUiRole role = token.getRole();
      if (role != prevRole && !prevTokens.isEmpty()) {
        component =
            ArrangementUtil.buildUiComponent(role, prevTokens, myColorsProvider, mySettingsManager);
        component.setListener(this);
        for (ArrangementSettingsToken prevToken : prevTokens) {
          myComponents.put(prevToken, component);
        }
        panel.add(component.getUiComponent());
        panel = addRowIfNecessary(panel);
        prevRole = null;
        prevTokens.clear();
      }
      component =
          ArrangementUtil.buildUiComponent(
              role,
              Collections.singletonList(token.getToken()),
              myColorsProvider,
              mySettingsManager);
      component.setListener(this);
      uiComponent = component.getUiComponent();
      switch (role) {
        case LABEL:
          panel = addRowIfNecessary(panel);
          add(uiComponent, labelConstraints);
          myLabelWidth = Math.max(myLabelWidth, uiComponent.getPreferredSize().width);
          prevRole = null;
          break;
        case TEXT_FIELD:
          panel = addRowIfNecessary(panel);

          ArrangementUiComponent textLabel =
              ArrangementUtil.buildUiComponent(
                  StdArrangementTokenUiRole.LABEL,
                  Collections.singletonList(token.getToken()),
                  myColorsProvider,
                  mySettingsManager);
          JComponent textLabelComponent = textLabel.getUiComponent();
          add(textLabelComponent, labelConstraints);
          myLabelWidth = Math.max(myLabelWidth, textLabelComponent.getPreferredSize().width);

          panel.add(uiComponent);
          panel = addRowIfNecessary(panel);
          prevRole = null;

          myComponents.put(token.getToken(), component);

          if (myDefaultFocusRequestor == null) {
            myDefaultFocusRequestor = uiComponent;
          }
          break;
        default:
          if (role == StdArrangementTokenUiRole.COMBO_BOX) {
            prevTokens.add(token.getToken());
            prevRole = role;
            break;
          }

          panel.add(uiComponent);
          myComponents.put(token.getToken(), component);
      }
    }

    if (prevRole != null && !prevTokens.isEmpty()) {
      component =
          ArrangementUtil.buildUiComponent(
              prevRole, prevTokens, myColorsProvider, mySettingsManager);
      panel.add(component.getUiComponent());
      component.setListener(this);
      for (ArrangementSettingsToken prevToken : prevTokens) {
        myComponents.put(prevToken, component);
      }
    }
    addRowIfNecessary(panel);
  }