@Override
  public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
    Point textLoc = new Point();
    Border border = getBorder();

    if (getTitle() == null || getTitle().length() == 0) {
        if (border != null) {
            border.paintBorder(c, g, x, y, width, height);
        }
        return;
    }

    Rectangle grooveRect = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING,
                                         width - (EDGE_SPACING * 2),
                                         height - (EDGE_SPACING * 2));
    Font font = g.getFont();
    Color color = g.getColor();

    g.setFont(getFont(c));

    FontMetrics fm = g.getFontMetrics();
    int         fontHeight = fm.getHeight();
    int         descent = fm.getDescent();
    int         ascent = fm.getAscent();
    int         diff;
    int         stringWidth = fm.stringWidth(getTitle());
    Insets      insets;

    if (border != null) {
        insets = border.getBorderInsets(c);
    } else {
        insets = new Insets(0, 0, 0, 0);
    }

    int titlePos = getTitlePosition();
    switch (titlePos) {
      case ABOVE_TOP -> {
        diff = ascent + descent + (Math.max(EDGE_SPACING,
                                            TEXT_SPACING * 2) - EDGE_SPACING);
        grooveRect.y += diff;
        grooveRect.height -= diff;
        textLoc.y = grooveRect.y - (descent + TEXT_SPACING);
      }
      case TOP, DEFAULT_POSITION -> {
        diff = Math.max(0, ((ascent / 2) + TEXT_SPACING) - EDGE_SPACING);
        grooveRect.y += diff;
        grooveRect.height -= diff;
        textLoc.y = (grooveRect.y - descent) +
                    (insets.top + ascent + descent) / 2;
      }
      case BELOW_TOP -> textLoc.y = grooveRect.y + insets.top + ascent + TEXT_SPACING;
      case ABOVE_BOTTOM -> textLoc.y = (grooveRect.y + grooveRect.height) -
                                       (insets.bottom + descent + TEXT_SPACING);
      case BOTTOM -> {
        grooveRect.height -= fontHeight / 2;
        textLoc.y = ((grooveRect.y + grooveRect.height) - descent) +
                    ((ascent + descent) - insets.bottom) / 2;
      }
      case BELOW_BOTTOM -> {
        grooveRect.height -= fontHeight;
        textLoc.y = grooveRect.y + grooveRect.height + ascent +
                    TEXT_SPACING;
      }
    }

    int justification = getTitleJustification();
    if(c.getComponentOrientation().isLeftToRight()) {
        if(justification==LEADING ||
           justification==DEFAULT_JUSTIFICATION) {
            justification = LEFT;
        }
        else if(justification==TRAILING) {
            justification = RIGHT;
        }
    }
    else {
        if(justification==LEADING ||
           justification==DEFAULT_JUSTIFICATION) {
            justification = RIGHT;
        }
        else if(justification==TRAILING) {
            justification = LEFT;
        }
    }

    switch (justification) {
      case LEFT -> textLoc.x = grooveRect.x + TEXT_INSET_H + insets.left;
      case RIGHT -> textLoc.x = (grooveRect.x + grooveRect.width) -
                                (stringWidth + TEXT_INSET_H + insets.right);
      case CENTER -> textLoc.x = grooveRect.x +
                                 ((grooveRect.width - stringWidth) / 2);
    }

    // If title is positioned in middle of border AND its fontsize
    // is greater than the border's thickness, we'll need to paint
    // the border in sections to leave space for the component's background
    // to show through the title.
    //
    if (border != null) {
        if (((titlePos == TOP || titlePos == DEFAULT_POSITION) &&
              (grooveRect.y > textLoc.y - ascent)) ||
             (titlePos == BOTTOM &&
              (grooveRect.y + grooveRect.height < textLoc.y + descent))) {

            Rectangle clipRect = new Rectangle();

            // save original clip
            Rectangle saveClip = g.getClipBounds();

            // paint strip left of text
            clipRect.setBounds(saveClip);
            if (computeIntersection2(clipRect, x, y, textLoc.x-1-x, height)) {
                g.setClip(clipRect);
                border.paintBorder(c, g, grooveRect.x, grooveRect.y,
                              grooveRect.width, grooveRect.height);
            }

            // paint strip right of text
            clipRect.setBounds(saveClip);
            if (computeIntersection2(clipRect, textLoc.x+stringWidth+1, y,
                           x+width-(textLoc.x+stringWidth+1), height)) {
                g.setClip(clipRect);
                border.paintBorder(c, g, grooveRect.x, grooveRect.y,
                              grooveRect.width, grooveRect.height);
            }

            if (titlePos == TOP || titlePos == DEFAULT_POSITION) {
                // paint strip below text
                clipRect.setBounds(saveClip);
                if (computeIntersection2(clipRect, textLoc.x-1, textLoc.y+descent,
                                    stringWidth+2, y+height-textLoc.y-descent)) {
                    g.setClip(clipRect);
                    border.paintBorder(c, g, grooveRect.x, grooveRect.y,
                              grooveRect.width, grooveRect.height);
                }

            } else { // titlePos == BOTTOM
              // paint strip above text
                clipRect.setBounds(saveClip);
                if (computeIntersection2(clipRect, textLoc.x-1, y,
                      stringWidth+2, textLoc.y - ascent - y)) {
                    g.setClip(clipRect);
                    border.paintBorder(c, g, grooveRect.x, grooveRect.y,
                              grooveRect.width, grooveRect.height);
                }
            }

            // restore clip
            g.setClip(saveClip);

        } else {
            border.paintBorder(c, g, grooveRect.x, grooveRect.y,
                              grooveRect.width, grooveRect.height);
        }
    }

    g.setColor(getTitleColor());
    g.drawString(getTitle(), textLoc.x, textLoc.y);

    final int index = myOriginalTitle.indexOf('&');
    if (index != -1 && index != myOriginalTitle.length() - 1 && index == myOriginalTitle.lastIndexOf('&') && g instanceof Graphics2D) {
      int x0 = fm.stringWidth(getTitle().substring(0, index));
      int x1 = fm.stringWidth(getTitle().substring(0, index+1));
      ((Graphics2D)g).setPaint(getTitleColor());
      g.drawLine(textLoc.x + x0 - 1, textLoc.y + 1, textLoc.x + x1 - 1, textLoc.y + 1);
      ((Graphics2D)g).setPaint(color);
    }

    g.setFont(font);
    g.setColor(color);
  }
@Override
  public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)