依序执行Swing计时器 [英] Sequential Swing timer execution

查看:109
本文介绍了依序执行Swing计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Swing计时器在程序中执行动画.在许多情况下,一次对animate()方法进行了多次不同的调用,并为每个调用创建了单独的Timer.我知道,由于Swing计时器的设计方式,它们全部一起执行-我的所有动画都同时发生.但是,在某些情况下,我需要等待一个动画完成才能执行另一个动画.

I'm using a Swing Timer to execute animations in my program. In many instances, there are several different calls made to the animate() method at once, with a separate Timer created for each. I know that, because of the way Swing timers are designed, these all get executed together - all my animations occur at the same time. However, there are some instances where I need to wait for one animation to complete to execute another.

是否有一种方法可以使Swing计时器按顺序执行-一个接一个地执行,而不是一次执行?还是Swing计时器有替代的机制,可以更好地匹配我的用例?

Is there a way to make Swing timers execute sequentially - one after the other, rather than all at once? Or is there an alternative mechanism to the Swing timer that might better match my use case?

编辑:恐怕我将用例简化了一点.如果我在每个场景过渡"都知道需要执行哪些动画,或者每次都出现相同的动画序列,则@peeskillet的建议将非常有效.不幸的是,情况并非如此-每个过渡都需要一组不同的动画,并且不同组的组件会在面板上移动,移动或移动.

I'm afraid I oversimplified my use case a bit. @peeskillet's suggestion would work perfectly if I knew at each "scene transition" what animations would need to be executed, or if the same sequence of animations occurred each time. Unfortunately that's not the case -- each transition requires a different set of animations, with different sets of components moving onto, off of and around on the panel.

我想要的是首先在屏幕外执行项目的动画,然后(在完成之后)对屏幕上的组件进行动画处理.在运行时区分这些动画的类型"不是问题-它们是从不同的方法启动的,因此很容易想象将它们添加到两个不同的队列"中-传出项目队列和传入项目队列.这样做之后,我便可以实施调用

What I want is to execute the animations of items off the screen first, and then (after that completes) animate the components on the screen. It's not a problem to distinguish between these "types" of animations at runtime - they're initiated from different methods, and thus its easy to imagine adding them to two different "queues" - a queue of outgoing items and a queue of incoming items. Having done so, I could then implement the basic strategy of calling a

也就是说,这一切对我来说都是直觉,启发式的,对我来说还没有弄清楚如何在实践中实现它.这些队列"实际上是什么,将容纳什么类并在以后执行它们?大概是一个实现了Runnable的线程,它创建了第二个线程来执行动画,并且可以更严格地控​​制动画的进行方式?还是仅在我完全掌握了如何使用它的情况下,事件调度线程才能在这里给我足够的控制权?在这种情况下-请帮助我.

That said - that all only makes sense to me intuitively, heuristically - I haven't figured out how to implement it in practice. What would those "queues" actually be, and what class would hold and later execute them?? Presumably one that implements Runnable, creating a second thread that can execute the animations with tighter control on how they proceed? Or does the event-dispatch thread give me the ample control here, if only I fully grasped how to use it? In which case - please help me do that.

(PS,我意识到我已经在这里大大改变了这个问题,从本质上把它变成了一个新问题,并且@peetskillet回答得非常好,以前的措词很好,所以我接受了这个答案并发布了一个新问题="https://stackoverflow.com/questions/21344261/grouping-animations-for-sequential-execution">此处.

(PS I realize that I've changed the question significantly here, essentially turning it into a new question, and that @peetskillet answered it as previously worded perfectly well, so I accepted that answer and posted a new question here.

推荐答案

有没有一种方法可以使Swing定时器依次执行-一个接一个地执行,而不是一次执行?"

"Is there a way to make Swing timers execute sequentially - one after the other, rather than all at once? "

只需使用某种布尔值即可,告诉第一个计时器什么时候应该停止,第二个计时器什么时候应该开始.像

Just use a `boolean of some sort, telling when the first timer when it should stop and when the second timer should start. Something like

Timer timer1 = new Timer(delay, null);       <---- initialize
Timer timer2 = new Timer(delay, null);
boolean something = false;

public Constructor() {
    timer1 = new Timer(delay, new Action Listener(){
        public void actionPerformed(ActionEvent e) {
            if (something) {               ------
                timer2.start();                 |
                timer1.stop();                  |---- some code should lead to
            } esle {                            |     `something` being true. Maybe
                animateFirstSomething();        |     another if statement inside the 
            }                                   |     else. Like if x equals y
        }                                  ------     something = true, else,
    });                                               animateFirstSomething()
    timer1.start();

    timer2 = new Timer(delay, new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            animationSecondSomething();
        }
    });
}


这是一个简单的例子


Here's simple example

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class TestTwoTimers extends JPanel {

    int rectOneX = 0;
    int rectTwoX = 0;

    Timer timer1 = new Timer(100, null);
    Timer timer2 = new Timer(100, null);
    boolean rectOneGo = true;



    public TestTwoTimers() {
        timer1 = new Timer(100, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (rectOneGo) {
                    if (rectOneX >= 225) {
                        timer2.start();
                        timer1.stop();
                    } else {
                        rectOneX += 10;
                        repaint();
                    }
                }
            }
        });
        timer2 = new Timer(100, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (rectTwoX < 225) {
                    rectTwoX += 10;
                    repaint();
                } else {
                    timer2.stop();
                }
            }
        });

        final JButton button = new JButton("Start First Timer");
        button.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                timer1.start();
            }
        });

        setLayout(new BorderLayout());
        add(button, BorderLayout.PAGE_END);
    }

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

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setColor(Color.red);
        g.fillRect(rectOneX, 50, 75, 75);

        g.setColor(Color.BLUE);
        g.fillRect(rectTwoX, 150, 75, 75);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                JFrame frame = new JFrame("Double Timers");
                frame.add(new TestTwoTimers());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

这篇关于依序执行Swing计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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