juce::DialogWindow::LaunchOptions blank / empty in Android

I found a simple example to use MIDI over Bluetooth (GitHub - COx2/juce_midi_ble_example) and have been trying to get it to work on an Android device.

I’ve altered it a bit to get it to work with JUCE 6.

When I press the “Device Settings” button was expecting something like this juce_midi_ble_example/IMG_0175.PNG at master · COx2/juce_midi_ble_example · GitHub
But the window is blank except for the title and close cross.

void MainComponent::showDeviceSetting()
{
    juce::AudioDeviceSelectorComponent selector(deviceManager,
                                                0, 256,
                                                0, 256,
                                                true, true,
                                                true, false);
    selector.setSize(400, 600);

    juce::DialogWindow::LaunchOptions dialog;
    dialog.content.setNonOwned(&selector);
    dialog.dialogTitle = "Audio/MIDI Device Settings!";
    dialog.componentToCentreAround = this;
    dialog.dialogBackgroundColour = getLookAndFeel().findColour(juce::ResizableWindow::backgroundColourId);
    dialog.escapeKeyTriggersCloseButton = true;
    dialog.useNativeTitleBar = false;
    dialog.resizable = false;
    dialog.useBottomRightCornerResizer = false;

    //dialog.runModal();
    dialog.launchAsync();
}

It feels like the content is being destroyed before it gets a chance to be displayed due to the use of launchAsync rather than runModal but I’m just guessing here.

Apparently, this also happens on Linux desktop.
Also happens in an Android emulator but I don’t know what if any options would appear in an emulator yet.

Is there anything obvious to anyone why I’m not getting the options in my window?

Thanks

The problem is that selector is created on the stack, so its lifetime will end at the end of showDeviceSetting. However, launchAsync (and therefore showDeviceSetting) returns immediately, and the selector component is destroyed before the window has a chance to show.

Here are some options to fix this:

  • Make the AudioDeviceSelectorComponent a data member of your MainComponent. Give it a size in the constructor of your MainComponent. Then, add it to your options like so:
    juce::DialogWindow::LaunchOptions dialog;
    dialog.content.setNonOwned (&selector);
    
  • Alternatively, create the selector component on the heap and ask the dialog component to take ownership:
    auto selector = std::make_unique<juce::AudioDeviceSelectorComponent> (deviceManager,
                                                                          0,
                                                                          256,
                                                                          0,
                                                                          256,
                                                                          true,
                                                                          true,
                                                                          true,
                                                                          false);
    selector->setSize (500, 500);
    
    juce::DialogWindow::LaunchOptions dialog;
    dialog.content.setOwned (selector.release());
    
1 Like

Legend

I did try changing setNonOwned to setOwned, so I was on the right path but obviously that in itself wasn’t enough.

Thank you, working perfectly now.