我实现了包含某些JFrameJLable。单击后,我想更改其外观。附加的代码应该这样做。实际上:事实并非如此。采取相同的代码并将其放入内部Thread-class的运行即可完成此工作。内部线程实例将单击的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启动线程,然后休眠一段时间。然后,当工作人员完成时,您可以恢复标签的颜色。有关更多信息和示例,请参见Concurrency
使用Swing计时器来计划更改。有关更多信息,请参见How to Use Swing Timers

关于java - 重写的mouseClicked(MouseEvent e)不会更改JFrame的组件JLable吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26326806/

10-09 09:57