@Override
 public String getValue() throws Exception {
   final RadComponent selection = (RadComponent) myCbx.getSelectedItem();
   if (selection == null) {
     return myOldValue == null ? null : "";
   }
   return selection.getId();
 }
  public static void paintComponentDecoration(
      final GuiEditor editor, final RadComponent component, final Graphics g) {
    // Collect selected components and paint decoration for non selected components
    final ArrayList<RadComponent> selection = new ArrayList<RadComponent>();
    final Rectangle layeredPaneRect = editor.getLayeredPane().getVisibleRect();
    FormEditingUtil.iterate(
        component,
        new FormEditingUtil.ComponentVisitor<RadComponent>() {
          public boolean visit(final RadComponent component) {
            if (!component.getDelegee().isShowing()) { // Skip invisible components
              return true;
            }
            final Shape oldClip = g.getClip();
            final RadContainer parent = component.getParent();
            if (parent != null) {
              final Point p =
                  SwingUtilities.convertPoint(
                      component.getDelegee(), 0, 0, editor.getLayeredPane());
              final Rectangle visibleRect =
                  layeredPaneRect.intersection(
                      new Rectangle(p.x, p.y, parent.getWidth(), parent.getHeight()));
              g.setClip(visibleRect);
            }
            if (component.isSelected()) { // we will paint selection later
              selection.add(component);
            } else {
              paintComponentBoundsImpl(editor, component, g);
            }
            paintGridOutline(editor, component, g);
            if (parent != null) {
              g.setClip(oldClip);
            }
            return true;
          }
        });

    // Let's paint decoration for selected components
    for (int i = selection.size() - 1; i >= 0; i--) {
      final Shape oldClip = g.getClip();
      final RadComponent c = selection.get(i);
      final RadContainer parent = c.getParent();
      if (parent != null) {
        final Point p = SwingUtilities.convertPoint(c.getDelegee(), 0, 0, editor.getLayeredPane());
        final Rectangle visibleRect =
            layeredPaneRect.intersection(
                new Rectangle(p.x, p.y, parent.getWidth(), parent.getHeight()));
        g.setClip(visibleRect);
      }
      paintComponentBoundsImpl(editor, c, g);
      if (parent != null) {
        g.setClip(oldClip);
      }
    }
  }
 private static int getDesignTimeInsets(RadComponent component) {
   while (component != null) {
     Integer designTimeInsets =
         (Integer) component.getDelegee().getClientProperty(GridLayoutManager.DESIGN_TIME_INSETS);
     if (designTimeInsets != null) {
       return designTimeInsets.intValue();
     }
     component = component.getParent();
   }
   return 0;
 }
  private RadComponent[] collectFilteredComponents(final RadComponent component) {
    final ArrayList<RadComponent> result = new ArrayList<RadComponent>();
    result.add(null);

    RadContainer container = component.getParent();
    while (container.getParent() != null) {
      container = container.getParent();
    }

    FormEditingUtil.iterate(
        container,
        new FormEditingUtil.ComponentVisitor() {
          public boolean visit(final IComponent component) {
            RadComponent radComponent = (RadComponent) component;
            final JComponent delegee = radComponent.getDelegee();
            if (!myPropertyType.isInstance(delegee)) {
              return true;
            }
            if (myFilter == null || myFilter.value(radComponent)) {
              result.add(radComponent);
            }
            return true;
          }
        });

    return result.toArray(new RadComponent[result.size()]);
  }
  /** Paints selection for the specified <code>component</code>. */
  public static void paintSelectionDecoration(
      @NotNull RadComponent component, Graphics g, boolean focused) {
    if (component.isSelected()) {
      if (focused) {
        g.setColor(PlatformColors.BLUE);
      } else {
        g.setColor(Color.GRAY);
      }
      final Point[] points = getPoints(component.getWidth(), component.getHeight());
      for (final Point point : points) {
        g.fillRect(point.x - R, point.y - R, 2 * R + 1, 2 * R + 1);
      }
    } else if (component.getWidth() < FormEditingUtil.EMPTY_COMPONENT_SIZE
        || component.getHeight() < FormEditingUtil.EMPTY_COMPONENT_SIZE) {
      Graphics2D g2d = (Graphics2D) g;
      Composite oldComposite = g2d.getComposite();
      Stroke oldStroke = g2d.getStroke();
      Color oldColor = g2d.getColor();

      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
      g2d.setStroke(new BasicStroke(0.7f));
      g2d.setColor(Color.black);
      g2d.drawRect(
          0,
          0,
          Math.max(component.getWidth(), FormEditingUtil.EMPTY_COMPONENT_SIZE),
          Math.max(component.getHeight(), FormEditingUtil.EMPTY_COMPONENT_SIZE));

      g2d.setComposite(oldComposite);
      g2d.setStroke(oldStroke);
      g2d.setColor(oldColor);
    }
  }
  public static void paintComponentTag(final RadComponent component, final Graphics g) {
    if (component instanceof RadContainer) return;
    for (IProperty prop : component.getModifiedProperties()) {
      if (prop.getName().equals(SwingProperties.TEXT)) {
        final Object desc = prop.getPropertyValue(component);
        if (!(desc instanceof StringDescriptor)
            || ((StringDescriptor) desc).getValue() == null
            || ((StringDescriptor) desc).getValue().length() > 0) {
          return;
        }
      } else if (prop.getName().equals(SwingProperties.MODEL)) {
        // don't paint tags on non-empty lists
        final Object value = prop.getPropertyValue(component);
        if (value instanceof String[] && ((String[]) value).length > 0) {
          return;
        }
      }
    }

    Rectangle bounds = component.getDelegee().getBounds();
    if (bounds.width > 100 && bounds.height > 40) {
      StringBuilder tagBuilder = new StringBuilder();
      if (component.getBinding() != null) {
        tagBuilder.append(component.getBinding()).append(':');
      }
      String className = component.getComponentClassName();
      int pos = className.lastIndexOf('.');
      if (pos >= 0) {
        tagBuilder.append(className.substring(pos + 1));
      } else {
        tagBuilder.append(className);
      }
      final Rectangle2D stringBounds = g.getFontMetrics().getStringBounds(tagBuilder.toString(), g);
      Graphics2D g2d = (Graphics2D) g;
      g2d.setColor(PlatformColors.BLUE);
      g2d.fillRect(0, 0, (int) stringBounds.getWidth(), (int) stringBounds.getHeight());
      g2d.setColor(Color.WHITE);
      g.drawString(tagBuilder.toString(), 0, g.getFontMetrics().getAscent());
    }
  }
  /**
   * @param x in component's coord system
   * @param y in component's coord system
   */
  public static int getResizeMask(@NotNull final RadComponent component, final int x, final int y) {
    if (component.getParent() == null || !component.isSelected()) {
      return 0;
    }

    // only components in XY can be resized...
    /*
    if (!component.getParent().isXY()) {
      return 0;
    }
    */

    final int width = component.getWidth();
    final int height = component.getHeight();

    final Point[] points = getPoints(width, height);

    if (isInside(x, y, points[SE])) {
      return EAST_MASK | SOUTH_MASK;
    } else if (isInside(x, y, points[NW])) {
      return WEST_MASK | NORTH_MASK;
    } else if (isInside(x, y, points[N])) {
      return NORTH_MASK;
    } else if (isInside(x, y, points[NE])) {
      return EAST_MASK | NORTH_MASK;
    } else if (isInside(x, y, points[W])) {
      return WEST_MASK;
    } else if (isInside(x, y, points[E])) {
      return EAST_MASK;
    } else if (isInside(x, y, points[SW])) {
      return WEST_MASK | SOUTH_MASK;
    } else if (isInside(x, y, points[S])) {
      return SOUTH_MASK;
    } else {
      return 0;
    }
  }
  /** This method paints grid bounds for "grid" containers */
  public static void paintGridOutline(
      final GuiEditor editor, @NotNull final RadComponent component, final Graphics g) {
    if (!editor.isShowGrid()) {
      return;
    }
    if (!(component instanceof RadContainer)) {
      return;
    }
    final RadContainer container = (RadContainer) component;
    if (!container.getLayoutManager().isGrid()) {
      return;
    }

    // performance: don't paint grid outline in drag layer
    Container parent = component.getDelegee().getParent();
    while (parent != null) {
      if (parent == editor.getDragLayer()) {
        return;
      }
      parent = parent.getParent();
    }

    final Point point =
        SwingUtilities.convertPoint(
            component.getDelegee(), 0, 0, editor.getRootContainer().getDelegee());
    g.translate(point.x, point.y);
    try {
      // Paint grid
      if (container.getWidth() > 0 && container.getHeight() > 0) {
        Image gridImage = CachedGridImage.getGridImage(container);
        g.drawImage(gridImage, 0, 0, null);
      }
    } finally {
      g.translate(-point.x, -point.y);
    }
  }
  /**
   * Paints container border. For grids the method also paints vertical and horizontal lines that
   * indicate bounds of the rows and columns. Method does nothing if the <code>component</code> is
   * not an instance of <code>RadContainer</code>.
   */
  private static void paintComponentBoundsImpl(
      final GuiEditor editor, @NotNull final RadComponent component, final Graphics g) {
    if (!(component instanceof RadContainer)
        && !(component instanceof RadNestedForm)
        && !component.isDragBorder()) {
      return;
    }

    boolean highlightBoundaries = (getDesignTimeInsets(component) > 2);

    if (component instanceof RadContainer && !component.isDragBorder()) {
      RadContainer container = (RadContainer) component;
      if (!highlightBoundaries
          && (container.getBorderTitle() != null || container.getBorderType() != BorderType.NONE)) {
        return;
      }
    }
    final Point point =
        SwingUtilities.convertPoint(
            component.getDelegee(), 0, 0, editor.getRootContainer().getDelegee());
    g.translate(point.x, point.y);
    try {
      if (component.isDragBorder()) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(LightColors.YELLOW);
        g2d.setStroke(new BasicStroke(2.0f));
        g2d.translate(1, 1);
      } else if (highlightBoundaries) {
        g.setColor(HIGHLIGHTED_BOUNDARY_COLOR);
      } else if (component.isSelected()) {
        g.setColor(SELECTED_BOUNDARY_COLOR);
      } else {
        g.setColor(NON_SELECTED_BOUNDARY_COLOR);
      }
      g.drawRect(0, 0, component.getWidth() - 1, component.getHeight() - 1);
      if (component.isDragBorder()) {
        g.translate(-1, -1);
      }
    } finally {
      g.translate(-point.x, -point.y);
    }
  }
  private static String[] getFieldNames(final RadComponent component, final String currentName) {
    final ArrayList<String> result = new ArrayList<String>();
    if (currentName != null) {
      result.add(currentName);
    }

    final IRootContainer root = FormEditingUtil.getRoot(component);
    final String className = root.getClassToBind();
    if (className == null) {
      return ArrayUtil.toStringArray(result);
    }

    final PsiClass aClass = FormEditingUtil.findClassToBind(component.getModule(), className);
    if (aClass == null) {
      return ArrayUtil.toStringArray(result);
    }

    final PsiField[] fields = aClass.getFields();

    for (final PsiField field : fields) {
      if (field.hasModifierProperty(PsiModifier.STATIC)) {
        continue;
      }

      final String fieldName = field.getName();

      if (Comparing.equal(currentName, fieldName)) {
        continue;
      }

      if (!FormEditingUtil.isBindingUnique(component, fieldName, root)) {
        continue;
      }

      final String componentClassName;
      if (component instanceof RadErrorComponent) {
        componentClassName = component.getComponentClassName();
      } else if (component instanceof RadHSpacer || component instanceof RadVSpacer) {
        componentClassName = Spacer.class.getName();
      } else {
        componentClassName = component.getComponentClass().getName();
      }

      final PsiType componentType;
      try {
        componentType =
            JavaPsiFacade.getInstance(component.getProject())
                .getElementFactory()
                .createTypeFromText(componentClassName, null);
      } catch (IncorrectOperationException e) {
        continue;
      }

      final PsiType fieldType = field.getType();
      if (!fieldType.isAssignableFrom(componentType)) {
        continue;
      }

      result.add(fieldName);
    }

    String text = FormInspectionUtil.getText(component.getModule(), component);
    if (text != null) {
      String binding = BindingProperty.suggestBindingFromText(component, text);
      if (binding != null && !result.contains(binding)) {
        result.add(binding);
      }
    }

    final String[] names = ArrayUtil.toStringArray(result);
    Arrays.sort(names);
    return names;
  }