The Red Penguin

Introduction to event listeners


Wednesday 29 July 2020

Graphical user interfaces are, in general, implemented using the Event Listener Pattern. Every time we click a button, an event is emitted. An event listener will be listening to events and react to them.

Implementing a button

1. First step is to go into MainComponent.h. I want the button to tell MainComponent when it's going to be clicked. I need to add it to the list of inheritance relationships. So I have changed

class MainComponent : public juce::AudioAppComponent

to

class MainComponent : public juce::AudioAppComponent,
public juce::Button::Listener

I've added juce:: to Button::Listener - the video didn't mention it but looks like a feature of Juce 6.

2. Because I am now inheriting from Button::Listener I need to implement that function. So in the public section of that class (below void resized) I will enter:

/** implement Button::Listener */
void buttonClicked(juce::Button *) override;

3. Next I need to go to the MainComponent.cpp file and implement it by adding code at the bottom:
void MainComponent::buttonClicked(Button *button)
{
DBG("Button was clicked");
}


4. In the constructor MainComponent::MainComponent() in MainComponent.cpp where we configure the GUI, under addAndMakeVisible(volSlider); we can add more code:

playButton.addListener(this);

Problems with extra buttons

MYK worked through adding a second stop button (see Adding a GUI widget to the JUCE app), and then he demonstrated that if you click the 2nd button, this also was putting up the "Button was clicked" message to the console.

So this is where we use the argument in the button listener. The simplest way to do this is to look at the memory address of our play button and see if it's the same as the pointer.

The code would be:

void MainComponent::buttonClicked(juce::Button* button)
{
if (button == &playButton)
{
DBG("Play button was clicked");
}
if (button == &stopButton)
{
DBG("Stop button was clicked");
}
}