Добавление в список массивов с прослушивателем событий [Java]

У меня есть игровой цикл с треугольником, который случайным образом перемещается по экрану. Я хочу добавить кнопку, которая при нажатии добавит еще один случайно движущийся треугольник. Я использую прослушиватели событий, и независимо от того, где я их размещаю, я все равно получаю исключение

Вот мой код

import javax.swing.*;
import drawing.Canvas;
import tools.Utils;
import triangle.DynamicTriangle;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

public class TriangleProgram {
    private JFrame frame; 
    private Canvas canvas; 
    private JPanel lowerPanel; 
    private JButton addTriangleButton; 
    private ArrayList<DynamicTriangle> triangles;

    public void gameLoop() {
        int deltaTime = 20;

        triangles.add(new RandomTriangleA(canvas, 150, 150));

        for (DynamicTriangle dynamicTriangle : triangles) {
            dynamicTriangle.drawTriangle();
        }
        while (true)
        {
            for (DynamicTriangle dynamicTriangle : triangles) {
                dynamicTriangle.undrawTriangle();
            }

            for (DynamicTriangle dynamicTriangle : triangles) {
                dynamicTriangle.update(100);
                dynamicTriangle.wrapPosition();
            }

            for (DynamicTriangle dynamicTriangle : triangles) {
                dynamicTriangle.drawTriangle();
            }

            Utils.pause(deltaTime);
            canvas.repaint();
        }

    }

    public TriangleProgram() {
        frame = new JFrame();
        frame.setTitle("Canvas");
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        canvas = new Canvas();
        frame.add(canvas, BorderLayout.CENTER);

        lowerPanel = new JPanel();
        lowerPanel.setLayout(new FlowLayout());
        frame.add(lowerPanel, BorderLayout.SOUTH);

        triangles = new ArrayList<DynamicTriangle>();

        addTriangleButton = new JButton("Add Triangle"); 
        lowerPanel.add(addTriangleButton);
        frame.revalidate();

        addTriangleButton.addActionListener(new ButtonListener());

        gameLoop();

    }

    public static void main(String[] args) {
        System.out.println("Running TriangleProgram...");
        new TriangleProgram();
    }

    class ButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent ae) {
            System.out.println(triangles.size());
            triangles.add(new RandomTriangleA(canvas, 150, 150));
        }

    }

}

Я ожидаю, что каждый раз, когда я нажимаю кнопку, на холст добавляется новый треугольник, но вместо этого я получаю трассировку стека:

Running TriangleProgram...
1
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index -1 out-of-bounds for length 0
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
    at java.base/java.util.Objects.checkIndex(Objects.java:372)
    at java.base/java.util.ArrayList.remove(ArrayList.java:517)
    at java.base/java.util.Collections$SynchronizedList.remove(Collections.java:2424)
    at drawing.Canvas.removeMostRecentLine(Canvas.java:162)
    at triangle.Triangle.undrawTriangle(Triangle.java:131)
    at TriangleProgram.gameLoop(TriangleProgram.java:29)
    at TriangleProgram.<init>(TriangleProgram.java:69)
    at TriangleProgram.main(TriangleProgram.java:75)

Когда вы спрашиваете об исключении, всегда публикует полную трассировку стека исключений. Рассказывает, в чем и где проблема.

JB Nizet 27.03.2019 19:37

Привет, вы, кажется, ссылаетесь на треугольник в верхней части вашего метода «gameLoop», но переменная никогда не объявляется.

James McNee 27.03.2019 19:39

@JamesMacca Он инициализируется в конструкторе.

Bakon Jarser 27.03.2019 19:42

@JamesMacca конструктор проверки

JustAFellowCoder 27.03.2019 19:43

@BakonJarser «треугольники» инициализируются в конструкторе. "треугольник" - нет.

James McNee 27.03.2019 19:54
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
337
1

Ответы 1

        triangle.add(new Triangle(canvas, 150, 150));

Ну, здесь вы даже не объявляете triangle, поэтому не знаете, как этот код вообще работает, чтобы дать вам исключение. Я предполагаю, что вы имели в виду triangles Также вы, вероятно, можете (?) уплотнить свои петли.

Обновлено: также, когда вы объявляете треугольники списка, почему это список DynamicTriangle, но когда вы инициализируете и добавляете в список, это Triangle.

Не уверен, является ли DynamicTriangle подклассом Triangle или просто опечаткой, но в этом случае он не должен компилироваться.

Если это опечатка, используйте вместо ArrayList<DynamicTriangle> trianglesTriangle.

Если DyanmicTriangle является подклассом Triangle, тогда вы хотите объявить и инициализировать треугольники как ArrayList<Triangle>(), и когда вы добавляете, вы делаете .add(new DynamicTriangle(...

@JustAFellowCoder Я не имею в виду, что у них есть проблемы с ними, но он, вероятно, может просто использовать один для каждого цикла в цикле while вместо трех. зависит от того, чего он пытается достичь и что на самом деле делают те методы, которые он вызывает.

chris 27.03.2019 19:47

это была моя ошибка, я переименовывал свой код более разумно, прежде чем публиковать и сделал несколько ошибок. Я обновил код в основном посте вместе с полной трассировкой стека.

ExitEnter 28.03.2019 15:15

@ExitEnter проблема не в том классе, который вы опубликовали. можете ли вы опубликовать undrawTriangle и removeMostRecentLine

chris 28.03.2019 18:49

Другие вопросы по теме