Paint is not redrawing. What am I doing wrong?

I’ve spent hours trying to figure out what I’m doing wrong, and have looked at the demos but I just can’t figure it out. Most of what I’ve done was created by the GUI editor too, so it just confuses me further. I have created several image buttons, and when they are clicked, the background image should change. Strangely, those parts of the background image that can be seen through the transparent portions of the buttons are actually being redrawn (perhaps because the button is forced to redraw when the mouse hovers) but nothing else is.
I don’t know if it is relevant but I’m using Visual Studio 2015 on Windows 10.

void SynthAudioProcessorEditor::paint (Graphics& g)
{
//[UserPrePaint] Add your own custom painting code here…
//[/UserPrePaint]

g.fillAll (Colours::white);

//[UserPaint] Add your own custom painting code here..
g.setColour(Colours::black);

switch (currentTab) {
case Overview:
    g.drawImage(cachedImage_greyBarA_png_1, 5, 5, 790, 74, 0, 0, cachedImage_greyBarA_png_1.getWidth(), cachedImage_greyBarA_png_1.getHeight());
    break;
case Tone:
    g.drawImage(cachedImage_greyBarB_png_1, 5, 5, 790, 74, 0, 0, cachedImage_greyBarB_png_1.getWidth(), cachedImage_greyBarB_png_1.getHeight());
    break;
case Modulation:
    g.drawImage(cachedImage_greyBarC_png_1, 5, 5, 790, 74, 0, 0, cachedImage_greyBarC_png_1.getWidth(), cachedImage_greyBarC_png_1.getHeight());
    break;
case Options:
    g.drawImage(cachedImage_greyBarD_png_1, 5, 5, 790, 74, 0, 0, cachedImage_greyBarD_png_1.getWidth(), cachedImage_greyBarD_png_1.getHeight());
    break;
}


//[/UserPaint]

}

In these cases I find most times, that I didn’t set the bounds correctly. Maybe check the size of SynthAudioProcessorEditor or maybe you did not call addAndMakeVisible.

The bounds for each button have been set automatically by the GUI editor. The SynthAudioProcessorEditor has a size of 800 x 600. The buttons all have calls to addAndMakeVisible but not the editor, because it is not a child component.

ok, but the editor needs a size too… Do you call setSize (800, 600); in the constructor or how do you know it has this size?

I’ve just discovered and tried using the repaint() function, and that seems to have fixed the problem completely. Though I do hope that there are no side-effects to doing it this way. Like I wish I knew what the problem was, so I could be sure that I am not just adding wasteful overhead to my plugin.

Hmm, where did you call repaint()? good that it is painting now, but you shouldn’t need to call it as long as nothing changed, like from a timer or so…

I call it after a button is clicked:

void SynthAudioProcessorEditor::buttonClicked (Button* buttonThatWasClicked)
{
//[UserbuttonClicked_Pre]
//[/UserbuttonClicked_Pre]

if (buttonThatWasClicked == logo)
{
    //[UserButtonCode_logo] -- add your button handler code here..
    //[/UserButtonCode_logo]
}
else if (buttonThatWasClicked == overview)
{
    //[UserButtonCode_overview] -- add your button handler code here..
    currentTab = Overview;
    repaint();
    //[/UserButtonCode_overview]
}
else if (buttonThatWasClicked == tone)
{
    //[UserButtonCode_tone] -- add your button handler code here..
    currentTab = Tone;
    repaint();
    //[/UserButtonCode_tone]
}
else if (buttonThatWasClicked == modulation)
{
    //[UserButtonCode_modulation] -- add your button handler code here..
    currentTab = Modulation;
    repaint();
    //[/UserButtonCode_modulation]
}
else if (buttonThatWasClicked == options)
{
    //[UserButtonCode_options] -- add your button handler code here..
    currentTab = Options;
    repaint();
    //[/UserButtonCode_options]
}

//[UserbuttonClicked_Post]
//[/UserbuttonClicked_Post]

}

Ok, that’s actually correct, because the system cannot know, that a change of currentTab means a repaint is necessary.

OK thanks. I’ll keep that in mind

If you need continuous repainting, do:

class MyComponent  : public Component, private Timer
{
public:
    MyComponent() {
        setSize (800, 600);
        startTimerHz(60);
    }
        
    void timerCallback() final {
        repaint();
    }
    
    void paint (Graphics& g) final {...}
1 Like

Thanks! This is great!

…but don’t use the above suggestion as a magic replacement for understanding how to repaint things correctly! Obviously constant repainting will burn CPU and is only appropriate if you’re genuinely always animating your entire GUI at 60fps.

1 Like

OK. Thanks Jules. I think, as you say, this suggestion perhaps might not be appropriate for my current app, but in the future I hope to make a video game or two and I imagine that this will be perfect for that circumstance.