[bug] CallOutBox doesn't refresh the Path of its shape when its LookAndFeel changes

I’m using a custom LookAndFeel to draw callout boxes with sharp corners.

I’m displaying a callout like this

callout.reset (new CallOutBox (infoPanel, targetArea, this));
callout->setLookAndFeel (calloutLookAndFeel);
callout->enterModalState (true);

The problem is that the shape of the callout path is calculated in its constructor, when the look and feel it has access to is still the default one (that has rounded corners).

I expected assigning a new look and feel (the one that results in sharp corners) to the callout would make it recalculate its path, but that does not happen.

The fix is easy: it is enough to add this to the CallOutBox class:

void lookAndFeelChanged() override { refreshPath(); };

I’ve seen this kind of thing in many places (LookAndFeel methods not recalled on LookAndFeel changes). In createFileBrowserGoUpButton()?, the suggested solution (which doesn’t seem like a solution to me) is setting everything in the default look and feel, stored as a shared resource.

This is not an option in my case because the LookAndFeel that I use as default must have a different shape for its callouts.

Yep, it’s not an actual solution. Like, it forces these elements to be global for the whole GUI. I wasn’t sure if that was intended or just an omission.

Anyone from the JUCE team willing to consider this?


Buuump, my first post above still has got no feedback from any JUCE maintainer for what seems like a JUCE (small) bug


  1. In the constructor of a CallOutBox, the shape of its outline is calculated as a Path (with rounded corners of a certain radius, etc.)

  2. A LookAndFeel can legitimately want its CallOutBoxes to have a different shape (e.g. with sharp corners)

  3. At the moment, changing the LookAndFeel of an existing CallOutBox does not cause the recalculation of the Path for its outline according to the new LookAndFeel

  4. One would expect that the outline gets updated according to the new LookAndFeel instead, and that’s easily achieved by overriding lookAndFeelChanged() in the CallOutBox class and calling the private CallOutBox::refreshPath() from there.

This issue should be fixed by the following commit: