Java的:移动的JLabel两次使用定时器 [英] Java: Moving jLabel twice using Timer

查看:266
本文介绍了Java的:移动的JLabel两次使用定时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在JFrame的项目工作:

的JLabel 我想把它移到动画,然后将另一个的JLabel
换句话说,我想第一个的JLabel 当它完成了中移动,然后,第二个的JLabel
移动。

我已经尝试过,没有成功。我要搬到一个函数的JLabel
和IFII尝试使用它两个的JLabel,无论是移动的JLabel在同一时间,我不希望这种事情发生。

你能帮我做到这一点,太感谢你了。

下面是我具备的功能:

 公共无效MoveFor​​Player(JLabel的玩家卡)
{    INT延迟= Q;
    ActionListener的taskPerformer =新的ActionListener(){
       诠释计数= 0;       @覆盖
       公共无效的actionPerformed(ActionEvent的EVT){
           如果(计数== 20){
              ((定时器)evt.getSource())停止()。
           }
           PlayerCard.setLocation(。(PlayerCard.getLocation()X-5),PlayerCard.getLocation()Y + 5);
           算上++;
       }
   };
   新的定时器(延迟,taskPerformer)。开始();
}


解决方案

您可以看看像<一个href=\"http://stackoverflow.com/questions/14540080/animations-when-using-gridbag-layout/14541651#14541651\">this例如其中包装了的GridBagLayout 或像成才的这是基于通用吐温发动机

这是第一个例子,这增加的能力的修改的版本时为特定的布局顺序动画完成通知

 进口java.awt.BorderLayout中;
进口java.awt.Color中;
进口java.awt.Component中;
进口java.awt.Container中;
进口java.awt.Dimension中;
进口java.awt.EventQueue中;
进口java.awt.GridBagConstraints中;
进口java.awt.GridBagLayout中;
进口java.awt.Insets中;
进口java.awt.LayoutManager2;
进口java.awt.Point中;
进口java.awt.Rectangle中;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口的java.util.ArrayList;
进口java.util.EventListener的;
进口java.util.EventObject中;
进口的java.util.HashMap;
进口的java.util.List;
进口的java.util.Map;
进口java.util.WeakHashMap中;
进口javax.swing.JFrame中;
进口javax.swing.JLabel中;
进口javax.swing.JPanel中;
进口javax.swing.Timer中;
进口javax.swing.UIManager中;
进口javax.swing.UnsupportedLookAndFeelException;
进口javax.swing.border.LineBorder中;
进口javax.swing.event.EventListenerList;公共类TestAnimatedLayout {    公共静态无效的主要(字串[] args){
        新TestAnimatedLayout();
    }    公共TestAnimatedLayout(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(ClassNotFoundException的前){
                }赶上(InstantiationException前){
                }赶上(IllegalAccessException前){
                }赶上(UnsupportedLookAndFeelException前){
                }                JFrame的帧=新的JFrame(测试);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(新的BorderLayout());
                frame.add(新TestAnimatedLayoutPane());
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);
            }        });
    }    公共类TestAnimatedLayoutPane继承JPanel {        私人卡卡1,卡2;        公共TestAnimatedLayoutPane(){
            AnimatedLayout animatedLayout =新AnimatedLayout(新的GridBagLayout());
            animatedLayout.addLayoutAnimationListener(新LayoutAnimationListener(){
                @覆盖
                公共无效layoutAnimationStopped(LayoutAnimationEvent EVT){
                    的System.out.println(Stoppped);
                    如果(卡2 == NULL){
                        卡2 =新卡(2);
                        GridBagConstraints的GBC =新的GridBagConstraints();
                        gbc.insets =新插图(4,4,4,4);
                        gbc.gridx = 1;
                        gbc.gridy = 0;
                        加(卡2,GBC);
                        重新验证();
                    }
                }
            });
            setLayout的(animatedLayout);
            GridBagConstraints的GBC =新的GridBagConstraints();
            gbc.insets =新插图(4,4,4,4);
            gbc.gridx = 0;
            gbc.gridy = 0;
            卡1 =新卡(1);
            加(卡1,GBC);
        }        @覆盖
        公共尺寸的get preferredSize(){
            返回新尺寸(200,200);
        }    }    公共类卡扩展JLabel {        市民卡(字符串文本){
            超(文本);
            setHorizo​​ntalAlignment(中心);
            参考setVerticalAlignment(中心);
            setBorder(新LineBorder(Color.BLACK));
            setOpaque(真);
            的setBackground(Color.WHITE);
        }        @覆盖
        公共尺寸的get preferredSize(){
            返回新尺寸(50,100);
        }    }    公共类LayoutAnimationEvent扩展的EventObject {        私营集装箱父母;        公共LayoutAnimationEvent(AnimatedLayout源,集装箱父){
            超(源);
            this.parent =父母;
        }        公共集装箱的getParent(){
            回到父母;
        }        公共AnimatedLayout getAnimationLayout(){
            返回(AnimatedLayout)的getSource();
        }    }    公共接口LayoutAnimationListener扩展的EventListener {        公共无效layoutAnimationStopped(LayoutAnimationEvent EVT);    }    公共类AnimatedLayout实现LayoutManager2中的{        私人EventListenerList对象listenerList =新EventListenerList对象();        私人LayoutManager2中的代理;
        私人地图&lt;成分,矩形&GT; mapStart;
        私人地图&lt;成分,矩形&GT; mapTarget;
        私人地图&LT;集装箱,定时器和GT; mapTrips;
        私人地图&LT;集装箱,动画&GT; mapAnimators;        公共AnimatedLayout(LayoutManager2中的代理){
            this.proxy =代理;
            mapTrips =新的WeakHashMap&所述;&GT;(5);
            mapAnimators =新的WeakHashMap&所述;&GT;(5);
        }        公共无效addLayoutAnimationListener(LayoutAnimationListener监听){
            listenerList.add(LayoutAnimationListener.class,监听器);
        }        公共无效removeLayoutAnimationListener(LayoutAnimationListener监听){
            listenerList.add(LayoutAnimationListener.class,监听器);
        }        保护无效fireAnimationStopped(集装箱父){
            LayoutAnimationListener [] =听众listenerList.getListeners(LayoutAnimationListener.class);
            如果(听众= NULL&放大器;!&安培; listeners.length大于0){
                LayoutAnimationEvent EVT =新LayoutAnimationEvent(这一点,父母);
                对于(LayoutAnimationListener监听器:监听器){
                    listener.layoutAnimationStopped(EVT);
                }
            }
        }        @覆盖
        公共无效addLayoutComponent方法(字符串名称,组件comp){
            proxy.addLayoutComponent(姓名,COMP);
        }        @覆盖
        公共无效中的removeLayoutComponent(组件comp){
            proxy.removeLayoutComponent(化合物);
        }        @覆盖
        公共尺寸preferredLayoutSize(集装箱父){
            返回代理preferredLayoutSize(父)。
        }        @覆盖
        公共尺寸的minimumLayoutSize(集装箱父){
            返回proxy.minimumLayoutSize(父);
        }        @覆盖
        公共无效layoutContainer(集装箱父){
            定时器定时= mapTrips.get(父);
            如果(定时器== NULL){
                的System.out.println(...创造新之旅);
                定时器=新定时器(125,新TripAction(父));
                timer.setRepeats(假);
                timer.setCoalesce(假);
                mapTrips.put(父母,定时器);
            }
            的System.out.println(旅......);
            timer.restart();
        }        保护无效的doLayout(集装箱父){            的System.out.println(...的doLayout);            mapStart =新的HashMap&所述;&GT;(parent.getComponentCount());            为(成分排版:parent.getComponents()){
                mapStart.put(补偿,(矩形)comp.getBounds()的clone());
            }            proxy.layoutContainer(父);            LayoutConstraints约束=新LayoutConstraints();
            为(成分排版:parent.getComponents()){
                矩形范围= comp.getBounds();
                矩形startBounds = mapStart.get(化合物);
                如果(!mapStart.get(COMP).equals(边界)){                    如果(startBounds.x == 0安培;&安培; startBounds.y == 0){                        startBounds.x =(parent.getWidth() - startBounds.width)/ 2;
                        startBounds.y =(parent.getHeight() - startBounds.height)/ 2;                    }                    comp.setBounds(startBounds);
                    constraints.add(补偿,startBounds,边界);
                }
            }            的System.out.println(项目布局+ constraints.size());
            如果(constraints.size()大于0){
                动画动画= mapAnimators.get(父);
                如果(动画== NULL){
                    动画=新的动画(这一点,父母,约束);
                    mapAnimators.put(父母,动画师);
                }其他{
                    animator.setConstraints(约束);
                }
                animator.restart();
            }其他{
                如果(mapAnimators.containsKey(父)){
                    动画动画= mapAnimators.get(父);
                    animator.stop();
                    mapAnimators.remove(父);
                }
            }        }        @覆盖
        公共无效addLayoutComponent方法(组件补偿,对象约束){
            proxy.addLayoutComponent(补偿,约束);
        }        @覆盖
        公共尺寸的maximumLayoutSize(Container target)在{
            返回proxy.maximumLayoutSize(目标);
        }        @覆盖
        公众持股量getLayoutAlignmentX(Container target)在{
            返回proxy.getLayoutAlignmentX(目标);
        }        @覆盖
        公众持股量中的getLayoutAlignmentY(Container target)在{
            返回proxy.getLayoutAlignmentY(目标);
        }        @覆盖
        公共无效的invalidateLayout(Container target)在{
            proxy.invalidateLayout(目标);
        }        保护无效animationDidStop(集装箱父){
            fireAnimationStopped(父);
        }        保护类TripAction实现的ActionListener {            私营集装箱货柜;            公共TripAction(集装箱货柜){
                this.container =容器;
            }            @覆盖
            公共无效的actionPerformed(ActionEvent的五){
                的System.out.println(...之旅);
                mapTrips.remove(容器);
                的doLayout(容器);
            }        }    }    公共类LayoutConstraints {        私人列表&LT; AnimationBounds&GT; animationBounds;        公共LayoutConstraints(){
            animationBounds =新的ArrayList&LT; AnimationBounds&GT;(25);
        }        公共无效添加(组件comp,矩形startBounds,矩形targetBounds){            添加(新AnimationBounds(对比,startBounds,targetBounds));        }        公共无效添加(AnimationBounds边界){            animationBounds.add(边界);        }        公众诠释大小(){
            返回animationBounds.size();
        }        公共AnimationBounds [] getAnimationBounds(){            返回animationBounds.toArray(新AnimationBounds [animationBounds.size()]);        }    }    公共类AnimationBounds {        私人色差分量;
        私人矩形startBounds;
        私人矩形targetBounds;        公共AnimationBounds(色差分量,矩形startBounds,矩形targetBounds){
            this.component =组件;
            this.startBounds = startBounds;
            this.targetBounds = targetBounds;
        }        公共矩形getStartBounds(){
            返回startBounds;
        }        公共矩形getTargetBounds(){
            返回targetBounds;
        }        公共组件getComponent(){
            返回组件;
        }        公共矩形的getBounds(浮动进度){            返回calculateProgress(getStartBounds(),getTargetBounds(),进度);        }    }    公共静态矩形calculateProgress(矩形startBounds,矩形targetBounds,浮动进度){        矩形范围=新的Rectangle();        如果(startBounds = NULL&放大器;!&安培;!targetBounds = NULL){            bounds.setLocation(calculateProgress(startBounds.getLocation(),targetBounds.getLocation(),进度));
            bounds.setSize(calculateProgress(startBounds.getSize(),targetBounds.getSize(),进度));        }        返回界限;    }    公共静态点calculateProgress(点的startPoint,点TARGETPOINT,浮动进度){        逐点=新点();        如果(的startPoint = NULL&放大器;!&安培;!TARGETPOINT = NULL){            point.x = calculateProgress(startPoint.x,targetPoint.x,进度);
            point.y = calculateProgress(startPoint.y,targetPoint.y,进度);        }        返回点;    }    公共静态尺寸calculateProgress(尺寸startSize,外形尺寸的targetSize,浮动进度){        尺寸大小=新的Dimension();        如果(startSize = NULL&放大器;!&安培;!=的targetSize NULL){            size.width = calculateProgress(startSize.width,targetSize.width,进度);
            size.height = calculateProgress(startSize.height,targetSize.height,进度);        }        返回的大小;    }    公共静态INT calculateProgress(INT在startValue,诠释endValue值,浮动分数){        int值= 0;
        INT距离= endValue值 - 在startValue;
        值=(INT)((浮点)距离*分数);
        值+ =在startValue;        返回值;    }    公共类动画实现的ActionListener {        私人定时器定时器;
        私人LayoutConstraints限制;
        私人诠释打勾;
        私营集装箱父母;
        私人AnimatedLayout布局;        公共动画(AnimatedLayout布局,集装箱父母,LayoutConstraints约束){
            setConstraints(约束);
            定时器=新定时器(16本);
            timer.setRepeats(真);
            timer.setCoalesce(真);
            this.parent =父母;
            this.layout =布局;
        }        私人无效setConstraints(LayoutConstraints约束){
            this.constraints =限制;
        }        公共无效启动(){
            勾选= 0;
            timer.restart();
        }        保护无效停止(){
            timer.stop();
            勾选= 0;
        }        @覆盖
        公共无效的actionPerformed(ActionEvent的五){            勾选+ = 16;
            浮动进度=(浮点)打勾/(浮点)1000;
            如果(进度&GT; = 1F){
                进度= 1F;
                timer.stop();
                layout.animationDidStop(父);
            }            为(AnimationBounds AB:constraints.getAnimationBounds()){
                矩形范围= ab.getBounds(进度);
                组件comp = ab.getComponent();
                comp.setBounds(边界);
                comp.invalidate();
                comp.repaint();
            }            parent.repaint();        }    }}

在你告诉我,这太复杂了,单单了解该动画是一个复杂的问题,而是试图动画元件谁应该适当布局管理器的控制下时,它变得更加复杂...

I work on jFrame project:

I have jlabel I want to move it in animation, and then move another jlabel in other words, I want the first jlabel to move and then when it finished,the second jlabel moves.

I've already tried and didn't succeed. I have a function to move one jlabel and ifIi try to use it on both jlabels, both jlabels move at the same time, and I don't want this to happen.

Can you help me do it, thank you so much.

Here is the function that I have :

public void MoveForPlayer(JLabel PlayerCard)
{

    int delay = q; 
    ActionListener taskPerformer = new ActionListener() {
       int count=0;

       @Override
       public void actionPerformed(ActionEvent evt) {
           if(count==20) {
              ((Timer)evt.getSource()).stop();                              
           }
           PlayerCard.setLocation((PlayerCard.getLocation().x-5), PlayerCard.getLocation().y+5);
           count++;
       }
   };
   new Timer(delay, taskPerformer).start();     
}

解决方案

You could take a look at something like this example which wraps animation layer around a GridBagLayout or someting like this which is based on the Universal Tween Engine

This is a modified version of the first example, which adds the ability to be notified when the animation for a particular layout sequence has finished.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.EventObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
import javax.swing.event.EventListenerList;

public class TestAnimatedLayout {

    public static void main(String[] args) {
        new TestAnimatedLayout();
    }

    public TestAnimatedLayout() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestAnimatedLayoutPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestAnimatedLayoutPane extends JPanel {

        private Card card1, card2;

        public TestAnimatedLayoutPane() {
            AnimatedLayout animatedLayout = new AnimatedLayout(new GridBagLayout());
            animatedLayout.addLayoutAnimationListener(new LayoutAnimationListener() {
                @Override
                public void layoutAnimationStopped(LayoutAnimationEvent evt) {
                    System.out.println("Stoppped");
                    if (card2 == null) {
                        card2 = new Card("2");
                        GridBagConstraints gbc = new GridBagConstraints();
                        gbc.insets = new Insets(4, 4, 4, 4);
                        gbc.gridx = 1;
                        gbc.gridy = 0;
                        add(card2, gbc);
                        revalidate();
                    }
                }
            });
            setLayout(animatedLayout);
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(4, 4, 4, 4);
            gbc.gridx = 0;
            gbc.gridy = 0;
            card1 = new Card("1");
            add(card1, gbc);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

    public class Card extends JLabel {

        public Card(String text) {
            super(text);
            setHorizontalAlignment(CENTER);
            setVerticalAlignment(CENTER);
            setBorder(new LineBorder(Color.BLACK));
            setOpaque(true);
            setBackground(Color.WHITE);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(50, 100);
        }

    }

    public class LayoutAnimationEvent extends EventObject {

        private Container parent;

        public LayoutAnimationEvent(AnimatedLayout source, Container parent) {
            super(source);
            this.parent = parent;
        }

        public Container getParent() {
            return parent;
        }

        public AnimatedLayout getAnimationLayout() {
            return (AnimatedLayout) getSource();
        }

    }

    public interface LayoutAnimationListener extends EventListener {

        public void layoutAnimationStopped(LayoutAnimationEvent evt);

    }

    public class AnimatedLayout implements LayoutManager2 {

        private EventListenerList listenerList = new EventListenerList();

        private LayoutManager2 proxy;
        private Map<Component, Rectangle> mapStart;
        private Map<Component, Rectangle> mapTarget;
        private Map<Container, Timer> mapTrips;
        private Map<Container, Animator> mapAnimators;

        public AnimatedLayout(LayoutManager2 proxy) {
            this.proxy = proxy;
            mapTrips = new WeakHashMap<>(5);
            mapAnimators = new WeakHashMap<>(5);
        }

        public void addLayoutAnimationListener(LayoutAnimationListener listener) {
            listenerList.add(LayoutAnimationListener.class, listener);
        }

        public void removeLayoutAnimationListener(LayoutAnimationListener listener) {
            listenerList.add(LayoutAnimationListener.class, listener);
        }

        protected void fireAnimationStopped(Container parent) {
            LayoutAnimationListener[] listeners = listenerList.getListeners(LayoutAnimationListener.class);
            if (listeners != null && listeners.length > 0) {
                LayoutAnimationEvent evt = new LayoutAnimationEvent(this, parent);
                for (LayoutAnimationListener listener : listeners) {
                    listener.layoutAnimationStopped(evt);
                }
            }
        }

        @Override
        public void addLayoutComponent(String name, Component comp) {
            proxy.addLayoutComponent(name, comp);
        }

        @Override
        public void removeLayoutComponent(Component comp) {
            proxy.removeLayoutComponent(comp);
        }

        @Override
        public Dimension preferredLayoutSize(Container parent) {
            return proxy.preferredLayoutSize(parent);
        }

        @Override
        public Dimension minimumLayoutSize(Container parent) {
            return proxy.minimumLayoutSize(parent);
        }

        @Override
        public void layoutContainer(Container parent) {
            Timer timer = mapTrips.get(parent);
            if (timer == null) {
                System.out.println("...create new trip");
                timer = new Timer(125, new TripAction(parent));
                timer.setRepeats(false);
                timer.setCoalesce(false);
                mapTrips.put(parent, timer);
            }
            System.out.println("trip...");
            timer.restart();
        }

        protected void doLayout(Container parent) {

            System.out.println("doLayout...");

            mapStart = new HashMap<>(parent.getComponentCount());

            for (Component comp : parent.getComponents()) {
                mapStart.put(comp, (Rectangle) comp.getBounds().clone());
            }

            proxy.layoutContainer(parent);

            LayoutConstraints constraints = new LayoutConstraints();
            for (Component comp : parent.getComponents()) {
                Rectangle bounds = comp.getBounds();
                Rectangle startBounds = mapStart.get(comp);
                if (!mapStart.get(comp).equals(bounds)) {

                    if (startBounds.x == 0 && startBounds.y == 0) {

                        startBounds.x = (parent.getWidth() - startBounds.width) / 2;
                        startBounds.y = (parent.getHeight() - startBounds.height) / 2;

                    }

                    comp.setBounds(startBounds);
                    constraints.add(comp, startBounds, bounds);
                }
            }

            System.out.println("Items to layout " + constraints.size());
            if (constraints.size() > 0) {
                Animator animator = mapAnimators.get(parent);
                if (animator == null) {
                    animator = new Animator(this, parent, constraints);
                    mapAnimators.put(parent, animator);
                } else {
                    animator.setConstraints(constraints);
                }
                animator.restart();
            } else {
                if (mapAnimators.containsKey(parent)) {
                    Animator animator = mapAnimators.get(parent);
                    animator.stop();
                    mapAnimators.remove(parent);
                }
            }

        }

        @Override
        public void addLayoutComponent(Component comp, Object constraints) {
            proxy.addLayoutComponent(comp, constraints);
        }

        @Override
        public Dimension maximumLayoutSize(Container target) {
            return proxy.maximumLayoutSize(target);
        }

        @Override
        public float getLayoutAlignmentX(Container target) {
            return proxy.getLayoutAlignmentX(target);
        }

        @Override
        public float getLayoutAlignmentY(Container target) {
            return proxy.getLayoutAlignmentY(target);
        }

        @Override
        public void invalidateLayout(Container target) {
            proxy.invalidateLayout(target);
        }

        protected void animationDidStop(Container parent) {
            fireAnimationStopped(parent);
        }

        protected class TripAction implements ActionListener {

            private Container container;

            public TripAction(Container container) {
                this.container = container;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("...trip");
                mapTrips.remove(container);
                doLayout(container);
            }

        }

    }

    public class LayoutConstraints {

        private List<AnimationBounds> animationBounds;

        public LayoutConstraints() {
            animationBounds = new ArrayList<AnimationBounds>(25);
        }

        public void add(Component comp, Rectangle startBounds, Rectangle targetBounds) {

            add(new AnimationBounds(comp, startBounds, targetBounds));

        }

        public void add(AnimationBounds bounds) {

            animationBounds.add(bounds);

        }

        public int size() {
            return animationBounds.size();
        }

        public AnimationBounds[] getAnimationBounds() {

            return animationBounds.toArray(new AnimationBounds[animationBounds.size()]);

        }

    }

    public class AnimationBounds {

        private Component component;
        private Rectangle startBounds;
        private Rectangle targetBounds;

        public AnimationBounds(Component component, Rectangle startBounds, Rectangle targetBounds) {
            this.component = component;
            this.startBounds = startBounds;
            this.targetBounds = targetBounds;
        }

        public Rectangle getStartBounds() {
            return startBounds;
        }

        public Rectangle getTargetBounds() {
            return targetBounds;
        }

        public Component getComponent() {
            return component;
        }

        public Rectangle getBounds(float progress) {

            return calculateProgress(getStartBounds(), getTargetBounds(), progress);

        }

    }

    public static Rectangle calculateProgress(Rectangle startBounds, Rectangle targetBounds, float progress) {

        Rectangle bounds = new Rectangle();

        if (startBounds != null && targetBounds != null) {

            bounds.setLocation(calculateProgress(startBounds.getLocation(), targetBounds.getLocation(), progress));
            bounds.setSize(calculateProgress(startBounds.getSize(), targetBounds.getSize(), progress));

        }

        return bounds;

    }

    public static Point calculateProgress(Point startPoint, Point targetPoint, float progress) {

        Point point = new Point();

        if (startPoint != null && targetPoint != null) {

            point.x = calculateProgress(startPoint.x, targetPoint.x, progress);
            point.y = calculateProgress(startPoint.y, targetPoint.y, progress);

        }

        return point;

    }

    public static Dimension calculateProgress(Dimension startSize, Dimension targetSize, float progress) {

        Dimension size = new Dimension();

        if (startSize != null && targetSize != null) {

            size.width = calculateProgress(startSize.width, targetSize.width, progress);
            size.height = calculateProgress(startSize.height, targetSize.height, progress);

        }

        return size;

    }

    public static int calculateProgress(int startValue, int endValue, float fraction) {

        int value = 0;
        int distance = endValue - startValue;
        value = (int) ((float) distance * fraction);
        value += startValue;

        return value;

    }

    public class Animator implements ActionListener {

        private Timer timer;
        private LayoutConstraints constraints;
        private int tick;
        private Container parent;
        private AnimatedLayout layout;

        public Animator(AnimatedLayout layout, Container parent, LayoutConstraints constraints) {
            setConstraints(constraints);
            timer = new Timer(16, this);
            timer.setRepeats(true);
            timer.setCoalesce(true);
            this.parent = parent;
            this.layout = layout;
        }

        private void setConstraints(LayoutConstraints constraints) {
            this.constraints = constraints;
        }

        public void restart() {
            tick = 0;
            timer.restart();
        }

        protected void stop() {
            timer.stop();
            tick = 0;
        }

        @Override
        public void actionPerformed(ActionEvent e) {

            tick += 16;
            float progress = (float) tick / (float) 1000;
            if (progress >= 1f) {
                progress = 1f;
                timer.stop();
                layout.animationDidStop(parent);
            }

            for (AnimationBounds ab : constraints.getAnimationBounds()) {
                Rectangle bounds = ab.getBounds(progress);
                Component comp = ab.getComponent();
                comp.setBounds(bounds);
                comp.invalidate();
                comp.repaint();
            }

            parent.repaint();

        }

    }

}

Before you tell me "it's too complicated", understand that animation alone is a complex subject, but when trying to animated components who should be under the control of appropriate layout managers, it becomes even more complicated...

这篇关于Java的:移动的JLabel两次使用定时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆