表のデータを昇順、降順で並び替えるようなこともできるみたいです。
便利な機能
JUCEチュートリアル、「Interface Design」、「The TableListBox class」チュートリアル「Sorting the Data」をやっていきます。任意の列の項目について、項目の並び替えができるような機能を追加していきます。
公式のチュートリアルページはこちらになります。
https://docs.juce.com/master/tutorial_table_list_box.html
こんな人の役に立つかも
・JUCEプログラミングを勉強している人
・JUCEチュートリアル「The TableListBox class」をやっている人
・JUCEの表の項目を並べ替えたい人
sortOrderChanged関数
sortOrderChanged関数を実装することで、表の列項目の右に出現する三角を押した時に、列項目での並び替えの処理を定義することができます。
今回は、このスクショの上のボタンを押すことで、次のように降順にしたり、また、昇順に戻したりすることができるようにします。
sortOrderChanged関数は、TableTutorialComponentクラスのpublicなメンバ関数として実装しています。受け取る引数として、newSortColumnIdに列番号、isForwardsにbool値を受け取ります。
class TableTutorialComponent : public juce::Component,
public juce::TableListBoxModel
{
public:
//...略...
void sortOrderChanged(int newSortColumnId, bool isForwards) override
{
//[1]列番号が0でないことを確認します。
if (newSortColumnId != 0)
{
//[2]行の並び替えを行います。
TutorialDataSorter sorter(getAttributeNameForColumnId(newSortColumnId), isForwards);
dataList->sortChildElements(sorter);
//[3]表の更新を行います。
table.updateContent();
}
}
//...略...
[1]では、列番号が0でないことを確認して、[2]で並び替えを行います。XmlElementクラスのsortChildElements関数を利用してデータ自体を並び替えます。与える引数としてcomparatorオブジェクトというものが必要になります。これは、この後実装するTutorialDataSorterというクラスで実装します。このクラスには、「int compareElements (const XmlElement* first, const XmlElement* second);」という関数を実装して、並び替えの処理を実装することになります。
[3]で、ListBoxクラスのupdateContent関数で表の内容の変更を適用します。
TutorialDataSorterクラスの追加
TableTutorialComponentクラスのprivateなメンバとして、次のプログラムの[1]のような「TutorialDataSorter」という内部クラスを実装していきます。
private:
//...略...
//[1]実装するクラスです。
class TutorialDataSorter
{
public:
//[3]コンストラクタです。
TutorialDataSorter(const juce::String& attributeToSortBy, bool forwards)
: attributeToSort(attributeToSortBy),
direction(forwards ? 1 : -1)
{}
//[4]並び替えの関数です。
int compareElements(juce::XmlElement* first, juce::XmlElement* second) const
{
//[4-1]文字列を比較します。
auto result = first->getStringAttribute(attributeToSort)
.compareNatural(second->getStringAttribute(attributeToSort));
//[4-2]同じ文字列の場合、ID番号で並べます。
if (result == 0)
result = first->getStringAttribute("ID")
.compareNatural(second->getStringAttribute("ID"));
return direction * result;//[4-3]値を返します。
}
private:
//[2]
juce::String attributeToSort;
int direction;
};
//...略...
まずは、[2]に利用する変数などをprivateなメンバとして定義しておきます。(一番下です)このクラスでは、Stringsクラスの「attributeToSort」とint型変数の「direction」を利用する予定ですので、この2つを定義しています。
[3]はコンストラクタです。引数としてStringクラスのオブジェクト(の参照)、と、項目の降順、昇順を表現するfowardsというbool変数を受け取ります。これらはメンバイニシャライザでそれぞれ、先ほど定義したprivateなメンバに「attributeToSortByはattributeToSortへ」、「forwaedsはdirectionへ」と格納されます。direction変数はint型なので、三項演算子でtrueの場合1、falseの場合0と変換して格納しています。
[4]は、必ず定義する関数です。引数で、2つのデータを受け取ることがわかります。この関数は、intを返し、返す値は次のように定義されています。
・firstがsecondの前に来る場合「正」
・2つの値が同値の場合「0」
・secondがfirstの前に来る場合「負」
[4-1]では、文字列をStringクラスのcompareNatural関数で比較します。大文字小文字を区別せず、数字なども比較できる便利な関数です。ここで、同じ文字列の場合、0となります。[4-2]では、同じ文字列の場合、列項目「ID」で並び替えます。
[4-3]では返す値として、directionをかけています。昇順にするのか、降順にするのかをここで掛け合わせることで並びの方向を決定します。