All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.enterprisemath.utils.image.CompositeImageAnimation Maven / Gradle / Ivy

Go to download

Collection of utility classes for large scale projects focusing on robust and testable code.

There is a newer version: 4.1.1
Show newest version
package com.enterprisemath.utils.image;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.builder.ToStringBuilder;

import com.enterprisemath.utils.DomainUtils;
import com.enterprisemath.utils.ValidationUtils;

/**
 * Implementation of image animation which composes several animations together.
 * Precondition is that all of the animations in the composition have
 * same number of frames and same frame duration.
 * 
 * @author radek.hecl
 *
 */
public class CompositeImageAnimation implements ImageAnimation {

    /**
     * Builder object.
     */
    public static class Builder {

        /**
         * Frame width.
         */
        private Integer frameWidth;

        /**
         * Frame height.
         */
        private Integer frameHeight;

        /**
         * Sub animations.
         */
        private List subAnimations = new ArrayList();

        /**
         * Sets frame width.
         * 
         * @param frameWidth frame width
         * @return this instance
         */
        public Builder setFrameWidth(Integer frameWidth) {
            this.frameWidth = frameWidth;
            return this;
        }

        /**
         * Sets frame height.
         * 
         * @param frameHeight frame height
         * @return this instance
         */
        public Builder setFrameHeight(Integer frameHeight) {
            this.frameHeight = frameHeight;
            return this;
        }

        /**
         * Adds sub animation.
         * 
         * @param x position x
         * @param y position y
         * @param animation animation
         * @return this instance
         */
        public Builder addSubAnimation(int x, int y, ImageAnimation animation) {
            subAnimations.add(new SubAnimation(x, y, animation));
            return this;
        }

        /**
         * Builds the result object.
         * 
         * @return created object
         */
        public CompositeImageAnimation build() {
            return new CompositeImageAnimation(this);
        }
    }

    /**
     * Frame width.
     */
    private Integer frameWidth;

    /**
     * Frame height.
     */
    private Integer frameHeight;

    /**
     * Sub animations.
     */
    private List subAnimations;

    /**
     * Creates new instance.
     * 
     * @param builder builder object
     */
    public CompositeImageAnimation(Builder builder) {
        frameWidth = builder.frameWidth;
        frameHeight = builder.frameHeight;
        subAnimations = Collections.unmodifiableList(DomainUtils.softCopyList(builder.subAnimations));
        guardInvariants();
    }

    /**
     * Guards this object to be consistent. Throws exception if this is not the case.
     */
    private void guardInvariants() {
        ValidationUtils.guardPositiveInt(frameWidth, "frameWidth must be positive");
        ValidationUtils.guardPositiveInt(frameHeight, "frameHeight must be positive");
        ValidationUtils.guardPositiveInt(subAnimations.size(), "at least 1 sub animation must be defined");
        int frameDuration = subAnimations.get(0).getAnimation().getFrameDuration();
        int numFrames = subAnimations.get(0).getAnimation().getNumFrames();
        for (SubAnimation sa : subAnimations) {
            ValidationUtils.guardEquals(frameDuration, sa.getAnimation().getFrameDuration(),
                    "frameDuration must be same for all animations in composite");
            ValidationUtils.guardEquals(numFrames, sa.getAnimation().getNumFrames(),
                    "numFrames must be same for all animations in composite");
        }
    }

    @Override
    public int getFrameWidth() {
        return frameWidth;
    }

    @Override
    public int getFrameHeight() {
        return frameHeight;
    }

    @Override
    public int getNumFrames() {
        return subAnimations.get(0).getAnimation().getNumFrames();
    }

    @Override
    public int getFrameDuration() {
        return subAnimations.get(0).getAnimation().getFrameDuration();
    }

    @Override
    public RenderedImage getFrame(int index) {
        BufferedImage img = new BufferedImage(frameWidth, frameHeight, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D g = (Graphics2D)img.getGraphics();
        for (SubAnimation sa : subAnimations) {
            AffineTransform at = AffineTransform.getTranslateInstance(sa.getX(), sa.getY());
            g.drawRenderedImage(sa.getAnimation().getFrame(index), at);
        }
        return img;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    /**
     * Defines sub animation. Sub animation is animation in the part of the frame.
     *
     */
    private static class SubAnimation {

        /**
         * Position x.
         */
        private int x;

        /**
         * Position y.
         */
        private int y;

        /**
         * Animation.
         */
        private ImageAnimation animation;

        /**
         * Creates new instance.
         * @param x position x
         * @param y position y
         * @param animation animation
         */
        private SubAnimation(int x, int y, ImageAnimation animation) {
            this.x = x;
            this.y = y;
            this.animation = animation;
            guardInvariatns();
        }

        /**
         * Guards this object to be consistent. Throws exception if this is not the case.
         */
        private void guardInvariatns() {
            ValidationUtils.guardNotNull(animation, "animation cannot be null");
        }

        /**
         * Returns position x.
         * 
         * @return position x
         */
        public int getX() {
            return x;
        }

        /**
         * Returns position y.
         * 
         * @return position y
         */
        public int getY() {
            return y;
        }

        /**
         * Returns animation.
         * 
         * @return animation
         */
        public ImageAnimation getAnimation() {
            return animation;
        }

        @Override
        public String toString() {
            return ToStringBuilder.reflectionToString(this);
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy