@Override
  public void componentLayoutChanged(int index, PropertyChangeEvent ev)
      throws PropertyVetoException {
    RADVisualComponent<?> radComp = radContainer.getSubComponent(index);

    if (ev != null && ev.getPropertyName() != null) {
      layoutDelegate.acceptComponentLayoutChange(index, ev);

      FormModel formModel = radContainer.getFormModel();
      formModel.fireComponentLayoutChanged(
          radComp, ev.getPropertyName(), ev.getOldValue(), ev.getNewValue());

      if (radComp.getNodeReference() != null) // propagate the change to node
      {
        radComp
            .getNodeReference()
            .firePropertyChangeHelper(ev.getPropertyName(), ev.getOldValue(), ev.getNewValue());
      }
    } else {
      if (radComp.getNodeReference() != null) // propagate the change to node
      {
        radComp.getNodeReference().fireComponentPropertySetsChange();
      }
      radComp.resetConstraintsProperties();
    }
  }
  public boolean isLayoutChanged() {
    Container defaultContainer =
        (Container) BeanSupport.getDefaultInstance(radContainer.getBeanClass());
    Container defaultContDelegate = radContainer.getContainerDelegate(defaultContainer);

    return layoutDelegate.isLayoutChanged(defaultContainer, defaultContDelegate);
  }
 // return container delegate of container instance of meta container
 @Override
 public Container getPrimaryContainerDelegate() {
   Container defCont = (Container) radContainer.getBeanInstance();
   if (primaryContainerDelegate == null || primaryContainer != defCont) {
     primaryContainer = defCont;
     primaryContainerDelegate = radContainer.getContainerDelegate(defCont);
   }
   return primaryContainerDelegate;
 }
  public void removeComponent(RADVisualComponent<?> radComp, int index) {
    // first store constraints in the meta component
    LayoutConstraints<?> constr = layoutDelegate.getConstraints(index);
    if (constr != null) {
      radComp.setLayoutConstraints(layoutDelegate.getClass(), constr);
    }
    // remove the component from layout
    layoutDelegate.removeComponent(index);
    // remove the component instance from the primary container instance
    if (!layoutDelegate.removeComponentFromContainer(
        getPrimaryContainer(),
        getPrimaryContainerDelegate(),
        (Component)
            radComp
                .getBeanInstance())) { // layout delegate does not support removing individual
                                       // components,
      // so we clear the container and add the remaining components again
      layoutDelegate.clearContainer(getPrimaryContainer(), getPrimaryContainerDelegate());

      RADVisualComponent<?>[] radComps = radContainer.getSubComponents();
      if (radComps.length > 1) {
        // we rely on that radcomp was not removed from the model yet
        Component[] comps = new Component[radComps.length - 1];
        for (int i = 0; i < radComps.length; i++) {
          if (i != index) {
            Component comp = (Component) radComps[i].getBeanInstance();
            comps[i < index ? i : i - 1] = comp;
          }
        }
        layoutDelegate.addComponentsToContainer(
            getPrimaryContainer(), getPrimaryContainerDelegate(), comps, 0);
      }
    }
  }
  private void fillLayout(LayoutConstraints<?>[] oldConstraints) {
    RADVisualComponent<?>[] radComps = radContainer.getSubComponents();
    int componentCount = radComps.length;
    Component[] primaryComps = new Component[componentCount];
    LayoutConstraints<?>[] newConstraints = new LayoutConstraints<?>[componentCount];

    for (int i = 0; i < componentCount; i++) {
      primaryComps[i] = radComps[i].getBeanInstance();
      newConstraints[i] = radComps[i].getLayoutConstraints(layoutDelegate.getClass());
    }

    layoutDelegate.convertConstraints(oldConstraints, newConstraints, primaryComps);

    if (componentCount > 0) {
      layoutDelegate.acceptNewComponents(radComps, newConstraints, 0);
      layoutDelegate.addComponents(radComps, newConstraints, 0);

      for (int i = 0; i < componentCount; i++) {
        radComps[i].resetConstraintsProperties();
      }
    }

    // setup primary container
    Container cont = getPrimaryContainer();
    Container contDel = getPrimaryContainerDelegate();
    layoutDelegate.setLayoutToContainer(cont, contDel);
    if (componentCount > 0) {
      layoutDelegate.addComponentsToContainer(cont, contDel, primaryComps, 0);
    }
  }
  private LayoutConstraints<?>[] removeLayoutDelegate(boolean extractConstraints) {
    int componentCount = layoutDelegate.getComponentCount();
    LayoutConstraints<?>[] constraints = null;

    if (componentCount > 0) {
      RADVisualComponent<?>[] radComps = radContainer.getSubComponents();
      if (radComps.length
          == componentCount) { // robustness: might be called after failed layout initialization
        if (extractConstraints) {
          constraints = new LayoutConstraints<?>[componentCount];
        }

        for (int i = 0; i < componentCount; i++) {
          LayoutConstraints<?> constr = layoutDelegate.getConstraints(i);
          if (extractConstraints) {
            constraints[i] = constr;
          }
          if (constr != null) {
            radComps[i].setLayoutConstraints(layoutDelegate.getClass(), constr);
          }
        }
      }
    }
    layoutDelegate.removeAll();
    layoutDelegate.clearContainer(getPrimaryContainer(), getPrimaryContainerDelegate());
    layoutDelegate = null;
    return constraints;
  }
  @Override
  public void containerLayoutChanged(PropertyChangeEvent ev) throws PropertyVetoException {
    if (ev != null && ev.getPropertyName() != null) {
      layoutDelegate.acceptContainerLayoutChange(ev);

      FormModel formModel = radContainer.getFormModel();
      formModel.fireContainerLayoutChanged(
          radContainer, ev.getPropertyName(), ev.getOldValue(), ev.getNewValue());
    } else {
      propertySets = null;
    }

    LayoutNode node = radContainer.getLayoutNodeReference();
    if (node != null) {
      // propagate the change to node
      if (ev != null && ev.getPropertyName() != null) {
        node.fireLayoutPropertiesChange();
      } else {
        node.fireLayoutPropertySetsChange();
      }
    }
  }
 public void removeAll() {
   // first store constraints in meta components
   RADVisualComponent<?>[] components = radContainer.getSubComponents();
   for (int i = 0; i < components.length; i++) {
     LayoutConstraints<?> constr = layoutDelegate.getConstraints(i);
     if (constr != null) {
       components[i].setLayoutConstraints(layoutDelegate.getClass(), constr);
     }
   }
   // remove components from layout
   layoutDelegate.removeAll();
   // clear the primary container instance
   layoutDelegate.clearContainer(getPrimaryContainer(), getPrimaryContainerDelegate());
 }
  /**
   * Creation and initialization of a layout delegate for a new container.
   *
   * @param initialize
   * @return false if suitable layout delegate is not found
   * @throws java.lang.Exception
   * @throw IllegalArgumentException if the container instance is not empty
   */
  public boolean prepareLayoutDelegate(boolean initialize) throws Exception {
    LayoutSupportDelegate delegate = null;
    LayoutManager lmInstance = null;

    // first try to find a dedicated layout delegate (for the container)
    Class<?> layoutDelegateClass =
        LayoutSupportRegistry.getSupportClassForContainer(radContainer.getBeanClass());

    if (layoutDelegateClass != null) {
      delegate = (LayoutSupportDelegate) layoutDelegateClass.newInstance();
      /*
      if (!delegate.checkEmptyContainer(getPrimaryContainer())) {
          RuntimeException ex = new IllegalArgumentException();
          org.openide.ErrorManager.getDefault().annotate(
                  ex, AbstractLayoutSupport.getBundle().getString(
                          "MSG_ERR_NonEmptyContainer")); // NOI18N
          throw ex;
      }
      */
    } else {
      Container contDel = getPrimaryContainerDelegate();
      // if (contDel.getComponentCount() == 0) {
      // we can still handle only empty containers ...
      lmInstance = contDel.getLayout();
      delegate = LayoutSupportRegistry.createSupportForLayout(lmInstance.getClass());
      /*
      } else {
          RuntimeException ex = new IllegalArgumentException();
          org.openide.ErrorManager.getDefault().annotate(
                  ex, AbstractLayoutSupport.getBundle().getString(
                          "MSG_ERR_NonEmptyContainer")); // NOI18N
          throw ex;
      }
          */
    }

    if (delegate != null) {
      if (initialize) {
        setLayoutDelegate(delegate);
      } else {
        layoutDelegate = delegate;
        needInit = true;
        initializeFromInstance = lmInstance != null;
      }
      return true;
    } else {
      return false;
    }
  }
  @Override
  public void updatePrimaryContainer() {
    Container cont = getPrimaryContainer();
    Container contDel = getPrimaryContainerDelegate();

    layoutDelegate.clearContainer(cont, contDel);
    layoutDelegate.setLayoutToContainer(cont, contDel);

    RADVisualComponent<?>[] components = radContainer.getSubComponents();
    if (components.length > 0) {
      Component[] comps = new Component[components.length];
      for (int i = 0; i < components.length; i++) {
        comps[i] = (Component) components[i].getBeanInstance();
      }
      layoutDelegate.addComponentsToContainer(cont, contDel, comps, 0);
    }
  }
  // drag and drop support
  public LayoutConstraints<?> getNewConstraints(
      Container container,
      Container containerDelegate,
      Component component,
      int index,
      Point posInCont,
      Point posInComp) {

    LayoutConstraints<?> constraints =
        layoutDelegate.getNewConstraints(
            container, containerDelegate, component, index, posInCont, posInComp);
    String context = null;
    Object[] params = null;
    if (layoutDelegate instanceof AbstractLayoutSupport) {
      AbstractLayoutSupport support = (AbstractLayoutSupport) layoutDelegate;
      context = support.getAssistantContext();
      params = support.getAssistantParams();
    }
    context = (context == null) ? "generalPosition" : context; // NOI18N
    radContainer.getFormModel().getAssistantModel().setContext(context, params);
    return constraints;
  }
  /**
   * Выравнивание выбранных компонентов в выбранном направлении.
   *
   * @param dimension направление выравнивания
   * @param alignment требуемое выравнивание
   * @throws java.lang.Exception
   */
  public void align(int dimension, int alignment) throws Exception {
    if (selected != null && selected.size() > 1) { // выбрано по крайней мере 2 компонента
      assert selected.size() == selectedConstraints.size();
      assert container != null;
      Dimension parentSize = container.getBeanInstance().getSize();
      if (dimension == 0) { // выравнирание в горизонтальном направлении
        if (alignment == LayoutConstants.LEADING) { // выравнивание влево
          // ищем самый левый компонент
          MarginConstraints first = findLeftCompConstraints(parentSize.width);
          int leftNew = calcLeft(first, parentSize.width); // новая левая координата
          // выравниваем остальные компоненты по найденому
          for (int i = 0; i < selectedConstraints.size(); i++) {
            MarginLayoutConstraints mlc = selectedConstraints.get(i);
            MarginConstraints mc = mlc.getConstraintsObject();
            RADVisualComponent<?> vc = selected.get(i);
            if (mc != first) {
              int leftOld = calcLeft(mc, parentSize.width); // старая левая координата
              int rightOld = calcRight(mc, parentSize.width); // старая правая координата
              if (mc.getLeft() != null) {
                Margin newLeft = mc.getLeft().copy();
                newLeft.setPlainValue(leftNew, parentSize.width); // выравниваем левую координату
                mlc.getMLeft().setValue(newLeft);
                if (mc.getRight()
                    != null) { // ширина не используется. нужно устанавливать правую координату
                  Margin newRight = mc.getRight().copy();
                  newRight.setPlainValue(
                      rightOld + (leftOld - leftNew),
                      parentSize.width); // изменяем правую координату
                  mlc.getMRight().setValue(newRight);
                }
              } else {
                Margin newRight = mc.getRight().copy();
                newRight.setPlainValue(
                    rightOld + (leftOld - leftNew), parentSize.width); // изменяем правую координату
                mlc.getMRight().setValue(newRight);
              }
            }
            // отметить компонент как invalid
            vc.getBeanInstance().invalidate();
          }
        }
        if (alignment == LayoutConstants.TRAILING) { // выравнивание вправо
          // ищем самый правый компонент
          MarginConstraints first = findRightCompConstraints(parentSize.width);
          int rightNew = calcRight(first, parentSize.width); // новая правая координата
          // выравниваем остальные компоненты по найденому
          for (int i = 0; i < selectedConstraints.size(); i++) {
            MarginLayoutConstraints mlc = selectedConstraints.get(i);
            MarginConstraints mc = mlc.getConstraintsObject();
            RADVisualComponent<?> vc = selected.get(i);
            if (mc != first) {
              int leftOld = calcLeft(mc, parentSize.width); // старая левая координата
              int rightOld = calcRight(mc, parentSize.width); // старая правая координата
              // выравнивание
              if (mc.getLeft() != null) {
                Margin newLeft = mc.getLeft().copy();
                newLeft.setPlainValue(
                    leftOld + (rightOld - rightNew), parentSize.width); // изменяем левую координату
                mlc.getMLeft().setValue(newLeft);
                if (mc.getRight() != null) // ширина не используется
                {
                  Margin newRight = mc.getRight().copy();
                  newRight.setPlainValue(
                      rightNew, parentSize.width); // выравниваем правая координату
                  //   }
                  mlc.getMRight().setValue(newRight);
                }
              } else {
                Margin newRight = mc.getRight().copy();
                newRight.setPlainValue(rightNew, parentSize.width); // выравниваем правая координату
                mlc.getMRight().setValue(newRight);
              }
            }
            // отметить компонент как invalid
            vc.getBeanInstance().invalidate();
          }
        }
        if (alignment == LayoutConstants.CENTER) { // выравнивание по центру
          // ищем самый левый компонент
          MarginConstraints firstL = findLeftCompConstraints(parentSize.width);
          int leftNew = calcLeft(firstL, parentSize.width); // новая левая координата
          // ищем самый правый компонент
          MarginConstraints firstR = findRightCompConstraints(parentSize.width);
          int rightNew = calcRight(firstR, parentSize.width); // новая правая координата;
          int centerNew = (parentSize.width - rightNew + leftNew) / 2; // новый центр
          // выравниваем остальные компоненты по найденому
          for (int i = 0; i < selectedConstraints.size(); i++) {
            MarginLayoutConstraints mlc = selectedConstraints.get(i);
            MarginConstraints mc = mlc.getConstraintsObject();
            RADVisualComponent<?> vc = selected.get(i);

            int leftOld = calcLeft(mc, parentSize.width); // старая левая координата
            int rightOld = calcRight(mc, parentSize.width); // старая правая координата
            int centerOld = (parentSize.width - rightOld + leftOld) / 2;
            // выравнивание
            int sm = centerNew - centerOld;
            if (mc.getLeft() != null) {
              Margin newLeft = mc.getLeft().copy();
              newLeft.setPlainValue(leftOld + sm, parentSize.width); // изменяем левую координату
              mlc.getMLeft().setValue(newLeft);
              if (mc.getRight() != null) // ширина не используется
              {
                Margin newRight = mc.getRight().copy();
                newRight.setPlainValue(
                    rightOld - sm, parentSize.width); // выравниваем правая координату
                mlc.getMRight().setValue(newRight);
              }
            } else {
              Margin newRight = mc.getRight().copy();
              newRight.setPlainValue(
                  rightOld - sm, parentSize.width); // выравниваем правая координату
              mlc.getMRight().setValue(newRight);
            }
            // отметить компонент как invalid
            vc.getBeanInstance().invalidate();
          }
        }
      }
      if (dimension == 1) { // выравнивание в вертикальном направлении
        if (alignment == LayoutConstants.LEADING) { // выравнивание вверх
          // ищем самый верхний компонент
          MarginConstraints first = findTopCompConstraints(parentSize.height);
          int topNew = calcTop(first, parentSize.height); // новая верхняя координата
          // выравниваем остальные компоненты по найденому
          for (int i = 0; i < selectedConstraints.size(); i++) {
            MarginLayoutConstraints mlc = selectedConstraints.get(i);
            MarginConstraints mc = mlc.getConstraintsObject();
            RADVisualComponent<?> vc = selected.get(i);
            if (mc != first) {
              int topOld = calcTop(mc, parentSize.height); // старая левая координата
              int bottomOld = calcBottom(mc, parentSize.height); // старая правая координата
              if (mc.getTop() != null) {
                Margin newTop = mc.getTop().copy();
                newTop.setPlainValue(topNew, parentSize.height); // выравниваем левую координату
                mlc.getMTop().setValue(newTop);
                if (mc.getBottom()
                    != null) { // ширина не используется. нужно устанавливать правую координату
                  Margin newBottom = mc.getBottom().copy();
                  newBottom.setPlainValue(
                      bottomOld + (topOld - topNew),
                      parentSize.height); // изменяем правую координату
                  mlc.getMBottom().setValue(newBottom);
                }
              } else {
                Margin newBottom = mc.getBottom().copy();
                newBottom.setPlainValue(
                    bottomOld + (topOld - topNew), parentSize.height); // изменяем правую координату
                mlc.getMBottom().setValue(newBottom);
              }
            }
            // отметить компонент как invalid
            vc.getBeanInstance().invalidate();
          }
        }
        if (alignment == LayoutConstants.TRAILING) { // выравнивание вниз
          // ищем самый нижный компонент
          MarginConstraints first = findBottomCompConstraints(parentSize.height);
          int bottomNew = calcBottom(first, parentSize.height); // новая нижняя координата
          // выравниваем остальные компоненты по найденому
          for (int i = 0; i < selectedConstraints.size(); i++) {
            MarginLayoutConstraints mlc = selectedConstraints.get(i);
            MarginConstraints mc = mlc.getConstraintsObject();
            RADVisualComponent<?> vc = selected.get(i);
            if (mc != null) {
              int topOld = calcTop(mc, parentSize.height); // старая верхняя координата
              int bottomOld = calcBottom(mc, parentSize.height); // старая нижняя координата
              // выравнивание
              if (mc.getTop() != null) {
                Margin newTop = mc.getTop().copy();
                newTop.setPlainValue(
                    topOld + (bottomOld - bottomNew),
                    parentSize.height); // изменяем левую координату
                mlc.getMTop().setValue(newTop);
                if (mc.getBottom() != null) { // ширина не используется
                  Margin newBottom = mc.getBottom().copy();
                  newBottom.setPlainValue(
                      bottomNew, parentSize.height); // выравниваем правая координату
                  mlc.getMBottom().setValue(newBottom);
                }
              } else {
                Margin newBottom = mc.getBottom().copy();
                newBottom.setPlainValue(
                    bottomNew, parentSize.height); // выравниваем правая координату
                mlc.getMBottom().setValue(newBottom);
              }
            }
            // отметить компонент как invalid
            vc.getBeanInstance().invalidate();
          }
        }
        if (alignment == LayoutConstants.CENTER) { // выравнивание по центру
          // ищем самый верхний компонент
          MarginConstraints firstT = findTopCompConstraints(parentSize.height);
          int topNew = calcTop(firstT, parentSize.height); // новая верхняя координата
          // ищем самый нижний компонент
          MarginConstraints firstR = findBottomCompConstraints(parentSize.height);
          int bottomNew = calcBottom(firstR, parentSize.height); // новая верхняя координата
          int centerNew = (parentSize.height - bottomNew + topNew) / 2; // новый центр
          // выравниваем остальные компоненты по найденому
          for (int i = 0; i < selectedConstraints.size(); i++) {
            MarginLayoutConstraints mlc = selectedConstraints.get(i);
            MarginConstraints mc = mlc.getConstraintsObject();
            RADVisualComponent<?> vc = selected.get(i);
            int topOld = calcTop(mc, parentSize.height); // старая верхняя координата
            int bottomOld = calcBottom(mc, parentSize.height); // старая нижняя координата
            int centerOld = (parentSize.height - bottomOld + topOld) / 2;
            // выравнивание
            int sm = centerNew - centerOld;
            if (mc.getTop() != null) {
              Margin newTop = mc.getTop().copy();
              newTop.setPlainValue(topOld + sm, parentSize.height); // изменяем верхняя координату
              mlc.getMTop().setValue(newTop);
              if (mc.getBottom() != null) // ширина не используется
              {
                Margin newBottom = mc.getBottom().copy();
                newBottom.setPlainValue(
                    bottomOld - sm, parentSize.height); // выравниваем нижняя координату
                mlc.getMBottom().setValue(newBottom);
              }
            } else {
              Margin newBottom = mc.getBottom().copy();
              newBottom.setPlainValue(
                  bottomOld - sm, parentSize.height); // выравниваем нижняя координату
              mlc.getMBottom().setValue(newBottom);
            }
            // отметить компонент как invalid
            vc.getBeanInstance().invalidate();
          }
        }
      }
    }
  }
 protected Dimension parentSize(RADVisualComponent<?> aVisualComponent) {
   RADVisualContainer<?> radParent = aVisualComponent.getParentComponent();
   Container parentComp = radParent.getBeanInstance();
   Dimension parentSize = parentComp.getSize();
   return parentSize;
 }
 // return component instance of meta component
 @Override
 public Component getPrimaryComponent(int index) {
   return (Component) radContainer.getSubComponent(index).getBeanInstance();
 }
 // return container instance of meta container
 @Override
 public Container getPrimaryContainer() {
   return (Container) radContainer.getBeanInstance();
 }