flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java
@Override
	protected void paintRow( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds,
		TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf )
	{
		boolean isEditing = (editingComponent != null && editingRow == row);
		boolean isSelected = tree.isRowSelected( row );
		boolean isDropRow = isDropRow( row );
		boolean needsSelectionPainting = (isSelected || isDropRow) && isPaintSelection();

		// do not paint row if editing
		if( isEditing ) {
			// paint wide selection
			// (do not access cell renderer here to avoid side effect
			// if renderer component is also used as editor component)
			if( isSelected && isWideSelection() ) {
				Color oldColor = g.getColor();
				g.setColor( selectionInactiveBackground );
				paintWideSelection( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf );
				g.setColor( oldColor );
			}
			return;
		}

		boolean hasFocus = FlatUIUtils.isPermanentFocusOwner( tree );
		boolean cellHasFocus = hasFocus && (row == getLeadSelectionRow());

		// if tree is used as cell renderer in another component (e.g. in Rhino JavaScript debugger),
		// check whether that component is focused to get correct selection colors
		if( !hasFocus && isSelected && tree.getParent() instanceof CellRendererPane )
			hasFocus = FlatUIUtils.isPermanentFocusOwner( tree.getParent().getParent() );

		// get renderer component
		Component rendererComponent = currentCellRenderer.getTreeCellRendererComponent( tree,
			path.getLastPathComponent(), isSelected, isExpanded, isLeaf, row, cellHasFocus );

		// renderer background/foreground
		Color oldBackgroundSelectionColor = null;
		if( isSelected && !hasFocus && !isDropRow ) {
			// apply inactive selection background/foreground if tree is not focused
			oldBackgroundSelectionColor = setRendererBackgroundSelectionColor( rendererComponent, selectionInactiveBackground );
			setRendererForeground( rendererComponent, selectionInactiveForeground );

		} else if( isSelected ) {
			// update background/foreground if set via style
			if( selectionBackground != defaultSelectionBackground )
				oldBackgroundSelectionColor = setRendererBackgroundSelectionColor( rendererComponent, selectionBackground );
			if( selectionForeground != defaultSelectionForeground )
				setRendererForeground( rendererComponent, selectionForeground );
		}

		// update focus selection border
		Color oldBorderSelectionColor = null;
		if( isSelected && hasFocus &&
			(!showCellFocusIndicator || tree.getMinSelectionRow() == tree.getMaxSelectionRow()) )
		{
			// remove focus selection border if exactly one item is selected or if showCellFocusIndicator is false
			oldBorderSelectionColor = setRendererBorderSelectionColor( rendererComponent, null );

		} else if( hasFocus && selectionBorderColor != defaultSelectionBorderColor ) {
			// update focus selection border if set via style
			oldBorderSelectionColor = setRendererBorderSelectionColor( rendererComponent, selectionBorderColor );
		}

		// paint selection background
		if( needsSelectionPainting ) {
			// set selection color
			Color oldColor = g.getColor();
			g.setColor( isDropRow
				? UIManager.getColor( "Tree.dropCellBackground" )
				: (rendererComponent instanceof DefaultTreeCellRenderer
					? ((DefaultTreeCellRenderer)rendererComponent).getBackgroundSelectionColor()
					: (hasFocus ? selectionBackground : selectionInactiveBackground)) );

			if( isWideSelection() ) {
				// wide selection
				paintWideSelection( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf );
			} else {
				// non-wide selection
				paintCellBackground( g, rendererComponent, bounds );
			}

			// this is actually not necessary because renderer should always set color
			// before painting, but doing anyway to avoid any side effect (in bad renderers)
			g.setColor( oldColor );
		} else {
			// paint cell background if DefaultTreeCellRenderer.getBackgroundNonSelectionColor() is set
			if( rendererComponent instanceof DefaultTreeCellRenderer ) {
				DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) rendererComponent;
				Color bg = renderer.getBackgroundNonSelectionColor();
				if( bg != null && !bg.equals( defaultCellNonSelectionBackground ) ) {
					Color oldColor = g.getColor();
					g.setColor( bg );
					paintCellBackground( g, rendererComponent, bounds );
					g.setColor( oldColor );
				}
			}
		}

		// paint renderer
		rendererPane.paintComponent( g, rendererComponent, tree, bounds.x, bounds.y, bounds.width, bounds.height, true );

		// restore background selection color and border selection color
		if( oldBackgroundSelectionColor != null )
			((DefaultTreeCellRenderer)rendererComponent).setBackgroundSelectionColor( oldBackgroundSelectionColor );
		if( oldBorderSelectionColor != null )
			((DefaultTreeCellRenderer)rendererComponent).setBorderSelectionColor( oldBorderSelectionColor );
	}
/**
	 * Same as super.paintRow(), but supports wide selection and uses
	 * inactive selection background/foreground if tree is not focused.
	 */
Same as super.paintRow(), but supports wide selection and uses
inactive selection background/foreground if tree is not focused.
Same as super . paintRow () but supports wide selection and uses inactive selection background / foreground if tree is not focused .
@Override
	protected void paintRow( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds,
		TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf )
	{
		boolean isEditing = (editingComponent != null && editingRow == row);
		boolean isSelected = tree.isRowSelected( row );
		boolean isDropRow = isDropRow( row );
		boolean needsSelectionPainting = (isSelected || isDropRow) && isPaintSelection();
		if( isEditing ) {
			if( isSelected && isWideSelection() ) {
				Color oldColor = g.getColor();
				g.setColor( selectionInactiveBackground );
				paintWideSelection( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf );
				g.setColor( oldColor );
			}
			return;
		}
		boolean hasFocus = FlatUIUtils.isPermanentFocusOwner( tree );
		boolean cellHasFocus = hasFocus && (row == getLeadSelectionRow());
		if( !hasFocus && isSelected && tree.getParent() instanceof CellRendererPane )
			hasFocus = FlatUIUtils.isPermanentFocusOwner( tree.getParent().getParent() );
		Component rendererComponent = currentCellRenderer.getTreeCellRendererComponent( tree,
			path.getLastPathComponent(), isSelected, isExpanded, isLeaf, row, cellHasFocus );
		Color oldBackgroundSelectionColor = null;
		if( isSelected && !hasFocus && !isDropRow ) {
			oldBackgroundSelectionColor = setRendererBackgroundSelectionColor( rendererComponent, selectionInactiveBackground );
			setRendererForeground( rendererComponent, selectionInactiveForeground );
		} else if( isSelected ) {
			if( selectionBackground != defaultSelectionBackground )
				oldBackgroundSelectionColor = setRendererBackgroundSelectionColor( rendererComponent, selectionBackground );
			if( selectionForeground != defaultSelectionForeground )
				setRendererForeground( rendererComponent, selectionForeground );
		}
		Color oldBorderSelectionColor = null;
		if( isSelected && hasFocus &&
			(!showCellFocusIndicator || tree.getMinSelectionRow() == tree.getMaxSelectionRow()) )
		{
			oldBorderSelectionColor = setRendererBorderSelectionColor( rendererComponent, null );
		} else if( hasFocus && selectionBorderColor != defaultSelectionBorderColor ) {
			 if set via style
			oldBorderSelectionColor = setRendererBorderSelectionColor( rendererComponent, selectionBorderColor );
		}
		if( needsSelectionPainting ) {
			Color oldColor = g.getColor();
			g.setColor( isDropRow
				? UIManager.getColor( "Tree.dropCellBackground" )
				: (rendererComponent instanceof DefaultTreeCellRenderer
					? ((DefaultTreeCellRenderer)rendererComponent).getBackgroundSelectionColor()
					: (hasFocus ? selectionBackground : selectionInactiveBackground)) );
			if( isWideSelection() ) {
				paintWideSelection( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf );
			} else {
				paintCellBackground( g, rendererComponent, bounds );
			}
			g.setColor( oldColor );
		} else {
			if( rendererComponent instanceof DefaultTreeCellRenderer ) {
				DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) rendererComponent;
				Color bg = renderer.getBackgroundNonSelectionColor();
				if( bg != null && !bg.equals( defaultCellNonSelectionBackground ) ) {
					Color oldColor = g.getColor();
					g.setColor( bg );
					paintCellBackground( g, rendererComponent, bounds );
					g.setColor( oldColor );
				}
			}
		}
		rendererPane.paintComponent( g, rendererComponent, tree, bounds.x, bounds.y, bounds.width, bounds.height, true );
		if( oldBackgroundSelectionColor != null )
			((DefaultTreeCellRenderer)rendererComponent).setBackgroundSelectionColor( oldBackgroundSelectionColor );
		if( oldBorderSelectionColor != null )
			((DefaultTreeCellRenderer)rendererComponent).setBorderSelectionColor( oldBorderSelectionColor );
	}
@ Override protected void paintRow ( Graphics g , Rectangle clipBounds , Insets insets , Rectangle bounds , TreePath path , int row , boolean isExpanded , boolean hasBeenExpanded , boolean isLeaf ) { boolean isEditing = ( editingComponent != null && editingRow == row ) ; boolean isSelected = tree . isRowSelected ( row ) ; boolean isDropRow = isDropRow ( row ) ; boolean needsSelectionPainting = ( isSelected || isDropRow ) && isPaintSelection ( ) ; if ( isEditing ) { if ( isSelected && isWideSelection ( ) ) { Color oldColor = g . getColor ( ) ; g . setColor ( selectionInactiveBackground ) ; paintWideSelection ( g , clipBounds , insets , bounds , path , row , isExpanded , hasBeenExpanded , isLeaf ) ; g . setColor ( oldColor ) ; } return ; } boolean hasFocus = FlatUIUtils . isPermanentFocusOwner ( tree ) ; boolean cellHasFocus = hasFocus && ( row == getLeadSelectionRow ( ) ) ; if ( ! hasFocus && isSelected && tree . getParent ( ) instanceof CellRendererPane ) hasFocus = FlatUIUtils . isPermanentFocusOwner ( tree . getParent ( ) . getParent ( ) ) ; Component rendererComponent = currentCellRenderer . getTreeCellRendererComponent ( tree , path . getLastPathComponent ( ) , isSelected , isExpanded , isLeaf , row , cellHasFocus ) ; Color oldBackgroundSelectionColor = null ; if ( isSelected && ! hasFocus && ! isDropRow ) { oldBackgroundSelectionColor = setRendererBackgroundSelectionColor ( rendererComponent , selectionInactiveBackground ) ; setRendererForeground ( rendererComponent , selectionInactiveForeground ) ; } else if ( isSelected ) { if ( selectionBackground != defaultSelectionBackground ) oldBackgroundSelectionColor = setRendererBackgroundSelectionColor ( rendererComponent , selectionBackground ) ; if ( selectionForeground != defaultSelectionForeground ) setRendererForeground ( rendererComponent , selectionForeground ) ; } Color oldBorderSelectionColor = null ; if ( isSelected && hasFocus && ( ! showCellFocusIndicator || tree . getMinSelectionRow ( ) == tree . getMaxSelectionRow ( ) ) ) { oldBorderSelectionColor = setRendererBorderSelectionColor ( rendererComponent , null ) ; } else if ( hasFocus && selectionBorderColor != defaultSelectionBorderColor ) { oldBorderSelectionColor = setRendererBorderSelectionColor ( rendererComponent , selectionBorderColor ) ; } if ( needsSelectionPainting ) { Color oldColor = g . getColor ( ) ; g . setColor ( isDropRow ? UIManager . getColor ( "Tree.dropCellBackground" ) : ( rendererComponent instanceof DefaultTreeCellRenderer ? ( ( DefaultTreeCellRenderer ) rendererComponent ) . getBackgroundSelectionColor ( ) : ( hasFocus ? selectionBackground : selectionInactiveBackground ) ) ) ; if ( isWideSelection ( ) ) { paintWideSelection ( g , clipBounds , insets , bounds , path , row , isExpanded , hasBeenExpanded , isLeaf ) ; } else { paintCellBackground ( g , rendererComponent , bounds ) ; } g . setColor ( oldColor ) ; } else { if ( rendererComponent instanceof DefaultTreeCellRenderer ) { DefaultTreeCellRenderer renderer = ( DefaultTreeCellRenderer ) rendererComponent ; Color bg = renderer . getBackgroundNonSelectionColor ( ) ; if ( bg != null && ! bg . equals ( defaultCellNonSelectionBackground ) ) { Color oldColor = g . getColor ( ) ; g . setColor ( bg ) ; paintCellBackground ( g , rendererComponent , bounds ) ; g . setColor ( oldColor ) ; } } } rendererPane . paintComponent ( g , rendererComponent , tree , bounds . x , bounds . y , bounds . width , bounds . height , true ) ; if ( oldBackgroundSelectionColor != null ) ( ( DefaultTreeCellRenderer ) rendererComponent ) . setBackgroundSelectionColor ( oldBackgroundSelectionColor ) ; if ( oldBorderSelectionColor != null ) ( ( DefaultTreeCellRenderer ) rendererComponent ) . setBorderSelectionColor ( oldBorderSelectionColor ) ; }
Same as super.paintRow(), but supports wide selection and uses
 inactive selection background/foreground if tree is not focused.
Same as super . paintRow () but supports wide selection and uses inactive selection background / foreground if tree is not focused .
// do not paint row if editing // paint wide selection // (do not access cell renderer here to avoid side effect // if renderer component is also used as editor component) // if tree is used as cell renderer in another component (e.g. in Rhino JavaScript debugger), // check whether that component is focused to get correct selection colors // get renderer component // renderer background/foreground // apply inactive selection background/foreground if tree is not focused // update background/foreground if set via style // update focus selection border // remove focus selection border if exactly one item is selected or if showCellFocusIndicator is false // update focus selection border if set via style // paint selection background // set selection color // wide selection // non-wide selection // this is actually not necessary because renderer should always set color // before painting, but doing anyway to avoid any side effect (in bad renderers) // paint cell background if DefaultTreeCellRenderer.getBackgroundNonSelectionColor() is set // paint renderer // restore background selection color and border selection color