简体   繁体   English

更新 JButton 背景颜色的问题

[英]Problem with updating background color of a JButton

I have to maintain a very old and badly written Java software.我必须维护一个非常陈旧且写得很糟糕的 Java 软件。 And i ran into a problem after an update: There are some buttons that change the shown panel in a card layout.更新后我遇到了一个问题:有一些按钮可以更改卡片布局中显示的面板。 There are handlers registered, and that part seems to work.有处理程序注册,这部分似乎工作。 Now the second part of these buttons is changing the background color.现在这些按钮的第二部分是改变背景颜色。 But this change is not triggered by the click.但是这种变化不是由点击触发的。 At least not directly.至少不是直接的。 Clicking the button triggers a message to some machine, that machine then responds with a status, and that status then leads to a color change of that button.单击按钮会向某台机器触发一条消息,然后该机器以状态响应,然后该状态会导致该按钮的颜色发生变化。

This color change ceised to work after the last update.此颜色更改在上次更新后生效。 So basically there are 2 questions:所以基本上有2个问题:

  1. I have the vague idea that this lack of color changing is related to "do not update GUI elements outside the event dispatch thread".我有一个模糊的想法,这种颜色变化的缺乏与“不要在事件调度线程之外更新 GUI 元素”有关。 How probable is it that this is the root of the problem?这是问题根源的可能性有多大? There is an observation which lead to that assumption: Moving around the mouse triggers the color change after some time.有一个观察结果导致了这个假设:在鼠标周围移动会在一段时间后触发颜色变化。

  2. If yes, what would be the easiest way to cope with that?如果是,那么最简单的方法是什么? Implement a PropertyChangeListener on these buttons?在这些按钮上实现 PropertyChangeListener? Or any other (better) way?或任何其他(更好)的方式?

Since the nice people here insist on seeing some code:由于这里的好人坚持要查看一些代码:

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]);
}

There is nothing special about it though.不过没有什么特别之处。 This code itself is not the problem.这段代码本身不是问题。 My assumption is, since this code is executed in some network thread, not in the event dispatch thread, that is the root of the problem.我的假设是,由于此代码是在某个网络线程中执行的,而不是在事件调度线程中执行,就是问题的根源。

So, according to MadProgrammers suggestion, i made a small utility class:所以,根据 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);
    }
}

} }

And then changed the line btn[ldr].setBackground(backgroundColors[colorIdx]);然后更改了行 btn[ldr].setBackground(backgroundColors[colorIdx]); to: EventQueue.invokeLater(new ColorChanger(btn[ldr], backgroundColors[colorIdx])); to: EventQueue.invokeLater(new ColorChanger(btn[ldr], backgroundColors[colorIdx]));

At least that looks reasonable.至少这看起来很合理。 It will take some time though until i can test this at the customers site.不过,我需要一些时间才能在客户网站上对此进行测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM