Мой метод рисования частично работает. Команды рисования внутри моих циклов не выполняются. Как я мог решить эту проблему? - PullRequest
0 голосов
/ 27 июня 2018
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class CA extends JFrame
{
    static int[] cells = new int[60];
    static int generation;

    static int[] ruleSet = {0,0,0,0,0,0,0,1};

    int width = 600;
    int w = 15;

    JFrame frame;
    JPanel panel;

    public CA() 
    {
        generation = 0;
        panel = new JPanel();
        this.setSize(1000, 1000);
        this.setVisible(true);
        panel.setLayout(null);
        this.add(panel);
        repaint();
    }

    public static void generate() 
    {
        int[] nextGen = new int[cells.length];
        for(int i = 1; i < cells.length-1; i++) 
        {
            int left = i-1;
            int me = i;
            int right = i+1;
            nextGen[i] = rules(left,me,right);
        }
        for(int i = 0; i < nextGen.length; i++) 
        {
            cells[i] = nextGen[i];
        }
        System.out.println(Arrays.toString(cells));
    }

    public static int rules(int a, int b, int c) 
    {
        if(a == 1 && b ==1 && c == 1)
            return ruleSet[0];
        else if(a == 1 && b ==1 && c == 0)
            return ruleSet[1];
        else if(a == 1 && b ==0 && c == 1)
            return ruleSet[2];
        else if(a == 1 && b ==0 && c == 0)
            return ruleSet[3];
        else if(a == 0 && b ==1 && c == 1)
            return ruleSet[4];
        else if(a == 0 && b ==1 && c == 0)
            return ruleSet[5];
        else if(a == 0 && b ==0 && c == 1)
            return ruleSet[6];
        else
            return ruleSet[7];
    }
    public static void main(String[] args) 
    {
        for(int i = 0 ; i < cells.length; i++) 
        {
            cells[i]=0;
        }
        int num = (int)cells.length / 2;
        cells[num] = 1;
        new CA();
    }

    public void paint(Graphics g) 
    {
        super.paintComponents(g);
        //g2d.drawRect(10, 10, 100, 100);
        //generation = 0;
        System.out.println("generation ......." + generation);
        while(generation < 3) 
        {
            int counter = 0;
            System.out.println("cells...." + Arrays.toString(cells));
            for( int i : cells) 
            {
                if(i == 1) 
                {
                    System.out.println("i == 1");
                    g.fillRect((counter*w) + 300, generation + 300, w, w);
                    //counter++;
                }
                else {
                    System.out.println("not filling rect");
                }
            }
            System.out.println("generation ...in while ...." + generation);
            generate();
            generation++;
        }
        g.drawString("this works", 100, 100);
    }
}

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

1 Ответ

0 голосов
/ 27 июня 2018

Весь ваш подход нарушен, и вместо этого я рекомендую вам следовать этим рекомендациям:

  • Прежде всего, рисуйте в методе paintComponent JPanel, и обязательно вызовите тот же супер-метод в переопределении вашего метода. Все это хорошо описано в уроках рисования Swing: Урок: Выполнение пользовательской рисования .
  • Цикл while не относится к методу рисования, если ваша цель состоит в том, чтобы анимировать изменения отображения ячеек, и на самом деле я бы рискнул, чтобы в вашем коде не было цикла while
  • Вместо этого используйте Swing Timer , чтобы помочь вам управлять вашей анимацией. Вы вызываете следующее поколение в ActionListener Timer, а затем вызываете repaint(), который будет сигнализировать JPanel о перерисовке.
  • В методе paintComponent используйте данные о клеточных автоматах, чтобы решить, что и где рисовать.

Также:

  • Никогда не рисуйте непосредственно в JFrame, поскольку это сложный контейнер окна верхнего уровня, и рисование непосредственно в нем может нарушить его способность отображать компоненты, которые он содержит
  • Не вызывайте super.paintComponents в рамках переопределения метода рисования. В этом случае супер вызов должен соответствовать вызову переопределения.
  • Опять же, вам не следует переопределять краску, а использовать метод JPCanel paintComponent.
  • Похоже, вы закрываете свой JFrame панелью JPanel
  • Ваш класс расширяет JFrame, что вы почти никогда не хотите делать.
...