简体   繁体   English

等待计时器/进程完成,然后再继续

[英]Wait for Timer/Process to finish before continuing

I have a function that flashes the border of a JButton which gets called multiple times in a row. 我有一个函数,它会闪烁JButton的边框,该边框连续被调用多次。 I want the processes to continue only after the entirety of the function completes. 我希望过程仅在整个功能完成后才能继续。 Right now, the flashing starts for one button, then it will start for another before the flashing stopped for the first button. 现在,从一个按钮开始闪烁,然后在另一个按钮停止闪烁之前开始另一个闪烁。 The function looks like the following which is in a class that extends JButton: 该函数类似于扩展JButton的类中的以下代码:

    public void flash() {
    final Timer timer = new Timer(7, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            alpha += increment;
            if (alpha >= 255) {
                alpha = 255;
                increment = -increment;
            }
            if (alpha <= 0) {
                alpha = 0;
                increment = -increment;
            }
            setBorder(BorderFactory.createLineBorder(new Color(81, 171, 112, alpha), 4));
        }
    });

    timer.start();

    final Timer delay = new Timer(
            2000,
            new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0, 0), 0));
            timer.stop();
        }
    });
    delay.setRepeats(false);
    delay.setCoalesce(true);
    delay.start();
}

A fundamental problem you have here is that there are multiple button objects. 这里的一个基本问题是有多个按钮对象。 That means each flash() lives in an independent object (since it isn't static). 这意味着每个flash()生活在一个独立的对象中(因为它不是静态的)。 That means each button has no idea if the others are flashing or not. 这意味着每个按钮都不知道其他按钮是否闪烁。

What you need is one place that does the flashing. 您需要的是一个闪烁的地方。 A place where whatever needs the flashing to happen can dump the work. 任何需要闪烁的地方都会丢掉工作。 A place that knows about the buttons so it can manipulate their borders. 知道按钮的地方,以便可以操纵按钮的边界。 Lets call it the flasherQueue . 让我们称之为flasherQueue

A static member could be used for this but a more flexible design would inject the single flasherQueue object into each of your button objects as they are constructed. 可以使用静态成员,但是更灵活的设计是在构造按钮对象时将单个flasherQueue对象注入到每个按钮对象中。 Each button knowing about flasherQueue is only required if it's the buttons that decide when to flash. 仅当由按钮决定何时闪烁时,才需要知道flasherQueue的每个按钮。

At this point you are free to make your buttons flash() method into a blocking call. 此时,您可以随意将按钮的flash()方法变为阻塞调用。 Whatever you have decide to flash a button simply passes a reference to the button to the flasherQueue . 无论您决定要闪烁flasherQueue按钮,只需将对该按钮的引用传递给flasherQueue The flasherQueue , looping in it's own thread, grinds through any buttons it's been given in order, waiting for each to finish flashing. 在自己的线程中循环的flasherQueue遍历按顺序给出的所有按钮,等待每个按钮完成闪烁。

Done this way you should only ever have at most one flashing button at a time and should be free to process other events so your GUI should repaint. 这样,您一次最多只能有一个闪烁的按钮,并且应该可以自由处理其他事件,因此您的GUI应该重新绘制。

This is really a degenerative form of producer / consumer . 这确实是生产者/消费者的退化形式。 As long as you have only one consumer calling a buttons flash() only one button will flash at a time. 只要您只有一个使用者调用按钮flash()一次就只会闪烁一个按钮。 You'll probably be able to make use of java's BlockingQueue for your data structure behind flasherQueue . 您可能可以在flasherQueue之后的数据结构中使用Java的BlockingQueue

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

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