mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 05:50:53 +03:00
AnimatedPainter:
Some checks failed
CI / build (1.8) (push) Has been cancelled
CI / build (11) (push) Has been cancelled
CI / build (14) (push) Has been cancelled
CI / build (15) (push) Has been cancelled
CI / build (9) (push) Has been cancelled
CI / snapshot (push) Has been cancelled
CI / release (push) Has been cancelled
Some checks failed
CI / build (1.8) (push) Has been cancelled
CI / build (11) (push) Has been cancelled
CI / build (14) (push) Has been cancelled
CI / build (15) (push) Has been cancelled
CI / build (9) (push) Has been cancelled
CI / snapshot (push) Has been cancelled
CI / release (push) Has been cancelled
- renamed `getValues()` to `getAnimatableValues()` - renamed `getClientPropertyKey()` to `getAnimationClientPropertyKey()` - AnimatedPainterSupport improvements
This commit is contained in:
@@ -25,10 +25,12 @@ import javax.swing.border.Border;
|
||||
/**
|
||||
* Border that automatically animates painting on component value changes.
|
||||
* <p>
|
||||
* {@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.
|
||||
* <p>
|
||||
* Example for an animated border:
|
||||
* <pre>
|
||||
@@ -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 ) );
|
||||
* }
|
||||
|
||||
@@ -25,16 +25,23 @@ import javax.swing.JComponent;
|
||||
/**
|
||||
* Icon that automatically animates painting on component value changes.
|
||||
* <p>
|
||||
* {@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.
|
||||
* <p>
|
||||
* Example for an animated icon:
|
||||
* <pre>
|
||||
* 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;
|
||||
* </pre>
|
||||
*
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,15 +25,17 @@ import com.formdev.flatlaf.util.Animator.Interpolator;
|
||||
/**
|
||||
* Painter that automatically animates painting on component value(s) changes.
|
||||
* <p>
|
||||
* {@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.
|
||||
* <p>
|
||||
* See {@link AnimatedBorder} or {@link AnimatedIcon} for examples.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user