Drawing a graph

How to draw the graph correctly after changing it by clicking on the button? If I add any rendering methods to this code, the window stops opening at all.

#include <JuceHeader.h>
#include <juce_gui_basics/juce_gui_basics.h>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>

using namespace juce;


class Graph_logics
{
    std::vector<std::vector<int>> adjacencyMatrix;
public:
    Graph_logics() { adjacencyMatrix = std::vector<std::vector<int>>(); }
    void addVertex();
    void removeVertex(int vertex);
    void addEdge(int source, int destination, int weight);
    void removeEdge(int source, int destination);
    void printAdjacencyMatrix();
    auto getAdjacencyMatrix();
    void DFS(int startVertex);
    void BFS(int startVertex);
    std::vector<int> Dijkstra(int startVertex);
};

void Graph_logics::addVertex()
{
    int numVertices = adjacencyMatrix.size();
    for (int i = 0; i < numVertices; i++) adjacencyMatrix[i].push_back(0);
    adjacencyMatrix.push_back(std::vector<int>(numVertices + 1, 0));
}

void Graph_logics::removeVertex(int vertex)
{
    int numVertices = adjacencyMatrix.size();
    if (vertex >= numVertices) { std::cout << "Invalid vertex!" << std::endl; return; }
    adjacencyMatrix.erase(adjacencyMatrix.begin() + vertex);
    for (int i = 0; i < numVertices - 1; i++) adjacencyMatrix[i].erase(adjacencyMatrix[i].begin() + vertex);
}

void Graph_logics::addEdge(int source, int destination, int weight)
{
    int numVertices = adjacencyMatrix.size();
    if (source >= numVertices || destination >= numVertices) { std::cout << "Invalid vertices!" << std::endl; return; }
    adjacencyMatrix[source][destination] = weight;
}

void Graph_logics::removeEdge(int source, int destination)
{
    int numVertices = adjacencyMatrix.size();
    if (source >= numVertices || destination >= numVertices) { std::cout << "Invalid vertices!" << std::endl; return; }
    adjacencyMatrix[source][destination] = 0;
}

void Graph_logics::printAdjacencyMatrix()
{
    int numVertices = adjacencyMatrix.size();
    for (int i = 0; i < numVertices; i++)
    {
        for (int j = 0; j < numVertices; j++) std::cout << adjacencyMatrix[i][j] << " ";
        std::cout << std::endl;
    }
}

auto Graph_logics::getAdjacencyMatrix() { return adjacencyMatrix; }

void Graph_logics::DFS(int startVertex)
{
    int numVertices = adjacencyMatrix.size();
    std::vector<bool> visited(numVertices, false);
    std::stack<int> stack;
    visited[startVertex] = true;
    stack.push(startVertex);
    while (!stack.empty())
    {
        int currentVertex = stack.top();
        stack.pop();
        std::cout << currentVertex << " ";
        for (int i = 0; i < numVertices; i++)
            if (adjacencyMatrix[currentVertex][i] != 0 && !visited[i])
            {
                visited[i] = true;
                stack.push(i);
            }
    }
}

void Graph_logics::BFS(int startVertex)
{
    int numVertices = adjacencyMatrix.size();
    std::vector<bool> visited(numVertices, false);
    std::queue<int> queue;
    visited[startVertex] = true;
    queue.push(startVertex);
    while (!queue.empty())
    {
        int currentVertex = queue.front();
        queue.pop();
        std::cout << currentVertex << " ";
        for (int i = 0; i < numVertices; i++)
            if (adjacencyMatrix[currentVertex][i] != 0 && !visited[i])
            {
                visited[i] = true;
                queue.push(i);
            }
    }
}

std::vector<int> Graph_logics::Dijkstra(int startVertex)
{
    int numVertices = adjacencyMatrix.size();
    std::vector<int> distance(numVertices, std::numeric_limits<int>::max());
    std::vector<bool> visited(numVertices, false);
    distance[startVertex] = 0;
    for (int count = 0; count < numVertices - 1; count++) {
        int minDistance = std::numeric_limits<int>::max();
        int minVertex = -1;
        for (int v = 0; v < numVertices; v++)
            if (!visited[v] && distance[v] <= minDistance) { minDistance = distance[v]; minVertex = v; }
        if (minVertex == -1) break;
        visited[minVertex] = true;
        for (int v = 0; v < numVertices; v++)
            if (!visited[v] && adjacencyMatrix[minVertex][v] != 0 &&
                distance[minVertex] != std::numeric_limits<int>::max() &&
                distance[minVertex] + adjacencyMatrix[minVertex][v] < distance[v]) {
                distance[v] = distance[minVertex] + adjacencyMatrix[minVertex][v];
            }
    } return distance;
}

class GraphPaint : public juce::Component
{
    Graph_logics* graph;
public:
    GraphPaint(Graph_logics* graph) : graph(graph) {}

    void paint(juce::Graphics& g) override
    {
        const int vertexRadius = 20;
        const int startX = 150;
        const int startY = 150;
        const int padding = 100;

        g.fillAll(juce::Colours::white);

        auto adjacencyMatrix = graph->getAdjacencyMatrix();
        int numVertices = adjacencyMatrix.size();

        for (int i = 0; i < numVertices; i++)
        {
            int x = startX + i * padding;
            int y = startY;

            // Draw vertex
            g.setColour(juce::Colours::blue);
            g.drawEllipse(x - vertexRadius, y - vertexRadius, vertexRadius * 2, vertexRadius * 2, 2);

            // Draw vertex label
            g.setColour(juce::Colours::black);
            juce::String vertexLabel = juce::String(i);
            g.drawText(vertexLabel, x - vertexRadius, y - vertexRadius, vertexRadius * 2, vertexRadius * 2,
                juce::Justification::centred, true);

            for (int j = 0; j < numVertices; j++)
            {
                int weight = adjacencyMatrix[i][j];
                if (weight != 0)
                {
                    int destX = startX + j * padding;
                    int destY = startY;

                    // Draw edge
                    g.setColour(juce::Colours::black);
                    g.drawLine(x, y + vertexRadius, destX, destY - vertexRadius, 2);

                    // Draw edge weight
                    g.setColour(juce::Colours::red);
                    juce::String weightLabel = juce::String(weight);
                    int textX = (x + destX) / 2;
                    int textY = (y + destY) / 2;
                    g.drawText(weightLabel, textX - vertexRadius, textY - vertexRadius, vertexRadius * 2, vertexRadius * 2,
                        juce::Justification::centred, true);
                }
            }
        }
    }
};


class Creative_1Application : public juce::JUCEApplication
{
public:
    Creative_1Application() {}

    const juce::String getApplicationName() override { return ProjectInfo::projectName; }
    const juce::String getApplicationVersion() override { return ProjectInfo::versionString; }
    bool moreThanOneInstanceAllowed() override { return true; }

    void initialise(const juce::String& commandLine) override
    {
        mainWindow.reset(new MainWindow(getApplicationName()));
        mainWindow->setVisible(true);
        mainWindow->setContentNonOwned(new GraphPaint(nullptr), true);
    }

    void shutdown() override { mainWindow = nullptr; }
    void systemRequestedQuit() override { quit(); }
    void anotherInstanceStarted(const juce::String& commandLine) override {}

private:
    class MainWindow : public juce::DocumentWindow, public juce::Button::Listener
    {
    private:
        Graph_logics* graph;
        GraphPaint* graphPaint;
    public:
        MainWindow(juce::String name) : juce::DocumentWindow(name, juce::Colours::lightgrey, juce::DocumentWindow::closeButton), graph(nullptr), graphPaint(nullptr)
        {
            centreWithSize(800, 600);
            setVisible(true);

            button1 = new juce::TextButton();
            button1->setButtonText("Add Vertex");
            button1->setBounds(5, 30, 100, 30);
            button1->addListener(this);
            addAndMakeVisible(button1);

            button2 = new juce::TextButton();
            button2->setButtonText("Delete Vertex");
            button2->setBounds(5, 60, 100, 30);
            button2->addListener(this);
            addAndMakeVisible(button2);

            button3 = new juce::TextButton();
            button3->setButtonText("Add Edge");
            button3->setBounds(5, 90, 100, 30);
            button3->addListener(this);
            addAndMakeVisible(button3);

            button4 = new juce::TextButton();
            button4->setButtonText("Delete Edge");
            button4->setBounds(5, 120, 100, 30);
            button4->addListener(this);
            addAndMakeVisible(button4);

            button5 = new juce::TextButton();
            button5->setButtonText("BFS");
            button5->setBounds(5, 150, 100, 30);
            button5->addListener(this);
            addAndMakeVisible(button5);

            button6 = new juce::TextButton();
            button6->setButtonText("DFS");
            button6->setBounds(5, 180, 100, 30);
            button6->addListener(this);
            addAndMakeVisible(button6);

            button7 = new juce::TextButton();
            button7->setButtonText("TSP");
            button7->setBounds(5, 210, 100, 30);
            button7->addListener(this);
            addAndMakeVisible(button7);

            graph = new Graph_logics();
            graphPaint = new GraphPaint(graph);
        }

        void resized() override
        {
            graphPaint->setBounds(getLocalBounds());
        }

        void buttonClicked(juce::Button* button) override
        {
            if (button == button1) { graph->addVertex(); }
            else if (button == button2) { graph->removeVertex(1); }
            else if (button == button3) { graph->addEdge(1, 1, 1); }
            else if (button == button4) { graph->removeEdge(1, 1); }
            else if (button == button5) { graph->BFS(1); }
            else if (button == button6) { graph->DFS(1); }
            else if (button == button7) { /* Обработка нажатия на кнопку "TSP" */ }
            repaint();
        }

        void paint(juce::Graphics& g) override
        {
            juce::DocumentWindow::paint(g); // Вызов родительского метода paint()
            if (graphPaint != nullptr)
                graphPaint->paint(g); // Отрисовка графа
            resized(); // Обновление размеров компонента
        }

        void closeButtonPressed() override { juce::JUCEApplication::getInstance()->systemRequestedQuit(); }

    private:
        juce::TextButton* button1;
        juce::TextButton* button2;
        juce::TextButton* button3;
        juce::TextButton* button4;
        juce::TextButton* button5;
        juce::TextButton* button6;
        juce::TextButton* button7;

        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainWindow)
    };

    std::unique_ptr<MainWindow> mainWindow;
};

START_JUCE_APPLICATION(Creative_1Application)

You shouldn’t be doing that, it just recursively calls back to your paint method.

If this is fixed, the window does not open anyway. If I completely remove all rendering methods, the window appears.

Are you able to do some debugging on your code and share it with us? If you can’t see the graphic component on the UI it could be that maybe the positions of the components are “out of range”, meaning that they have been drawn but not on a visible part.
Also make suree that your rendering methods don’t interfere with numVertices. Try adding a couple breakpoints and see if they contain the correct numbers.