Odd Button::Listener::buttonClicked return


#1

Greetings,

I have come to notice an odd behavior in a small program I’ve created to add multiple time blocks together (HH:MM). After running through debug in VS2017, I’ve noticed that the Button pointer returned after a few operations is not the actual button that is being triggered. Related code below.

class MainContentComponent   : public Component, public Button::Listener
{
	public:
		MainContentComponent();
		~MainContentComponent();

		void resized() override;
		void buttonClicked(Button *) override;

	private:
		Array<TextButton*> buttonArray;
		
		JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

MainContentComponent::MainContentComponent()
{
	for (int i = 0; i < 14; i++)
	{
		TextButton *button = new TextButton(String());
		button->addListener(this);
		buttonArray.add(button);
		addAndMakeVisible(button);
	}
}

void MainContentComponent::buttonClicked(Button *b)
{
	const String name = b->getComponentID();
	
	keyPress(name);
}

In the MainContentComponent::resized() function, I run addShortcut() and setComponentID() to each button, for example:

buttonArray[0]->addShortcut(KeyPress('7'));
buttonArray[0]->addShortcut(KeyPress(KeyPress::numberPad7));
buttonArray[0]->setComponentID(String("7"));

buttonArray[0]->addShortcut(KeyPress(KeyPress::escapeKey));
buttonArray[0]->setComponentID(String("AC"));

In almost all cases, this flow works fine; typing numbers on the numpad is properly picked up by buttonClicked(), and the proper (or at least expected) pointer is passed to the function, with the proper component ID. But I’ve found an odd case in which it breaks down. If I press various keys (on physical numpad), followed by a mouse click on one of the buttons, again followed by various numpad keys, the next time I physically press the numpad ‘Enter’ key, the buttonClicked() function receives the button last picked by the mouse, rather than the actual key pressed (numpad Enter).

Am I potentially doing something wrong on this? Is this possibly an issue due to how the OS is handling key presses? Is there a bug in the Juce code somewhere?

If I’ve left out any relevant code, or description, feel free to ask. I mostly want to make sure that I’m not overlooking something here.


#2

Isn’t this exactly what you expect? Pressing enter will trigger the currently focused component which is the button which was last clicked.

Also, you should be adding your buttons to an OwnedArray or they won’t be released when the parent component is destroyed.


#3

I had completely forgotten about the focus being an issue, as I had assigned the numpad enter key as a shortcut to one of the buttons, and expected the enter key to trigger the assigned button, rather than the button recently focused through the mouse click. I imagine it will thus be an easy fix, simply forcing the mouse-clicked button to pass on obtaining focus.

As to the button objects, they’re currently handled in the main component’s destructor, though I will probably switch it over to an OwnedArray for simplicitys sake.