我实现了一个包含一些JLable
的JFrame
。我想在点击后更改它们的外观。附加的代码应该这样做。事实上:它做而不是。获取相同的代码并将其放入内部Thread类的运行中即可完成任务。内部线程实例反转单击的JLable
两次。
有人能告诉我为什么mouseClicked
-方法似乎不能影响点击的JLable
的外观吗?
@Override
public void mouseClicked(MouseEvent e) {
if (clickable) {
for (Position p : positions.keySet()) {
JLabel lable = positions.get(p);
if (lable == e.getComponent()) {
pickedPosition = p;
LOGGER.info(pickedPosition + " pressed");
synchronized (lable) {
// store old colors
Color obg = lable.getBackground();
Color ofg = lable.getForeground();
// invert them
Color nbg = new Color(255 - obg.getRed(), 255 - obg.getGreen(), 255 - obg.getBlue());
Color nfg = new Color(255 - ofg.getRed(), 255 - ofg.getGreen(), 255 - ofg.getBlue());
// set them
lable.setOpaque(true);
lable.setForeground(nfg);
lable.setBackground(nbg);
// wait a while
try {
lable.wait(WAIT_WHILE_INVERTING_MS);
}
catch (InterruptedException i) {
LOGGER.warn(i.getMessage());
}
// switch back to initial
lable.setBackground(obg);
lable.setForeground(ofg);
}
e.consume();
}
}
}
}
不需要synchronized
代码块。从事件代码执行的所有代码都将在事件调度线程(EDT)上执行。由于您应该始终更新EDT上组件的属性,因此无需担心其他线程会更新组件。
看起来您想要临时更改标签的"颜色"。问题是wait()方法会阻塞EDT并阻止GUI重新绘制自己。
您可以:
- 使用SwingWorker启动线程,然后休眠一段时间。然后当工人完成后,你可以恢复标签的颜色。有关更多信息和示例,请参阅并发
- 使用Swing Timer来安排更改。有关更多信息,请参阅如何使用摆动计时器