diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedBorder.java index afb7a8e2..aa0ec72b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedBorder.java @@ -25,10 +25,12 @@ import javax.swing.border.Border; /** * Border that automatically animates painting on component value changes. *
- * {@link #getValues(Component)} returns the value(s) of the component. + * {@link #getAnimatableValues(Component)} returns the animatable value(s) of the component. * If the value(s) have changed, then {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])} * is invoked multiple times with animated value(s) (from old value(s) to new value(s)). - * If {@link #getValues(Component)} returns multiple values, then each value gets its own independent animation. + * If {@link #getAnimatableValues(Component)} returns multiple values, then each value + * gets its own independent animation, which may start/end at different points in time, + * may have different duration, resolution and interpolator. *
* Example for an animated border: *
@@ -36,6 +38,11 @@ import javax.swing.border.Border;
* implements AnimatedBorder
* {
* @Override
+ * public float[] getAnimatableValues( Component c ) {
+ * return new float[] { c.isFocusOwner() ? 1 : 0 };
+ * }
+ *
+ * @Override
* public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
* int lh = UIScale.scale( 2 );
*
@@ -44,11 +51,6 @@ import javax.swing.border.Border;
* }
*
* @Override
- * public float[] getValues( Component c ) {
- * return new float[] { c.isFocusOwner() ? 1 : 0 };
- * }
- *
- * @Override
* public Insets getBorderInsets( Component c ) {
* return UIScale.scale( new Insets( 4, 4, 4, 4 ) );
* }
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedIcon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedIcon.java
index 5f351bcc..2381bb91 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedIcon.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedIcon.java
@@ -25,16 +25,23 @@ import javax.swing.JComponent;
/**
* Icon that automatically animates painting on component value changes.
*
- * {@link #getValues(Component)} returns the value(s) of the component.
+ * {@link #getAnimatableValues(Component)} returns the animatable value(s) of the component.
* If the value(s) have changed, then {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* is invoked multiple times with animated value(s) (from old value(s) to new value(s)).
- * If {@link #getValues(Component)} returns multiple values, then each value gets its own independent animation.
+ * If {@link #getAnimatableValues(Component)} returns multiple values, then each value
+ * gets its own independent animation, which may start/end at different points in time,
+ * may have different duration, resolution and interpolator.
*
* Example for an animated icon:
*
* private class MyAnimatedIcon
* implements AnimatedIcon
* {
+ * @Override
+ * public float[] getAnimatableValues( Component c ) {
+ * return new float[] { ((AbstractButton)c).isSelected() ? 1 : 0 };
+ * }
+ *
* @Override public int getIconWidth() { return 100; }
* @Override public int getIconHeight() { return 20; }
*
@@ -44,11 +51,6 @@ import javax.swing.JComponent;
* g.drawRect( x, y, width - 1, height - 1 );
* g.fillRect( x, y, Math.round( width * animatedValues[0] ), height );
* }
- *
- * @Override
- * public float[] getValues( Component c ) {
- * return new float[] { ((AbstractButton)c).isSelected() ? 1 : 0 };
- * }
* }
*
* // sample usage
@@ -57,7 +59,7 @@ import javax.swing.JComponent;
*
*
* Animation works only if the component passed to {@link #paintIcon(Component, Graphics, int, int)}
- * is a instance of {@link JComponent}.
+ * is an instance of {@link JComponent}.
* A client property is set on the component to store the animation state.
*
* @author Karl Tauber
@@ -65,6 +67,17 @@ import javax.swing.JComponent;
public interface AnimatedIcon
extends Icon, AnimatedPainter
{
+ /**
+ * {@inheritDoc}
+ *
+ * @since 2
+ */
+ @Override
+ default float[] getAnimatableValues( Component c ) {
+ // for compatibility
+ return new float[] { getValue( c ) };
+ }
+
/**
* Invokes {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}.
*/
@@ -80,6 +93,7 @@ public interface AnimatedIcon
*/
@Override
default void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
+ // for compatibility
paintIconAnimated( c, g, x, y, animatedValues[0] );
}
@@ -101,30 +115,41 @@ public interface AnimatedIcon
}
/**
- * {@inheritDoc}
- *
- * @since 2
- */
- @Override
- default float[] getValues( Component c ) {
- return new float[] { getValue( c ) };
- }
-
- /**
- * Gets the value of the component.
+ * Gets the animatable value of the component.
*
* This can be any value and depends on the component.
* If the value changes, then this class animates from the old value to the new one.
*
* For a toggle button this could be {@code 0} for off and {@code 1} for on.
*
- * @deprecated override {@link #getValues(Component)} instead
+ * @deprecated override {@link #getAnimatableValues(Component)} instead
*/
@Deprecated
default float getValue( Component c ) {
return 0;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @since TODO
+ */
+ @Override
+ default Object getAnimationClientPropertyKey() {
+ // for compatibility
+ return getClientPropertyKey();
+ }
+
+ /**
+ * Returns the client property key used to store the animation support.
+ *
+ * @deprecated override {@link #getAnimationClientPropertyKey()} instead
+ */
+ @Deprecated
+ default Object getClientPropertyKey() {
+ return getClass();
+ }
+
//---- class AnimationSupport ---------------------------------------------
/**
@@ -138,7 +163,7 @@ public interface AnimatedIcon
*/
@Deprecated
public static void paintIcon( AnimatedIcon icon, Component c, Graphics g, int x, int y ) {
- AnimatedPainterSupport.paint( icon, c, g, x, y, icon.getIconWidth(), icon.getIconHeight() );
+ AnimatedPainterSupport.paint( icon, c, (Graphics2D) g, x, y, icon.getIconWidth(), icon.getIconHeight() );
}
/**
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedPainter.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedPainter.java
index 0ff83de7..58270a06 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedPainter.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedPainter.java
@@ -25,15 +25,17 @@ import com.formdev.flatlaf.util.Animator.Interpolator;
/**
* Painter that automatically animates painting on component value(s) changes.
*
- * {@link #getValues(Component)} returns the value(s) of the component.
+ * {@link #getAnimatableValues(Component)} returns the animatable value(s) of the component.
* If the value(s) have changed, then {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* is invoked multiple times with animated value(s) (from old value(s) to new value(s)).
- * If {@link #getValues(Component)} returns multiple values, then each value gets its own independent animation.
+ * If {@link #getAnimatableValues(Component)} returns multiple values, then each value
+ * gets its own independent animation, which may start/end at different points in time,
+ * may have different duration, resolution and interpolator.
*
* See {@link AnimatedBorder} or {@link AnimatedIcon} for examples.
*
* Animation works only if the component passed to {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}
- * is a instance of {@link JComponent}.
+ * is an instance of {@link JComponent}.
* A client property is set on the component to store the animation state.
*
* @author Karl Tauber
@@ -41,10 +43,23 @@ import com.formdev.flatlaf.util.Animator.Interpolator;
*/
public interface AnimatedPainter
{
+ /**
+ * Gets the animatable value(s) of the component.
+ *
+ * This can be any value(s) and depends on the component.
+ * If the value(s) changes, then this class animates from the old value(s) to the new ones.
+ * If multiple values are returned, then each value gets its own independent animation.
+ *
+ * For a toggle button this could be {@code 0} for off and {@code 1} for on.
+ * A complex check box could return values for selected, hover, pressed and focused states.
+ * The painter then can show independent animations for those states.
+ */
+ float[] getAnimatableValues( Component c );
+
/**
* Starts painting.
* Either invokes {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
- * once to paint current value(s) (see {@link #getValues(Component)}. Or if value(s) has
+ * once to paint current value(s) (see {@link #getAnimatableValues(Component)}. Or if value(s) has
* changed, compared to last painting, then it starts an animation and invokes
* {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* multiple times with animated value(s) (from old value(s) to new value(s)).
@@ -57,7 +72,7 @@ public interface AnimatedPainter
* @param height the height of the paint area
*/
default void paintWithAnimation( Component c, Graphics g, int x, int y, int width, int height ) {
- AnimatedPainterSupport.paint( this, c, g, x, y, width, height );
+ AnimatedPainterSupport.paint( this, c, (Graphics2D) g, x, y, width, height );
}
/**
@@ -71,9 +86,9 @@ public interface AnimatedPainter
* @param y the y coordinate of the paint area
* @param width the width of the paint area
* @param height the height of the paint area
- * @param animatedValues the animated values, which are either equal to what {@link #getValues(Component)}
+ * @param animatedValues the animated values, which are either equal to what {@link #getAnimatableValues(Component)}
* returned, or somewhere between the previous values and the latest values
- * that {@link #getValues(Component)} returned
+ * that {@link #getAnimatableValues(Component)} returned
*/
void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues );
@@ -91,17 +106,6 @@ public interface AnimatedPainter
c.repaint( x, y, width, height );
}
- /**
- * Gets the value(s) of the component.
- *
- * This can be any value and depends on the component.
- * If the value(s) changes, then this class animates from the old value(s) to the new ones.
- * If multiple values are returned, then each value gets its own independent animation.
- *
- * For a toggle button this could be {@code 0} for off and {@code 1} for on.
- */
- float[] getValues( Component c );
-
/**
* Returns whether animation is enabled for this painter (default is {@code true}).
*/
@@ -161,7 +165,7 @@ public interface AnimatedPainter
/**
* Returns the client property key used to store the animation support.
*/
- default Object getClientPropertyKey() {
+ default Object getAnimationClientPropertyKey() {
return getClass();
}
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedPainterSupport.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedPainterSupport.java
index 1492c31f..4a41fdbe 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedPainterSupport.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/AnimatedPainterSupport.java
@@ -17,7 +17,6 @@
package com.formdev.flatlaf.util;
import java.awt.Component;
-import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
@@ -29,7 +28,8 @@ import javax.swing.JComponent;
*/
class AnimatedPainterSupport
{
- private int valueIndex;
+ private final int valueIndex;
+
private float startValue;
private float targetValue;
private float animatedValue;
@@ -43,22 +43,26 @@ class AnimatedPainterSupport
private int width;
private int height;
- static void paint( AnimatedPainter painter, Component c, Graphics g,
+ private AnimatedPainterSupport( int valueIndex ) {
+ this.valueIndex = valueIndex;
+ }
+
+ static void paint( AnimatedPainter painter, Component c, Graphics2D g,
int x, int y, int width, int height )
{
+ // get animatable component values
+ float[] values = painter.getAnimatableValues( c );
+
if( !isAnimationEnabled( painter, 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
- painter.paintAnimated( c, (Graphics2D) g, x, y, width, height, painter.getValues( c ) );
+ painter.paintAnimated( c, g, x, y, width, height, values );
return;
}
- // get component values
- float values[] = painter.getValues( c );
-
JComponent jc = (JComponent) c;
- Object key = painter.getClientPropertyKey();
+ Object key = painter.getAnimationClientPropertyKey();
AnimatedPainterSupport[] ass = (AnimatedPainterSupport[]) jc.getClientProperty( key );
// check whether length of values array has changed
@@ -83,8 +87,7 @@ class AnimatedPainterSupport
if( as == null ) {
// painted first time --> do not animate, but remember current component value
- as = new AnimatedPainterSupport();
- as.valueIndex = i;
+ as = new AnimatedPainterSupport( i );
as.startValue = as.targetValue = as.animatedValue = value;
ass[i] = as;
} else if( value != as.targetValue ) {
@@ -159,7 +162,7 @@ class AnimatedPainterSupport
for( int i = 0; i < ass.length; i++ )
animatedValues[i] = ass[i].animatedValue;
- painter.paintAnimated( c, (Graphics2D) g, x, y, width, height, animatedValues );
+ painter.paintAnimated( c, g, x, y, width, height, animatedValues );
}
private static boolean isAnimationEnabled( AnimatedPainter painter, Component c ) {
@@ -170,7 +173,7 @@ class AnimatedPainterSupport
if( !isAnimationEnabled( painter, c ) )
return;
- AnimatedPainterSupport[] ass = (AnimatedPainterSupport[]) ((JComponent)c).getClientProperty( painter.getClientPropertyKey() );
+ AnimatedPainterSupport[] ass = (AnimatedPainterSupport[]) ((JComponent)c).getClientProperty( painter.getAnimationClientPropertyKey() );
if( ass != null ) {
for( int i = 0; i < ass.length; i++ ) {
AnimatedPainterSupport as = ass[i];
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatAnimatedBorderTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatAnimatedBorderTest.java
index 46e17f96..fa84f7c3 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatAnimatedBorderTest.java
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatAnimatedBorderTest.java
@@ -244,7 +244,7 @@ public class FlatAnimatedBorderTest
}
@Override
- public float[] getValues( Component c ) {
+ public float[] getAnimatableValues( Component c ) {
return new float[] { FlatUIUtils.isPermanentFocusOwner( c ) ? 1 : 0 };
}
@@ -315,7 +315,7 @@ public class FlatAnimatedBorderTest
}
@Override
- public float[] getValues( Component c ) {
+ public float[] getAnimatableValues( Component c ) {
return new float[] { FlatUIUtils.isPermanentFocusOwner( c ) ? 1 : 0 };
}
@@ -416,7 +416,7 @@ public class FlatAnimatedBorderTest
}
@Override
- public float[] getValues( Component c ) {
+ public float[] getAnimatableValues( Component c ) {
return new float[] { FlatUIUtils.isPermanentFocusOwner( c ) ? 1 : 0 };
}
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatAnimatedIconTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatAnimatedIconTest.java
index 12f8bc22..3cf352c1 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatAnimatedIconTest.java
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatAnimatedIconTest.java
@@ -221,7 +221,7 @@ public class FlatAnimatedIconTest
}
@Override
- public float[] getValues( Component c ) {
+ public float[] getAnimatableValues( Component c ) {
return new float[] { ((JRadioButton)c).isSelected() ? 1 : 0 };
}
@@ -266,7 +266,7 @@ public class FlatAnimatedIconTest
}
@Override
- public float[] getValues( Component c ) {
+ public float[] getAnimatableValues( Component c ) {
return new float[] { ((AbstractButton)c).isSelected() ? 1 : 0 };
}
@@ -342,7 +342,7 @@ public class FlatAnimatedIconTest
}
@Override
- public float[] getValues( Component c ) {
+ public float[] getAnimatableValues( Component c ) {
AbstractButton b = (AbstractButton) c;
ButtonModel bm = b.getModel();
@@ -392,7 +392,7 @@ public class FlatAnimatedIconTest
}
@Override
- public float[] getValues( Component c ) {
+ public float[] getAnimatableValues( Component c ) {
return new float[] { ((AbstractButton)c).isSelected() ? 1 : 0 };
}