@Override
	protected void paintText( Graphics g, int tabPlacement, Font font, FontMetrics metrics,
		int tabIndex, String title, Rectangle textRect, boolean isSelected )
	{
		g.setFont( font );

		FlatUIUtils.runWithoutRenderingHints( g, oldRenderingHints, () -> {
			// html
			View view = getTextViewForTab( tabIndex );
			if( view != null ) {
				AffineTransform oldTransform = rotateGraphics( g, tabPlacement, textRect );
				Rectangle textRect2 = (oldTransform != null)
					? new Rectangle( textRect.x, textRect.y, textRect.height, textRect.width )
					: textRect;

				view.paint( g, textRect2 );

				if( oldTransform != null )
					((Graphics2D)g).setTransform( oldTransform );
				return;
			}

			// rotate text if necessary
			AffineTransform oldTransform = rotateGraphics( g, tabPlacement, textRect );

			// plain text
			int mnemIndex = FlatLaf.isShowMnemonics() ? tabPane.getDisplayedMnemonicIndexAt( tabIndex ) : -1;
			g.setColor( getTabForeground( tabPlacement, tabIndex, isSelected ) );
			FlatUIUtils.drawStringUnderlineCharAt( tabPane, g, title, mnemIndex,
				textRect.x, textRect.y + metrics.getAscent() );

			if( oldTransform != null )
				((Graphics2D)g).setTransform( oldTransform );
		} );
	}
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