@Override
	protected void paintTab( Graphics g, int tabPlacement, Rectangle[] rects,
		int tabIndex, Rectangle iconRect, Rectangle textRect )
	{
		Rectangle tabRect = rects[tabIndex];
		int x = tabRect.x;
		int y = tabRect.y;
		int w = tabRect.width;
		int h = tabRect.height;
		boolean isSelected = (tabIndex == tabPane.getSelectedIndex());

		// paint background
		if( tabsOpaque || tabPane.isOpaque() )
			paintTabBackground( g, tabPlacement, tabIndex, x, y, w, h, isSelected );

		// paint border
		paintTabBorder( g, tabPlacement, tabIndex, x, y, w, h, isSelected );

		// paint tab close button
		if( isTabClosable( tabIndex ) )
			paintTabCloseButton( g, tabIndex, x, y, w, h );

		// paint selection indicator
		if( isSelected )
			paintTabSelection( g, tabPlacement, tabIndex, x, y, w, h );

		if( tabPane.getTabComponentAt( tabIndex ) != null )
			return;

		// layout title and icon
		String title = tabPane.getTitleAt( tabIndex );
		Icon icon = getIconForTab( tabIndex );
		Font font = tabPane.getFont();
		FontMetrics metrics = tabPane.getFontMetrics( font );
		boolean isCompact = (icon != null && !isSelected && getTabWidthMode() == WIDTH_MODE_COMPACT && isHorizontalOrRotated( tabPlacement ));
		if( isCompact )
			title = null;
		String clippedTitle = layoutAndClipLabel( tabPlacement, metrics, tabIndex, title, icon, tabRect, iconRect, textRect, isSelected );

/*debug
		g.setColor( Color.red );
		g.drawRect( tabRect.x, tabRect.y, tabRect.width - 1, tabRect.height - 1 );
		g.setColor( Color.green );
		Rectangle tabRect2 = FlatUIUtils.subtractInsets( tabRect, getTabInsetsRotated( tabPlacement, tabIndex, getRealTabRotation( tabPlacement ) ) );
		g.drawRect( tabRect2.x, tabRect2.y, tabRect2.width - 1, tabRect2.height - 1 );
		g.setColor( Color.blue );
		g.drawRect( iconRect.x, iconRect.y, iconRect.width - 1, iconRect.height - 1 );
		g.setColor( Color.magenta );
		g.drawRect( textRect.x, textRect.y, textRect.width - 1, textRect.height - 1 );
		g.setColor( Color.orange );
		Rectangle closeHitArea = getTabCloseHitArea( tabIndex );
		if( moreTabsButton != null ) {
			Point viewPosition = tabViewport.getViewPosition();
			closeHitArea.x -= tabViewport.getX() - viewPosition.x;
			closeHitArea.y -= tabViewport.getY() - viewPosition.y;
		}
		g.drawRect( closeHitArea.x, closeHitArea.y, closeHitArea.width - 1, closeHitArea.height - 1 );
debug*/

		// special title clipping for scroll layout where title of last visible tab on right side may be truncated
		if( tabViewport != null && (tabPlacement == TOP || tabPlacement == BOTTOM) ) {
			Rectangle viewRect = tabViewport.getViewRect();
			viewRect.width -= 4; // subtract width of cropped edge
			if( !viewRect.contains( textRect ) ) {
				Rectangle r = viewRect.intersection( textRect );
				if( r.x > viewRect.x )
					clippedTitle = JavaCompatibility.getClippedString( null, metrics, title, r.width );
			}
		}

		// paint title and icon
		if( !isCompact )
			paintText( g, tabPlacement, font, metrics, tabIndex, clippedTitle, textRect, isSelected );
		paintIcon( g, tabPlacement, tabIndex, icon, iconRect, isSelected );
	}
The content border insets are used to create a separator between tabs and content.
If client property JTabbedPane.hasFullBorder is true, then the content border insets
are also used for the border.
flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java