public static void paintIcon( AnimatedIcon icon, Component c, Graphics g, int x, int y ) {
			if( !isAnimationEnabled( icon, c ) ) {
				// paint without animation if animation is disabled or
				// component is not a JComponent and therefore does not support
				// client properties, which are required to keep animation state
				paintIconImpl( icon, c, g, x, y, null );
				return;
			}

			JComponent jc = (JComponent) c;
			Object key = icon.getClientPropertyKey();
			AnimationSupport as = (AnimationSupport) jc.getClientProperty( key );
			if( as == null ) {
				// painted first time --> do not animate, but remember current component value
				as = new AnimationSupport();
				as.startValue = as.targetValue = as.animatedValue = icon.getValue( c );
				as.x = x;
				as.y = y;
				jc.putClientProperty( key, as );
			} else {
				// get component value
				float value = icon.getValue( c );

				if( value != as.targetValue ) {
					// value changed --> (re)start animation

					if( as.animator == null ) {
						// create animator
						AnimationSupport as2 = as;
						as.animator = new Animator( icon.getAnimationDuration(), fraction -> {
							// check whether component was removed while animation is running
							if( !c.isDisplayable() ) {
								as2.animator.stop();
								return;
							}

							// compute animated value
							as2.animatedValue = as2.startValue + ((as2.targetValue - as2.startValue) * fraction);
							as2.fraction = fraction;

							// repaint icon
							c.repaint( as2.x, as2.y, icon.getIconWidth(), icon.getIconHeight() );
						}, () -> {
							as2.startValue = as2.animatedValue = as2.targetValue;
							as2.animator = null;
						} );
					}

					if( as.animator.isRunning() ) {
						// if animation is still running, restart it from the current
						// animated value to the new target value with reduced duration
						as.animator.cancel();
						int duration2 = (int) (icon.getAnimationDuration() * as.fraction);
						if( duration2 > 0 )
							as.animator.setDuration( duration2 );
						as.startValue = as.animatedValue;
					} else {
						// new animation
						as.animator.setDuration( icon.getAnimationDuration() );
						as.animator.setResolution( icon.getAnimationResolution() );
						as.animator.setInterpolator( icon.getAnimationInterpolator() );

						as.animatedValue = as.startValue;
					}

					as.targetValue = value;
					as.animator.start();
				}

				as.x = x;
				as.y = y;
			}

			paintIconImpl( icon, c, g, x, y, as );
		}
Animation support class that stores the animation state and implements the animation.
flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedIcon.java