我有一个函数,它闪烁一个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();
}
最佳答案
这里的一个基本问题是有多个按钮对象。这意味着每个flash()
都生活在一个独立的对象中(因为它不是静态的)。这意味着每个按钮都不知道其他按钮是否闪烁。
您需要的是一个闪烁的地方。任何需要闪烁的地方都可能导致工作中断。知道按钮的地方,以便可以操纵按钮的边界。让我们称之为flasherQueue
。
可以使用静态成员,但是更灵活的设计是在构造每个按钮对象时将单个flasherQueue
对象注入到每个按钮对象中。仅当由按钮决定何时刷新时,才需要知道flasherQueue的每个按钮。
此时,您可以随意将按钮flash()
方法变为阻塞调用。无论您决定要闪烁哪个按钮,只需将对该按钮的引用传递给flasherQueue
。 flasherQueue
在其自己的线程中循环,遍历按顺序给出的所有按钮,等待每个按钮完成闪烁。
这样,一次最多只能有一个闪烁的按钮,并且可以自由处理其他事件,因此您的GUI应该重新绘制。
这实际上是producer / consumer的退化形式。只要您只有一个消费者调用按钮flash()
,一次只会闪烁一个按钮。您可能可以将Java的BlockingQueue用于flasherQueue
之后的数据结构。