Perhaps I'm doing something wrong, but if so, I can't track it down. My plugin has an internal mixer with mute buttons that have Drawable image states for "muted" and "unmuted", so here's an example of the mute button for channel 1:
PluginEditor.h:
DrawableButton* C1Mute;
PluginEditor.cpp:
// Channel 1 Mute
C1Mute = new DrawableButton ("C1Mute", DrawableButton::ImageRaw);
C1Mute->setImages (cachedImage_mute_button_png,
cachedImage_mute_button_png,
cachedImage_mute_button_png,
cachedImage_mute_button_png,
cachedImage_mute_button_active_png,
cachedImage_mute_button_active_png,
cachedImage_mute_button_active_png,
cachedImage_mute_button_active_png);
C1Mute->setClickingTogglesState (true);
C1Mute->setButtonText (("Mute"));
C1Mute->setTooltip (("Channel 1 Mute"));
C1Mute->setRepaintsOnMouseActivity(true);
C1Mute->addListener (this);
addAndMakeVisible (C1Mute);
I've been using this same code with previous Juce versions with no issues, but lately the changes to the Button classes have broken this so that I have to manually refresh the button's state separately from the button's toggle state.
Without that workaround in place, setRepaintsOnMouseActivity(true) is the only way to get this button to refresh its state - you can explicitly call repaint() to its component (and even recursively iterate through all child components issuing repaint() in a for loop!) without refreshing it - but for some reason a mouse hover will "wake" the button to its proper state, as will explicitly issuing a state refresh as shown in my previous post.
Come to think of it, I did just notice that I'm needlessly setting ButtonText for a purely Drawable raw image-based button with no visible text caption, so perhaps that's creating an unintended edge case. I don't even know why that's in there, this code has been essentially the same for a few years and that may be a scrap left over from prototyping... perhaps more tinkering is in order, but I'd be pretty surprised if that's the culprit - it would be odd in any case.