本文章介绍了 JUCE 中的一个关键概念:监听器和广播器系统。
我们通过实施简单的操作来响应按钮点击来研究这一点。
该类由两个子组件组成:TextButton 对象和 Label 对象。TextButton 对象可以显示包含某些特定文本的按钮,而 Label 对象可以显示一段文本。
1、添加侦听器基类
在 JUCE 中,按钮、滑块和许多其他类型的控件可能需要通知其他对象其状态的变化,这些控件是一种广播器对象。为了响应 broadcaster 对象中的更改,其他类需要成为该特定类型的 broadcaster 的侦听器。侦听器还需要至少注册到该类型的一个特定广播器对象。(JUCE中的广播员-听众系统遵循观察者模式。许多 broadcaster 对象都包含一个嵌套类,我们可以从中继承该类,以便成为该类型 broadcaster 的侦听器。例如,Button 类包含一个用于此目的的嵌套类 Button::Listener。
Listener
class XXXX: public juce::Component,
public juce::Button::Listener // [1]
{
public:
注意
要使用 Button::Listener 类,我们需要将其添加为基类。在我们的例子中,我们需要添加 Button::Listener 类作为类 [1] 的基类
2、配置接口(声明定义对象和重写虚函数)
2.1、声明定义对象如下:
.h文件
class MainContentComponent : public juce::Component
{
public:
//==============================================================================
MainContentComponent()
{
// ...
}
~MainContentComponent()
{
// ...
}
void resized() override
{
// ...
}
private:
juce::TextButton checkTheTimeButton;
juce::Label timeLabel;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};
.cpp文件
MainContentComponent()
{
addAndMakeVisible (checkTheTimeButton);
checkTheTimeButton.setButtonText ("Check the time...");
addAndMakeVisible (timeLabel);
timeLabel.setColour (juce::Label::backgroundColourId, juce::Colours::black);
timeLabel.setColour (juce::Label::textColourId, juce::Colours::white);
timeLabel.setJustificationType (juce::Justification::centred);
setSize (600, 110);
}
2.2 重写虚函数(实现监听器回调)
重写
void buttonClicked(juce::Button* buttonThatWasClicked);
.h文件
using namespace juce;
using namespace std;
class XXXX: public juce::Component,public juce::Button::Listener
{
public:
XXXX();
~XXXX() override;
void paint (juce::Graphics&) override;
void resized() override;
void buttonClicked(juce::Button* buttonThatWasClicked);
private:
juce::TextButton checkTheTimeButton;
juce::Label timeLabel;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RectLayout)
};
.cpp文件
void XXXX::buttonClicked(juce::Button* buttonThatWasClicked)
{
//判断是那个按钮
if (buttonThatWasClicked == &checkTheTimeButton)
{
//实现的逻辑
auto currentTime = juce::Time::getCurrentTime();
auto includeDate = true;
auto includeTime = true;
auto currentTimeString = currentTime.toString(includeDate, includeTime);
timeLabel.setText(currentTimeString, juce::dontSendNotification);
}
}
2.3 设置监听(连接)(非常关键;不添加函数不会进入ButtonClicked()函数)
checkTheTimeButton.addListener (this)
在需要的地方加入上述语句,实现信号连接。
析构函数中添加:checkTheTimeButton.removeListener(this);
2.4 另一种连接方式( Button::onClick)
直接设置接收函数:checkTime();
添加:checkTheTimeButton.onClick = [this] { checkTime(); };
checkTime为实现函数
.h文件
using namespace juce;
using namespace std;
class RectLayout : public juce::Component,public juce::Button::Listener
{
public:
RectLayout();
~RectLayout() override;
void paint (juce::Graphics&) override;
void resized() override;
void checkTime();
private:
juce::TextButton checkTheTimeButton;
juce::Label timeLabel;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RectLayout)
}
.cpp文件
#include <JuceHeader.h>
#include "RectLayout.h"
//==============================================================================
RectLayout::RectLayout()
{
addAndMakeVisible(checkTheTimeButton);
checkTheTimeButton.setButtonText("Check the time...");
checkTheTimeButton.onClick = [this] { checkTime(); };
addAndMakeVisible(timeLabel);
timeLabel.setColour(juce::Label::backgroundColourId, juce::Colours::black);
timeLabel.setColour(juce::Label::textColourId, juce::Colours::red);
timeLabel.setJustificationType(juce::Justification::centred);
}
RectLayout::~RectLayout()
{
}
void RectLayout::paint (juce::Graphics& g)
{
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
g.setColour (juce::Colours::blue);
g.drawRect (getLocalBounds(), 1); // draw an outline around the component
g.setColour (juce::Colours::white);
g.setFont (14.0f);
}
void RectLayout::resized()
{
checkTheTimeButton.setBounds(0, 190,this->getWidth(),30);
timeLabel.setBounds(0,160,this->getWidth(),30);
}
void RectLayout::checkTime()
{
auto currentTime = juce::Time::getCurrentTime();
auto includeDate = true;
auto includeTime = true;
auto currentTimeString = currentTime.toString(includeDate, includeTime);
timeLabel.setText(currentTimeString, juce::dontSendNotification);
}