How to delete component from the screen, when it has already deleated from array

gui

#1

Hello, i am trying to understand how to work with arrays, and i created an application, where you can create components, by changing slider value and these components are dragable. So, i decided to create an array of this components, and when the slider changes value, i clear the array and create new components, but old components are still exist and they are drawn on the screen. So, how can i delete them? Thank you!

MainComponent.h, in sliderValueChanged(Slider *slider) function i clear my array and create new components:

#pragma once
#include "../JuceLibraryCode/JuceHeader.h"
#include "DragClass.h"

//==============================================================================
class MainComponent   : public Component, Slider::Listener
{
public:
    //==============================================================================
    MainComponent();
    ~MainComponent();

    //==============================================================================
    void paint (Graphics&) override;
    void resized() override;

	void sliderValueChanged(Slider *slider)
	{
		if (slider == &numberOfRects)
		{
			myDragArray.removeRange(0, myDragArray.size());

			for (int i = 0; i < numberOfRects.getValue(); i++)
			{
				DragClass* dragRect = new DragClass();
				myDragArray.add(dragRect);
				addAndMakeVisible(dragRect);
				dragRect->centreWithSize(40, 40);
			}
		}
	}

private:
    //==============================================================================
	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainComponent)
		Array<DragClass*> myDragArray;
		Slider numberOfRects;
};

MainComponent.cpp:

#include "MainComponent.h"

//==============================================================================
MainComponent::MainComponent()
{
    setSize (600, 400);

	addAndMakeVisible(numberOfRects);
	numberOfRects.setRange(0, 100, 1);
	numberOfRects.setValue(2);
	numberOfRects.setSliderStyle(Slider::SliderStyle::LinearHorizontal);
	numberOfRects.setTextBoxStyle(Slider::TextBoxLeft, true, 60, 20);
	numberOfRects.addListener(this);
}

MainComponent::~MainComponent()
{
	for (int i = 0; i < myDragArray.size(); i++)
		delete myDragArray[i];
}

//==============================================================================
void MainComponent::paint (Graphics& g)
{
	g.fillAll(Colours::black);
}

void MainComponent::resized()
{
	numberOfRects.setBounds(250, 350, 250, 20);
}

And here is my DragClass, where i draw a rectangle and make it dragable
DragClass.h:

#pragma once
#include "../JuceLibraryCode/JuceHeader.h"
//==============================================================================
class DragClass    : public Component
{
public:
    DragClass();
    ~DragClass();

    void paint (Graphics&) override;
    void resized() override;
	void mouseDown(const MouseEvent& e) override
	{
		dragger.startDraggingComponent(this, e);
	}

	void mouseDrag(const MouseEvent& e) override
	{
		dragger.dragComponent(this, e, &constrainer);
	}
private:
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DragClass)
	ComponentBoundsConstrainer constrainer;
	ComponentDragger dragger;
};

DragClass.cpp:

#include "../JuceLibraryCode/JuceHeader.h"
#include "DragClass.h"
//==============================================================================
DragClass::DragClass()
{
}
DragClass::~DragClass()
{
}

void DragClass::paint (Graphics& g)
{
	g.fillAll(Colours::black);
	auto area = getLocalBounds().reduced(2);
	g.setColour(Colours::yellow);
	g.drawRect(area, 2);
}

void DragClass::resized()
{
	constrainer.setMinimumOnscreenAmounts(getHeight(), getWidth(), getHeight(), getWidth());
}

#2

You are storing raw pointers in your array, so clearing/changing the array contents doesn’t delete the allocated objects. (Therefore they remain visible, will leak memory etc…) Your MainComponent destructor deletes the objects last set in the array but the pointers for the previous objects are no longer anywhere available to be deleted.

You should probably use JUCE’s OwnedArray for the drag objects. (Or std::vector<std::unique_ptr<DragClass>> )


#3

Thank you, i will try to do it with OwnedArray and find out how to work with this std::vector<std::unique_ptr<DragClass>>