TableListBox weird error on row deletion

Hi,
I have a problem with my TableListBox. It is very weird and I don’t know what I can do.

So I wanted to create a table from a .xml document. To do this I mainly used the code from the demo (WidgetsDemo.h).

Using the same principle as in the demo, I first feed my XmlElement from a file by using

std::unique_ptr<XmlElement> demoData;
demoData.reset(XmlDocument::parse(s));

XmlElement* dataList = demoData->getChildByName("DATA");
XmlElement* columnList = demoData->getChildByName("COLUMNS");

Then I use this as my base for the TableListBox, just as in the TableDemo (in WidgetsDemo.h).
This works fine. Everything is displayed, I can interact with everything, etc.I was happy about that and moved on to some advanced functions, like rightClick handling, etc.

I then wanted to implement a delete Function. I want the current row to be deleted when the user presses a button.

So I created a delete function which gets called on button press.

void removeSelectedItems()
{
	SparseSet<int> selectedRows = table.getSelectedRows();
	for (int j = 0; j < selectedRows.size(); ++j)
	{
		dataList->removeChildElement(dataList->getChildElement(selectedRows[j]), true);
		table.updateContent();
	}
}

This also works fine. Almost.
And this is the problem. As I have 36 items in the XmlElement, it occurs that some table rows are out of view. If I now delete a row, it gets deleted, everything gets, moved up and even the next row gets selected. But as soon as the end of the table gets scrolled into view, either manually or as a cause of too many items being deleted, the program crashes. I can scroll normally to the end of the table just fine, before I delete anything. But as soon as I try to delete a row and the end of the table is visible, the program crashes!

Visual Studio shows me an error at the function MyApp.exe!juce::LinkedListPointer<juce::XmlElement::XmlAttributeNode>::get() Line 104 C++
also Visual Studio shows me a BubbleMessage saying

Raised Exception: Readpermission violation
"this" was "0x8".

The only thing I can think of that may be causing this issue is that the TableListBox still tries to draw the element, although it is deleted.

I have now spent over 4 hours trying to figure it out, but I’m surrendering now.
I would be very happy about fast help from the community…

Update:

I am still trying to figure out the issue. I experimented a little bit and debugged a lot, to see if maybe the getNextElement() of the previous item doesn’t get updated. Turns out it works quite fine. If I delete the row with ID = 5, the getNextElement() of the ID = 4 row now returns the row with ID = 6. But I discovered something interesting. Apparently the same error occurs if I try to do this:

XmlElement* lastElem = dataList->getChildElement(dataList->getNumChildElements() - 1);
lastElem->getNextElement()->getStringAttribute("ID").toStdString()

Of course I expected an exception from that, as there is no next Element after the last one and getNextElement() returns a nullptr. If I check for getNextElement() == nullptr and handle this case, everything works fine.
What I still understand is why my TableListBox wants to use the next Element of the last Element, only when I delete an Item… Because without any deletion everything works fine…

Final Update:

Fine, fine!
I’ll admit I’m just dumb. As the brainless person that I am, I forgot that the number of rows of the TableListBoxModel was hardcoded only once in the XML-Document load function. I simply had to call numRows = dataList->getNumChildElements(); before updating, and who would have guessed… everything works. YAY
(Facepalm over 9000)

I hope this helps someone, who is equally blind as I am.

Yes I was just looking for this solution! Thank you, would have never thought to update the numrows variable directly as I was just calling updatecontent after inserting a new row, and saving the whole XMLElement object to a file. after updating the numrows variable then calling updatecontent, it now works with the way I intended.

1 Like

Glad to hear I’m not the only one to have missed that.