【问题标题】:Sequential Swing timer execution顺序摆动定时器执行
【发布时间】:2014-01-23 02:09:20
【问题描述】:

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

有没有办法让 Swing 计时器按顺序执行 - 一个接一个,而不是一次全部执行?或者是否有替代 Swing 计时器的机制可能更符合我的用例?

编辑: 恐怕我有点过于简化了我的用例。 @peeskillet 的建议如果我知道在每个“场景转换”中需要执行哪些动画,或者每次都发生相同的动画序列,那么我的建议将非常有效。不幸的是,情况并非如此——每个过渡都需要一组不同的动画,不同的组件集在面板上移动、离开和移动。

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

的基本策略了

这就是说——这一切对我来说只是直观的、启发式的——我还没有弄清楚如何在实践中实现它。这些“队列”实际上是什么,什么类将持有并稍后执行它们?大概是一个实现 Runnable 的线程,它创建了第二个线程,可以通过更严格地控​​制动画的执行方式来执行动画?或者如果我完全掌握了如何使用它,事件调度线程是否给了我足够的控制权?在这种情况下 - 请帮我这样做。

(PS 我意识到我在这里已经对问题进行了重大更改,基本上将其变成了一个新问题,并且@peetskillet 回答它之前的措辞非常好,所以我接受了这个答案并发布了一个新问题here.

【问题讨论】:

  • 您只需完成一个计时器即可开始下一个计时器。没有内置机制。
  • @Gene- 如果计时器是动态的并且无法手动检查,该怎么办。

标签: java swing timer multiple-instances


【解决方案1】:

“有没有办法让 Swing 计时器按顺序执行——一个接一个,而不是一次全部执行?”

只需使用某种`布尔值,告诉第一个计时器何时应该停止以及第二个计时器应该何时开始。类似的东西

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();
        }
    });
}

这是一个简单的例子

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);
            }
        });
    }
}

【讨论】:

  • 为什么有两个或多个计时器,也许没有理由,把every Objects in one Array, then just loop inside...
  • @mKorbel 我不知道,我只是在回答 OP 的具体问题。我会使用数据结构。 :)
  • @peeskillet 谢谢,请在我的帖子更新中查看我的回复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-05
  • 1970-01-01
  • 2017-08-16
  • 2020-11-12
  • 1970-01-01
相关资源
最近更新 更多