Help sought for paint() issue


#1

I'm having a rather embarrassing affair with a custom component. Its paint() method is never called. I create the component, I add it to my application's main component, resize it, etc., but for some reason paint() is never called. The object is valid, its constructor is called and resized is called. I even put a repaint() call in its mouseDown() method. The object's mouseDown method is called when I click on it, and so is repaint(), but the object's paint() method is not. (I can't actually see the component but I know where it lives..). I'm at a loss here, I've tried everything I can think of. I hold my hand up and say I'm sure this is clearly something I'm doing wrong, but for the life of me I don't know where to look next. Anyone got any ideas?


#2

Have you checked it's actually visible on screen? If resized is being called add a sub component like a button or something and see if that gets drawn. Sounds like this is happening though if mouseDown is being called.

It's not a silly typo in the method signature it it? If you're compiler supports it (and even if it doesn't) you should always use the override keyword, I've been saved so many times already by this, can't believe I lived without it for so long!


#3

Thanks for the reply Dave. In the end I'm simplified everything(there was some viewport action going on too that wasn't helping things..). In doing so I think I have found the point at which the strangeness occurs.It seems that if I create an object and add it directly to the plugin's main component its paint method gets called. If I create an object, add it to an OwnedArray of components and then try to add the object from the ownedArray, its paint method doesn't get called. For example:


arrayOfComps.add(new CustomComp("test"));
arrayOfComps[arrayOfComps.size()-1]->setBounds(0,0,100,50);
addAndMakeVisible(arrayOfComps[arrayOfComps.size()-1]);

If I do this however, all works fine:

myComp = new CustomComp("test");
myComp->setBounds(0,0,100,50);
addAndMakeVisible(myComp);

What's really odd is that in both cases the customComponent's resized method gets called, but in the case of the OwnedArray the paint method doesn't. Both methods should work, and in fact I add custom controls to that OwnedArray and display them like this all the time. For some reason this particular object is just not playing ball when I insert it into that array. Here's the simple component I'm using:

class CustomComp : public Component
{
public:
ScopedPointer<TextButton> button;
//---- constructor -----
CustomComp(String name){
    setName(name);
    button = new TextButton("");
    button->setBounds(0, 0, getWidth(), getHeight());
    addAndMakeVisible(button);
}

~CustomComp(){}

void paint(Graphics& g){
Logger::writeToLog("test");  
}

void resized(){
button->setBounds(0, 0, getWidth(), getHeight());    
}

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomComp);
};


#4

They say a good run is better than a bad stand. In the end I reverted to an older version of my project where that problem wasn't present. What have I learned? Not a whole lot, but at least I can move on with my life!

 

 


#5

Are you sure your components aren't being deleted too early? resized() will get called as soon as you call setBounds() but there's a chance something else is clearing your array before the first paint call. It is a member variable and not on the stack somewhere?

I would put a breakpoint in the destructor of CustomComp just to check the objects are getting deleted when you expect.

It's also probably clearer to write your first block of code like this:

CustomComp* newComp = new CustomComp ("test"); newComp->setBounds (0, 0, 100, 50); addAndMakeVisible (newComp); arrayOfComps.add (newComp);

That way you're not constantly getting the last component from the array.

Also one last thing, when you say the paint method isn't getting called I presume that the embedded text button isn't being displayed either?


#6

That's right, no sign of the button either.  You're right about making the code clearer too, I have blabla[blabla.size()-1] all over the place. The destructor is the one method I didn't put a breakpoint in, go figure. Oh well, it's not like that will be the last time I get stuck on something, thankfully these moments are becoming less and less frequent!