JUCE复合控件之ListBox详解

复合控件:前台UI界面需抽象数据模型或其它辅助类才可以正常工作的复杂控件。绝大多数复合控件,均为“模型-视图”模式。即:视图类负责前台显示数据或提供人机交互的操作界面,抽象的模型类负责数据来源与数据的业务处理。实际编程时,在内容组件类中声明、管理和使用视图类的对象,同时,内容组件类继承自抽象的模型类,实现其纯虚函数,用自身(this)将二者关联到一起(视图设置模型),共同实现所需的功能。

ListBox是Component的直接派生类。要使用ListBox列表框,内容组件需继承ListBoxModel(列表框模型)类,实现该基类的2个纯虚函数,重写该基类的1个核心函数。ListBox对象的构造参数需要一个ListBoxModel类的指针。某个内容组件类使用列表框的常规步骤有5:

1、继承基类:

class FontsAndTextDemo : public Component, 
                         public ListBoxModel...

2、声明对象(此处声明为private作用域指针):

// 如果声明为普通指针,需在析构函数中销毁之
ScopedPointer<ListBox> listBox;

3、创建、添显、设置(本类无addListener()绑定捕获的功能)。类的构造函数中:

/** 创建ListBox对象,添加并显示。该对象需两个构造参数,一为其名称,二为ListBoxModel对象。因为本类继承了列表框模型类,因此自身即是一个列表框模型对象,2参写 this 即可 */
addAndMakeVisible (listBox = new ListBox ("myListbox", this));
listBox->setRowHeight (28);    // 设置列表框中每一行的行高

// 设置列表框的边框颜色,黑色半透明
listBox->setColour (ListBox::outlineColourId, 
                    Colours::black.withAlpha (0.5f));

listBox->setOutlineThickness (1);    // 设置列表框边线宽度(边框)

// 设置初始所选行,随机给出int参数,随机值的范围:0~数组fonts中的元素个数
listBox->selectRow (Random::getSystemRandom().nextInt (fonts.size()));

4、布局定位。类的resized()方法中setBounds()。可使用分栏技术,参见后文。

5、实现纯虚。继承而来的两个纯虚函数需实现,一个核心函数需重写:

// 返回列表框中的行数,本例,列表框的行数为数组fonts中的元素个数
int getNumRows() 
{ 
    return fonts.size(); 
}

/* 本函数执行一次则绘制列表框中的一行,系统内部自动重复调用此方法,将所有行绘制到列表框中。本例的绘制结果是:本机已安装的所有系统字体的文本名称逐行显示 */
void paintListBoxItem (int rowNumber, Graphics& g, int width, 
                       int height, bool rowIsSelected) 
{
    // 如果该行处于选中状态,则将其背景色绘制为浅蓝色
    if (rowIsSelected)   
        g.fillAll (Colours::lightblue);

/* 以下语句很有趣,用某个字体的样式绘制该字体的文本名称,使用户对所选的字体一目了然。定义一个字体对象,初始化为fonts数组中保存的某个字体,数组的下标为本函数的1参. fonts数组保存了本机所有已安装的字体对象,详见JUCE-DEMO字体与文本模块的源文件。 */
    Font font (fonts [rowNumber]);

    // 设置字体高度(大小)为参数height * 0.7
    font.setHeight (height * 0.7f);

    // 设置字体、颜色,准备绘制文本
    g.setFont (font);    
    g.setColour (Colours::black);

    // 此语句的1参为刚刚定义的font对象的字体原名
    g.drawText (font.getTypefaceName(), 4, 0, width - 4, 
                height, Justification::centredLeft, true);
} 

// 重写此核心函数。用户点选或不选某个项目时,内部调用此函数。参数为所选行的ID。
void selectedRowsChanged (int lastRowselected)  
{
   // 在此进行判断处理... 
}

如需实现列表项可拖放,则重写getDragSourceDescription(),返回所拖放的列表项的描述核心语句示例:返回列表框当前所选行的索引值:

int selectedId = listBox->getSelectedRow();

由上可知,ListBoxModel和ListBox这两个类协同配合实现列表框功能。

ListBoxModel抽象类的重要成员函数(网站发布,略)。

ListBox类的重要成员函数(网站发布,略)。

ListBox有两个派生类
 TabbedListBox:表格,后文详述。
 FileListComponent:文件列表组件。该组件可在列表框中显示某个目录下的文件,是文件浏览组件FileBrowserComponent必不可少的组合类,而FileBrowserComponent的对象又是JUCE内置的文件浏览器FileChooserDialogBox所必不可少的构造参数。