重写的mouseClicked(MouseEvent e)不会更改JFrame的组件JLable



我实现了一个包含一些JLableJFrame。我想在点击后更改它们的外观。附加的代码应该这样做。事实上:它做而不是。获取相同的代码并将其放入内部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重新绘制自己。

您可以:

  1. 使用SwingWorker启动线程,然后休眠一段时间。然后当工人完成后,你可以恢复标签的颜色。有关更多信息和示例,请参阅并发
  2. 使用Swing Timer来安排更改。有关更多信息,请参阅如何使用摆动计时器

最新更新