JButton и ActionListener вызывают много ошибок во время выполнения - PullRequest
0 голосов
/ 12 декабря 2018

Итак, я пытаюсь сделать версию Game of Life Конвея, используя Eclipse и JSwing, моя проблема заключается в том, что когда я пытаюсь запустить код для запуска поколения, вместо этого возникает большое количество ошибок времени выполнения. Проблема возникает, когда я пытаюсьнажать первую кнопку JButton, которую я сейчас использую в качестве кнопки запуска для следующего поколения симуляции.Класс Cell - это просто набор сеттеров и геттеров как для текущего состояния, так и для его места в массиве кнопок. Список ошибок, возникающих при нажатии первой кнопки, находится под кодом

public class MainPage extends JFrame implements ActionListener{

JButton[] screen = new JButton[2500]; 
JButton start = new JButton("Start");
Cell[] cells = new Cell[2500];
int select = 0;

public static void main(String args[]) {

    new MainPage();

}

public MainPage() {
    super("The Game Of Life");
    int k = 0;
    while (k < 2500) {
        screen[k] = new JButton("");
        screen[k].setBackground(Color.BLACK);
        cells[k] = new Cell(k);
        cells[k].setState(0);
        k++;
    }

    Container surface = this.getContentPane();
    surface.setLayout(new GridLayout(50,50));

    // k == row j == col
    for (int i = 0; i < 2500; i++) {

           int finalI = i; // no final modifier
            surface.add(screen[i]);

            screen[i].addActionListener(e -> {


                Color color = screen[finalI].getBackground();
                if (color == Color.BLACK)
                {
                    screen[finalI].setBackground(Color.WHITE);
                    cells[finalI].setState(1);
                }
                else {
                    screen[finalI].setBackground(Color.BLACK);
                    cells[finalI].setState(0);
                }

            });
            screen[0].addActionListener(this);

    }

    this.pack();
    this.setVisible(true);


}
public void setnewstates() {
    int k = 51;
    int screensize = 50;

    while (k < 2500 || k > 50 || k % 50 != 0 || (k + 1) % 50 != 0) // avoid borders for now
    {
        int neighbors = 0;
        int state = cells[k].getState();
        neighbors = cells[k - 1].getState() + neighbors; // check neighbors
        neighbors = cells[k + 1].getState() + neighbors;
        neighbors = cells[k + screensize].getState() + neighbors;
        neighbors = cells[k - screensize].getState() + neighbors;
        neighbors = cells[k + screensize + 1].getState() + neighbors;
        neighbors = cells[k + screensize - 1].getState() + neighbors;
        neighbors = cells[k - screensize - 1].getState() + neighbors;
        neighbors = cells[k - screensize + 1].getState() + neighbors;   

        if (state == 1) {
            if (neighbors < 2)
            {
                cells[k].setState(0);
                screen[k].setBackground(Color.BLACK);
            }
            if (neighbors > 3)
            {
                cells[k].setState(0);
                screen[k].setBackground(Color.BLACK);
            }
        }
        else if (state == 0) {
            if (neighbors == 3)
            {
                cells[k].setState(1);
                screen[k].setBackground(Color.WHITE);
            }
        }
    k++;
    }
}

public void actionPerformed(ActionEvent e) {
    if (e.getSource() == screen[0])
    {
        setnewstates();
    }
}
}

А вот и ошибки, которые возникают при нажатии первой кнопки

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at MainPage.setnewstates(MainPage.java:72)
at MainPage.actionPerformed(MainPage.java:106)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

1 Ответ

0 голосов
/ 12 декабря 2018

В setnewstates() вы начинаете с установки k = 0, затем одним из первых действий, которые вы делаете в цикле while, является ссылка cells[k - screensize - 1]

, например:

int neighbors = 0;
int state = cells[k].getState();

if (k > 0) neighbors = cells[k - 1].getState() + neighbors; // check neighbors
if (k < 2500) neighbors = cells[k + 1].getState() + neighbors;
if (k + screensize < 2500) neighbors = cells[k + screensize].getState() + neighbors;

Просто мысль: вы делаете свою жизнь действительно сложной, используя одномерный массив.Жизнь играется на двумерной сетке (у вас есть 50x50), поэтому я рекомендую вам поэкспериментировать с двумерным массивом [50] [50].

...