我必须维护一个非常古老且写得不好的Java软件。我在更新后遇到了一个问题: 有一些按钮可以更改卡布局中显示的面板。已经注册了处理程序,该部分似乎正常工作。现在,这些按钮的第二部分正在更改背景颜色。但是,此更改不是由点击触发的。至少不是直接。单击该按钮会触发到某台计算机的消息,然后该计算机以状态响应,然后该状态导致该按钮的颜色改变。
此颜色更改开始在上次更新后生效。所以基本上有两个问题:
我有一个模糊的想法,即缺少颜色更改与“不要在事件分配线程之外更新GUI元素”有关。这是问题根源的可能性有多大?有一个观察结果可以得出这样的假设:一段时间后,鼠标左右移动会触发颜色变化。
如果可以,最简单的应对方法是什么?在这些按钮上实现PropertyChangeListener?还是其他(更好的)方式?
因为这里的好人坚持要看一些代码:
Color[] backgroundColors = {
ColorExt.btnCol, // 0 0 not prepare mode, not selected
ColorExt.darkGreen, // 0 1 not prepare mode, selected
ColorExt.YELLOW, // 1 0 prepare mode, not selected
ColorExt.dimOrange, // 1 1 prepare mode, selected
};
JButton[] btn = { mainframe.jBtnLoader1, mainframe.jBtnLoader2, mainframe.jBtnLoader3 };
for (int ldr=0; ldr<3; ldr++) {
int colorIdx = 0;
if ((inCellViewFromLoader[ldr][124] & 16) != 0)
colorIdx = 2; // bLoaderError = true => prepare
if (mainframe.currentSelectedLoader == ldr) {
colorIdx += 1; // selected
}
btn[ldr].setBackground(backgroundColors[colorIdx]);
}
虽然没有什么特别的。这段代码本身不是问题。我的假设是,由于此代码是在某个网络线程中执行的,而不是在事件分发线程中执行的,因此那是问题的根源。
答案 0 :(得分:0)
因此,根据MadProgrammers的建议,我做了一个小的实用程序类:
/**
* Class to be instantiated in a call to EventQueue.invokeLater(), so the
* background color of the given component is updated in the Event
* Dispatch Thread.
*
*
*/
public class ColorChanger implements java.lang.Runnable {
private Color color = Color.WHITE;
private JComponent component = null;
public ColorChanger(JComponent component, Color color) {
super();
this.component = component;
this.color = color;
}
@Override
public void run() {
if (component != null) {
component.setBackground(color);
}
}
}
然后更改行 btn [ldr] .setBackground(backgroundColors [colorIdx]); 至: EventQueue.invokeLater(new ColorChanger(btn [ldr],backgroundColors [colorIdx]));
至少看起来合理。不过,要等到我可以在客户现场进行测试之前,还需要一些时间。