Tabs overlap on TabbedComponent

You can find a tiny demo application at
https://github.com/klangfreund/jucePlayground/tree/master/overlappingTabs

After launch it looks like this:

(The tabbed components have a colour with alpha = 0.5, such that the overlap is clearly visible.)

As soon as the window is resized or the 2nd or 3rd tab is clicked, the tabs jump to their correct position.
I assume LookAndFeel_V3 is used but with the spacing of LookAndFeel_V2.

The issue vanishes if setSize() is moved after the setDefaultLookAndFeel() in

MainContentComponent::MainContentComponent()
{
    setSize (300, 150);
    
    LookAndFeel::setDefaultLookAndFeel(&lookAndFeelV3);
    
    addAndMakeVisible(&secondComponent);
}

Am I doing something completely off the charts?

That's not unexpected.. It's best to set the l+f before creating any of your gui, otherwise you rely on everything correctly resizing and re-adjusting itself when the l+f changes, which is both unnecessary and likely to produce edge-cases like this.

Thanks for the insight. This made me realize that the issue is a Component with a fixed size:

The plugin I'm working on contains an animated settings panel which can slide onto and off the plugins editor window. The settings panel has a fixed size which is set in its own constructor. It is a member of the MyAudioProcessorEditor of the plugin.
LookAndFeel::setDefaultLookAndFeel(&lookAndFeelV3) is the first thing I call in the constructor of the MyAudioProcessorEditor, but the crux is that at this point the settings panel has already been initialised and therefore settingsPanel.setSize() has already been called.
This results in overlapping tabs on the settings panel.

How would you solve this? What would you consider the most elegant solution?

  • Additionally call settingsPanel.setLookAndFeel(&lookAndFeelV3) in the constructor of MyAudioProcessorEditor (That's the solution I'm using right now).
  • Create the settings panel on the heap after the LookAndFeel::setDefaultLookAndFeel(&lookAndFeelV3) call in the constructor of MyAudioProcessorEditor and refer to it with a smart pointer.
  • Call LookAndFeel::setDefaultLookAndFeel(&lookAndFeelV3) on MyAudioProcessor before MyAudioProcessorEditor is created.
  • ...

I have updated the example project to reflect this situation. Might be easier to grasp.

You could call just sendLookAndFeelChange() on your finished component to force everything to refresh itself, but if you can just set the global l+f up before any components get created, that's the best plan.

Thank you Jules!