简体   繁体   English

如何在不阻塞Timer(Java Swing)的情况下暂停程序执行?

[英]How to pause program execution without blocking a Timer (Java Swing)?

I have a Timer that shows an animation on the screen when a game event takes place. 我有一个计时器,当游戏事件发生时,它会在屏幕上显示动画。 What I want to do is have the main execution pause until this animation finishes, but everything I try seems to block the Timer from running. 我想要做的是让主动执行暂停,直到这个动画结束,但我尝试的一切似乎阻止了Timer的运行。 I've tried using Thread.sleep() and calling wait() and notify() on a lock object, but with the same result. 我已经尝试使用Thread.sleep()并在锁定对象上调用wait()和notify(),但结果相同。 The Timer listener's actionPerformed() is never called. 永远不会调用Timer侦听器的actionPerformed()。

This code sets up the timer: 此代码设置计时器:

protected void showMovingEffect(int steps, Direction dir, AnimatedImageSet imgs) {
    effectsPane.runAnimation(imgs, dir, steps);
    waiting = true;
    while (waiting) {
        synchronized(animationWaitLock) {
            try {
                animationWaitLock.wait();
            } catch (InterruptedException e) {}
        }
    }
}

And the Timer and listener inside the EffectsPane object: 而EffectsPane对象中的Timer和侦听器:

private void runAnimation(AnimatedImageSet ais, Direction dir, int iters) {
        System.out.println("run");
        imgs = ais;
        top = 0;
        left = 0;
        topStep = dir.getRowIncrement() * 10;
        leftStep = dir.getColIncrement() * 10;
        iterations = iters;
        index = 0;
        active = true;
        timer.start();
    }

public void actionPerformed(ActionEvent e) {
        System.out.println(index);
        top += topStep;
        left += leftStep;
        index++;
        currentImage = imgs.getImage(index);
        repaint();
        if (index == iterations) { 
            active = false;
            timer.stop();
            synchronized(animationWaitLock) {
                animationWaitLock.notify();
            }
            waiting = false;
        }
    }

The System.out.println call at the start of the actionPerformed() is never called, so either the wait() call is also pausing the Timer, or something is blocking it. 从不调用actionPerformed()开头的System.out.println调用,因此wait()调用也会暂停Timer,或者某些东西阻塞它。 If I comment out the sleep/wait lines in showMovingEffect(), the animation runs, but the program does not pause. 如果我在showMovingEffect()中注释掉睡眠/等待行,则动画会运行,但程序不会暂停。

One approach would be to display a modal dialog while the animation proceeds. 一种方法是在动画进行时显示模态对话框 As discussed here , user interaction will be foreclosed, but background GUI updates in response to the javax.swing.Timer will continue. 作为讨论在这里 ,用户交互将被取消赎回权,但在应对背景GUI更新javax.swing.Timer仍将继续。 You can allow the user to dismiss the dialog at any time, as shown here , but you may want to abandon the animation at that point. 您可以让用户随时关闭该对话框,如图所示这里 ,但你可能要放弃在该点的动画。

no input from the user is needed. 不需要用户输入。

You can block user interaction without displaying a dialog by entering a SecondaryLoop after the animation starts. 您可以通过在动画开始后输入SecondaryLoop来阻止用户交互而不显示对话框。

SecondaryLoop loop = Toolkit.getDefaultToolkit()
    .getSystemEventQueue().createSecondaryLoop();
timer.start();
loop.enter();

When the animation concludes, exit() the SecondaryLoop : 动画结束时, exit() SecondaryLoop

public void actionPerformed(ActionEvent e) {
    …
    if (index == iterations) {
        timer.stop();
        loop.exit ();
        …
    }
}

You can try this: 你可以试试这个:

timer.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        // your code
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM