/**
   * Paint the component.
   *
   * @param g The graphics context for painting
   * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
   */
  protected void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;

    fRenderer.paintComponent(g2, fButtonDelegate, this, 0, 0, getWidth(), getHeight(), true);

    ButtonModel model = getModel();
    boolean doOffset = model.isPressed() && model.isArmed();
    int offsetAmount = UIManager.getInt("Button.textShiftOffset");
    double degrees = Math.toRadians(-90);

    if (fRotation == LEFT) {
      int h = getHeight();
      g2.translate(0, h);
      g2.rotate(degrees);
      if (doOffset) {
        g2.translate(-offsetAmount, offsetAmount);
      }

      fRenderer.paintComponent(g2, fLabelDelegate, this, 0, 0, getHeight(), getWidth(), true);
      if (doOffset) {
        g2.translate(offsetAmount, -offsetAmount);
      }
      g2.rotate(-degrees);

      g2.translate(0, -h);
    } else {
      int w = getWidth();
      g2.translate(w, 0);
      g2.rotate(-degrees);
      if (doOffset) {
        g2.translate(offsetAmount, -offsetAmount);
      }
      fRenderer.paintComponent(g2, fLabelDelegate, this, 0, 0, getHeight(), getWidth(), true);
      if (doOffset) {
        g2.translate(-offsetAmount, offsetAmount);
      }
      g2.rotate(degrees);
      g2.translate(-w, 0);
    }
  }
 /** Paint cell at (row, column) */
 protected void paintCell(Graphics g, Rectangle cellBounds, int row, int column) {
   if (grid.getEditingRow() == row && grid.getEditingColumn() == column) {
     return;
   }
   GridCellRenderer renderer = grid.getCellRenderer(row, column);
   Component rendererComp = grid.prepareRenderer(renderer, row, column);
   CellSpan span = grid.getSpanModel().getSpanOver(row, column);
   rendererPane.paintComponent(
       g,
       rendererComp,
       grid,
       cellBounds.x,
       cellBounds.y,
       cellBounds.width,
       cellBounds.height,
       true);
 }
  private void configure() {
    fRotation = LEFT;

    fButtonDelegate =
        new JToggleButton() {
          public String getText() {
            return null;
          }

          public boolean isEnabled() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.isEnabled();
            }
            return super.isEnabled();
          }

          public boolean isSelected() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.isSelected();
            }
            return super.isSelected();
          }

          public boolean isFocusPainted() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.isFocusPainted();
            }
            return super.isFocusPainted();
          }

          public boolean isContentAreaFilled() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.isContentAreaFilled();
            }
            return super.isContentAreaFilled();
          }

          public boolean isBorderPainted() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.isBorderPainted();
            }
            return super.isBorderPainted();
          }

          public Border getBorder() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getBorder();
            }
            return super.getBorder();
          }

          public boolean isOpaque() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.isOpaque();
            }
            return super.isOpaque();
          }

          public Color getBackground() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getBackground();
            }
            return super.getBackground();
          }

          public Icon getIcon() {
            return null;
          }

          public Icon getPressedIcon() {
            return null;
          }

          public Icon getSelectedIcon() {
            return null;
          }

          public Icon getRolloverIcon() {
            return null;
          }

          public Icon getRolloverSelectedIcon() {
            return null;
          }

          public Icon getDisabledIcon() {
            return null;
          }
        };

    fLabelDelegate =
        new JLabel() {
          public String getText() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getText();
            }
            return super.getText();
          }

          public Color getForeground() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getForeground();
            }
            return super.getForeground();
          }

          public boolean isEnabled() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.isEnabled();
            }
            return super.isEnabled();
          }

          public int getIconTextGap() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getIconTextGap();
            }
            return super.getIconTextGap();
          }

          public int getVerticalAlignment() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getVerticalAlignment();
            }
            return super.getVerticalAlignment();
          }

          public int getVerticalTextPosition() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getVerticalTextPosition();
            }
            return super.getVerticalTextPosition();
          }

          public int getHorizontalAlignment() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getHorizontalAlignment();
            }
            return super.getHorizontalAlignment();
          }

          public int getHorizontalTextPosition() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getHorizontalTextPosition();
            }
            return super.getHorizontalTextPosition();
          }

          public Border getBorder() {
            return null;
          }

          public int getMnemonic() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getMnemonic();
            }
            return -1;
          }

          public int getDisplayedMnemonicIndex() {
            if (JVerticalToggleButton.this != null) {
              return JVerticalToggleButton.this.getDisplayedMnemonicIndex();
            }
            return super.getDisplayedMnemonicIndex();
          }

          private Insets insets = new Insets(0, 0, 0, 0);

          public Insets getInsets() {
            if (JVerticalToggleButton.this != null) {
              return super.getInsets();
            }

            Border b = JVerticalToggleButton.this.getBorder();

            Insets minsets = JVerticalToggleButton.this.getMargin();

            insets.left = minsets.left;
            insets.top = minsets.top;
            insets.right = minsets.right;
            insets.bottom = minsets.bottom;

            if (b != null) {
              Insets binsets = b.getBorderInsets(JVerticalToggleButton.this);
              insets.left += binsets.left;
              insets.top += binsets.top;
              insets.right += binsets.right;
              insets.bottom += binsets.bottom;
            }

            return insets;
          }

          public Icon getIcon() {
            if (JVerticalToggleButton.this != null) {
              return super.getIcon();
            }

            ButtonModel model = JVerticalToggleButton.this.getModel();
            Icon subIcon = null;

            if (!model.isEnabled()) {
              if (model.isSelected()) {
                subIcon = getDisabledSelectedIcon();
              } else {
                subIcon = getDisabledIcon();
              }
            } else if (model.isPressed() && model.isArmed()) {
              subIcon = getPressedIcon();
            } else if (isRolloverEnabled() && model.isRollover()) {
              if (model.isSelected()) {
                subIcon = getRolloverSelectedIcon();
              } else {
                subIcon = getRolloverIcon();
              }
            } else if (model.isSelected()) {
              subIcon = getSelectedIcon();
            }

            if (subIcon == null) subIcon = JVerticalToggleButton.this.getIcon();

            return subIcon;
          }

          public Icon getDisabledIcon() {
            return JVerticalToggleButton.this.getDisabledIcon();
          }
        };

    fLabelDelegate.setOpaque(false);

    // we paint our own border
    fButtonDelegate.setBorderPainted(false);
    fButtonDelegate.setModel(getModel());

    fRenderer = new CellRendererPane();
    fRenderer.add(fButtonDelegate);
    fRenderer.add(fLabelDelegate);

    fPreferredSize = new Dimension();
    fMinimumSize = new Dimension();
    fMaximumSize = new Dimension();

    Action action = getAction();
    if (action != null) {
      fButtonDelegate.setAction(action);
    }
  }
 protected void doPaintTooltipImage(
     Component rComponent, Rectangle cellBounds, Graphics2D g, KeyType key) {
   myRendererPane.paintComponent(
       g, rComponent, myComponent, 0, 0, cellBounds.width, cellBounds.height, true);
 }
  @Nullable
  private Point createToolTipImage(@NotNull KeyType key) {
    UIUtil.putClientProperty(myComponent, EXPANDED_RENDERER, true);
    Pair<Component, Rectangle> rendererAndBounds = getCellRendererAndBounds(key);
    UIUtil.putClientProperty(myComponent, EXPANDED_RENDERER, null);
    if (rendererAndBounds == null) return null;

    JComponent renderer = ObjectUtils.tryCast(rendererAndBounds.first, JComponent.class);
    if (renderer == null) return null;
    if (renderer.getClientProperty(DISABLE_EXPANDABLE_HANDLER) != null) return null;

    if (UIUtil.getClientProperty((JComponent) rendererAndBounds.getFirst(), USE_RENDERER_BOUNDS)
        == Boolean.TRUE) {
      rendererAndBounds.getSecond().translate(renderer.getX(), renderer.getY());
      rendererAndBounds.getSecond().setSize(renderer.getSize());
    }

    myKeyItemBounds = rendererAndBounds.second;

    Rectangle cellBounds = myKeyItemBounds;
    Rectangle visibleRect = getVisibleRect(key);

    if (cellBounds.y < visibleRect.y) return null;

    int cellMaxY = cellBounds.y + cellBounds.height;
    int visMaxY = visibleRect.y + visibleRect.height;
    if (cellMaxY > visMaxY) return null;

    int cellMaxX = cellBounds.x + cellBounds.width;
    int visMaxX = visibleRect.x + visibleRect.width;

    Point location = new Point(visMaxX, cellBounds.y);
    SwingUtilities.convertPointToScreen(location, myComponent);

    Rectangle screen =
        !Registry.is("ide.expansion.hints.on.all.screens")
            ? ScreenUtil.getScreenRectangle(location)
            : ScreenUtil.getAllScreensRectangle();

    int borderWidth = isPaintBorder() ? 1 : 0;
    int width = Math.min(screen.width + screen.x - location.x - borderWidth, cellMaxX - visMaxX);
    int height = cellBounds.height;

    if (width <= 0 || height <= 0) return null;

    Dimension size = getImageSize(width, height);
    myImage = UIUtil.createImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);

    Graphics2D g = myImage.createGraphics();
    g.setClip(null);
    doFillBackground(height, width, g);
    g.translate(cellBounds.x - visMaxX, 0);
    doPaintTooltipImage(renderer, cellBounds, g, key);

    CustomLineBorder border = null;
    if (borderWidth > 0) {
      border = new CustomLineBorder(getBorderColor(), borderWidth, 0, borderWidth, borderWidth);
      location.y -= borderWidth;
      size.width += borderWidth;
      size.height += borderWidth + borderWidth;
    }

    g.dispose();
    myRendererPane.remove(renderer);

    myTipComponent.setBorder(border);
    myTipComponent.setPreferredSize(size);
    return location;
  }