private int calculateTabWidthImpl( int tabPlacement, int tabIndex, FontMetrics metrics, boolean rotated ) {
		int tabWidthMode = getTabWidthMode();
		if( tabWidthMode == WIDTH_MODE_EQUAL && isHorizontalOrRotated( tabPlacement ) && !inCalculateEqual ) {
			inCalculateEqual = true;
			try {
				return isHorizontalTabPlacement( tabPlacement )
					? calculateMaxTabWidth( tabPlacement )
					: calculateMaxTabHeight( tabPlacement );
			} finally {
				inCalculateEqual = false;
			}
		}

		// update textIconGap before used in super class
		textIconGap = scale( textIconGapUnscaled );

		int tabWidth;
		Icon icon;
		if( tabWidthMode == WIDTH_MODE_COMPACT &&
			tabIndex != tabPane.getSelectedIndex() &&
			isHorizontalOrRotated( tabPlacement ) &&
			tabPane.getTabComponentAt( tabIndex ) == null &&
			(icon = getIconForTab( tabIndex )) != null )
		{
			Insets tabInsets = getTabInsets( tabPlacement, tabIndex );
			tabWidth = icon.getIconWidth() + tabInsets.left + tabInsets.right;
		} else {
			int iconPlacement = clientPropertyInt( tabPane, TABBED_PANE_TAB_ICON_PLACEMENT, tabIconPlacement );
			if( (iconPlacement == TOP || iconPlacement == BOTTOM) &&
				tabPane.getTabComponentAt( tabIndex ) == null &&
				(icon = getIconForTab( tabIndex )) != null )
			{
				// TOP and BOTTOM icon placement
				tabWidth = icon.getIconWidth();

				View view = getTextViewForTab( tabIndex );
				if( view != null )
					tabWidth = Math.max( tabWidth, (int) view.getPreferredSpan( View.X_AXIS ) );
				else {
					String title = tabPane.getTitleAt( tabIndex );
					if( title != null )
						tabWidth = Math.max( tabWidth, metrics.stringWidth( title ) );
				}

				Insets tabInsets = getTabInsets( tabPlacement, tabIndex );
				tabWidth += tabInsets.left + tabInsets.right;
			} else {
				tabWidth = super.calculateTabWidth( tabPlacement, tabIndex, metrics ) - 3 /* was added by superclass */;

				// tab components are not rotated
				Component tabComponent;
				if( rotated && (tabComponent = tabPane.getTabComponentAt( tabIndex )) != null ) {
					Dimension prefSize = tabComponent.getPreferredSize();
					tabWidth = tabWidth - prefSize.width + prefSize.height;
				}
			}
		}

		// make tab wider if closable
		if( isTabClosable( tabIndex ) )
			tabWidth += closeIcon.getIconWidth();

		// apply minimum and maximum tab width
		int min = getTabClientPropertyInt( tabIndex, TABBED_PANE_MINIMUM_TAB_WIDTH, minimumTabWidth );
		int max = getTabClientPropertyInt( tabIndex, TABBED_PANE_MAXIMUM_TAB_WIDTH, maximumTabWidth );
		if( min > 0 )
			tabWidth = Math.max( tabWidth, scale( min ) );
		if( max > 0 && tabPane.getTabComponentAt( tabIndex ) == null )
			tabWidth = Math.min( tabWidth, scale( max ) );

		return tabWidth;
	}
Repaint rollover tab, but deferred and only once.
This is to avoid unnecessary repaints in case of temporary changes to rollover tab.

E.g. when moving mouse over a single tab, a re-layout may occur and
set rollover tab to -1, in BasicTabbedPaneUI.TabbedPaneLayout.layoutContainer() and
BasicTabbedPaneUI.TabbedPaneScrollLayout.layoutContainer(), and subsequently
change rollover tab back to previous value.
flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java