Custom component in ListBox


#1

Hi,
I am new to juce, I am getting some problem while creating a list box with custom component in my case i wants to use textEditor.
I have followed the same step as in TableDemo sample programs.

I have created two button add and del to add row into the list box. when the click is made on the “add” button in that case I am creating a new row and increments hte rowCount by 1 and calling the updateContent() of the list box.

But I am not getting how to managed these components of the individual row. As when I click on "del " button I want to delete a row. here I decrements the rowCount value by. But in face i also wanted to delete the row component which I have added.

[code]// includes
#include “juce.h”

class TestListBoxDialogComponents;

//********************************************************************************************************************************
class TestListBoxDialog : public juce::DialogWindow
{
public:
TestListBoxDialog();
~TestListBoxDialog();

private:
void closeButtonPressed();

private:
TestListBoxDialogComponents *mComponents;
};

//********************************************************************************************************************************
class TestListBoxDialogComponents : public juce::Component,
public juce::ListBoxModel,
public juce::ButtonListener
{
public:
TestListBoxDialogComponents();
~TestListBoxDialogComponents();

private:
virtual void resized();
virtual int getNumRows();
virtual void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected);
virtual void buttonClicked(juce::Button button);
virtual Component
refreshComponentForRow (int rowNumber, bool isRowSelected, juce::Component* existingComponentToUpdate);
void AddRow();
void DeleteRow();
void GetText();

private:
juce::ListBox *mListBox;
juce::TextButton *mAddRowButton;
juce::TextButton *mDeleteRowButton;
juce::TextButton *mTestButton;
int mRowCount;
};

class CustomComponent : public Component
{
public:
CustomComponent(TestListBoxDialogComponents *owner) : mOwner(owner)
{
addAndMakeVisible(&mTextEditor);
}

~CustomComponent()
{
}

void resized()
{
	mTextEditor.setBoundsInset(juce::BorderSize(2));
    //comboBox.setBoundsInset(BorderSize (2));
}

// Our demo code will call this when we may need to update our contents
void setRow(const int inRow)
{
    mRow = inRow;
    //comboBox.setSelectedId (owner.getRating (row), true);
}

//void comboBoxChanged (ComboBox* /*comboBoxThatHasChanged*/)
//{
//    owner.setRating (row, comboBox.getSelectedId());
//}

public:
TestListBoxDialogComponents *mOwner;
juce::TextEditor mTextEditor;
int mRow;
};

[/code]

[code]
// includes
#include “TestListBox.h”

TestListBoxDialog::TestListBoxDialog() : DialogWindow(“Test box dialog”, juce::Colour(240,240,240), true, true),
mComponents(0)
{
// SCPrefDialog setup & initialization.
this->centreWithSize(400, 400);
this->setVisible(true);
this->setTitleBarHeight(20);

// Add and initialize SCPrefDialog Components.
mComponents = new TestListBoxDialogComponents();
this->setContentComponent(mComponents);

// Call this as the last function to this contructor.
this->runModalLoop();

}

void TestListBoxDialog::closeButtonPressed()
{
setVisible(false);
delete this;
}

TestListBoxDialog::~TestListBoxDialog()
{
delete mComponents;
}

//********************************************************************************************************************************

TestListBoxDialogComponents::TestListBoxDialogComponents() : mRowCount(0),
mListBox(0),
mAddRowButton(0),
mTestButton(0),
mDeleteRowButton(0)
{
mListBox = new juce::ListBox(“New words list”, this);
mListBox->setRowHeight(19);
this->addAndMakeVisible(mListBox);
mListBox->setBounds(10, 10, 372, 300);
mListBox->setOutlineThickness(2);
mListBox->setColour(juce::ListBox::outlineColourId, juce::Colours::lightgrey);

/* mAddRowButton setup & initialization. */
mAddRowButton = new juce::TextButton("+");
this->addAndMakeVisible(mAddRowButton);
mAddRowButton->setBounds(20, 340, 18, 18);
mAddRowButton->addListener(this);
mAddRowButton->setConnectedEdges(juce::Button::ConnectedOnLeft | juce::Button::ConnectedOnRight);

/* mDeleteRowButton setup & initialization. */
mDeleteRowButton = new juce::TextButton(L"—");		/* em dash (on win os ALT + 0151) */
this->addAndMakeVisible(mDeleteRowButton);
mDeleteRowButton->setBounds(38, 340, 18, 18);
mDeleteRowButton->addListener(this);
mDeleteRowButton->setConnectedEdges(juce::Button::ConnectedOnLeft | juce::Button::ConnectedOnRight);

/* mTestButton setup & initialization. */
mTestButton = new juce::TextButton("T");		/* em dash (on win os ALT + 0151) */
this->addAndMakeVisible(mTestButton);
mTestButton->setBounds(60, 340, 18, 18);
mTestButton->addListener(this);
mTestButton->setConnectedEdges(juce::Button::ConnectedOnLeft | juce::Button::ConnectedOnRight);

}
TestListBoxDialogComponents::~TestListBoxDialogComponents()
{
delete mListBox;
delete mDeleteRowButton;
delete mAddRowButton;
}

void TestListBoxDialogComponents::resized()
{
}

int TestListBoxDialogComponents::getNumRows()
{
return mRowCount;
}

void TestListBoxDialogComponents::paintListBoxItem(int rowNumber, Graphics& g, int width, int height, bool rowIsSelected)
{
}

void TestListBoxDialogComponents::buttonClicked(juce::Button *button)
{
if(button == mAddRowButton)
{
AddRow();
}
else if(button == mDeleteRowButton)
{
DeleteRow();
}
else if(button == mTestButton)
{
GetText();
}
}

Component* TestListBoxDialogComponents::refreshComponentForRow(int rowNumber, bool isRowSelected, juce::Component* existingComponentToUpdate)
{
CustomComponent* row = (CustomComponent*) existingComponentToUpdate;
if(row == 0)
row = new CustomComponent(this);

row->setRow(rowNumber);
return row;

}

void TestListBoxDialogComponents::AddRow()
{
mListBox->addChildComponent(new CustomComponent(this), mRowCount++);
mListBox->updateContent();
}

void TestListBoxDialogComponents::DeleteRow()
{
if(mRowCount > 0)
{
int rowNum = mListBox->getNumChildComponents();
CustomComponent com = (CustomComponent)mListBox->getComponentForRowNumber(rowNum-1);
if(com)
{
//mListBox->removeChildComponent(rowNum);
//delete com;
}

	mRowCount--;
	mListBox->updateContent();
}

}

void TestListBoxDialogComponents::GetText()
{
int rowNum = mListBox->getNumChildComponents();
for(int i = 0; i< rowNum; i++)
{
CustomComponent com = (CustomComponent)mListBox->getComponentForRowNumber(i);
int row = com->mRow;
juce::String s = com->mTextEditor.getText();
}
}[/code]


#2

Don’t add your row components directly! That’s the listbox’s job!


#3

Thanks sir !

I guess you are saying not do add this
mListBox->addChildComponent(new CustomComponent(this), mRowCount++);
simply crementing the mRowCount also displays a textEditor.

Also when I decrements the row count the last column disappears. But I am not able to retrieve the data in the text editor.


#4

Never add or remove components yourself to a listbox. Tell it how many rows you have, and it’ll update everything itself. Try searching the forum or codebase for refreshComponentForRow and I’m sure there are plenty of examples.


#5

If I recall correctly, doesn’t the Juce Demo have a listbox with custom components? Like… an edit box, and a dropdown?


#6

Yes… you are right!

TableDemo is adding custom component for a particular cell in a table. Here I wants to add custom component for rows in the list box. Basically, I wants to make the list box such that i can edit the text of any particular row, delete any row or add a new row in the list box from the UI. Is it possible with list box??


#7

@jules

Thanks you sir!

Got some previous post with “refreshComponentForRow” key.