Java 有人能就如何正确创建动画提供一些帮助/建议吗?

Java 有人能就如何正确创建动画提供一些帮助/建议吗?,java,swing,animation,jpanel,jcomponent,Java,Swing,Animation,Jpanel,Jcomponent,所以我正在用java创建生活游戏,但是我在动画部分遇到了问题。我在一个JComponent上绘制了单元格,它应该显示出来,但是我有一个开始按钮,它应该开始整个动画过程,但是当我单击开始按钮时什么也没有发生 从我看过的教程和我做过的研究中,我知道你必须有一个监听按钮的ActionListener,以及一个保存代码以启动动画的actionPerformed()方法。话虽如此,我的代码如下: import javax.swing.JFrame; import java.util.Random; imp

所以我正在用java创建生活游戏,但是我在动画部分遇到了问题。我在一个JComponent上绘制了单元格,它应该显示出来,但是我有一个开始按钮,它应该开始整个动画过程,但是当我单击开始按钮时什么也没有发生

从我看过的教程和我做过的研究中,我知道你必须有一个监听按钮的
ActionListener
,以及一个保存代码以启动动画的
actionPerformed()
方法。话虽如此,我的代码如下:

import javax.swing.JFrame;
import java.util.Random;
import java.util.Arrays;
import javax.swing.JComponent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.*;
import javax.swing.*;
import java.awt.BorderLayout;

public class GameOfLife extends JFrame {

  int PIXELSIZE = 10;
  int ROW = 75;
  int COLUMN = 75;
  Random random = new Random();
  JButton start;

  public GameOfLife() {
    JPanel panel = new JPanel();
    DrawCells cellsComp = new DrawCells();
    DrawCells buttonListener = new DrawCells();
    start = new JButton("Start");
    start.addActionListener(cellsComp);
    panel.setLayout(new BorderLayout());
    start.setToolTipText("Click to start game of life");
    this.setTitle("Game Of Life: Java");
    this.setSize(PIXELSIZE * ROW, PIXELSIZE * COLUMN);
    this.setLocationRelativeTo(null);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    panel.add(start, BorderLayout.SOUTH);
    panel.add(cellsComp, BorderLayout.CENTER);
    this.add(panel);
    this.setVisible(true);
  }

  private class DrawCells extends JComponent implements ActionListener {
    int x;
    int y;
    int grid[][] = new int[ROW][COLUMN];
    int updatedGrid[][] = new int[ROW][COLUMN];

    public void createGrid() {
      for (int i = 0; i < grid.length; i++) {
        for (int j = 0; j < grid[i].length; j++) {
          grid[i][j] = random.nextInt(2);
        }
      }
    }

    public void applyRules() {
      for (int i = 1; i < ROW - 1; i++) {
        for (int j = 1; j < COLUMN - 1; j++) {
          int neighboursCount = 0; // used to count the neighbours of each cell

          neighboursCount += grid[i-1][j-1]; // top left
          neighboursCount += grid[i][j-1]; // top center
          neighboursCount += grid[i+1][j-1]; // top right

          neighboursCount += grid[i-1][j]; // middle left
          neighboursCount += grid[i+1][j]; // middle right

          neighboursCount += grid[i-1][j+1]; // top left
          neighboursCount += grid[i][j+1]; // top center
          neighboursCount += grid[i+1][j+1]; // top right

          // Game of Life rules:

          // Alive cells:
          if (grid[i][j] == 1) {
            // rule 1 any live cell with fewer than two live neighboours dies, as if by underpopulation
            if (neighboursCount < 2) {
              updatedGrid[i][j] = 0;
            }
            // rule 2 any live cell with two or three live neighbours, lives on to the generation
            else if (neighboursCount == 2 || neighboursCount == 3) {
              updatedGrid[i][j] = 1;
            }
            // rule 3 any live cell with more than three live neighbours dies, as if by overpopulation
            else if (neighboursCount > 3 && neighboursCount <= 8) {
              updatedGrid[i][j] = 0;
            }
            else {
              updatedGrid[i][j] = 0;
            }
          }
          // Dead cells
          else if (grid[i][j] == 0) {
            // rule 4 any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction
            if (neighboursCount == 3) {
              updatedGrid[i][j] = 1;
            }
            else {
              updatedGrid[i][j] = 0;
            }
          }
        }
      }
      for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COLUMN; j++) {
          grid[i][j] = updatedGrid[i][j];
        }
      }
    }

    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      createGrid();
      Graphics2D g2 = (Graphics2D) g;
      for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COLUMN; j++) {
          if (grid[i][j] == 1) {
            g2.setColor(Color.RED);
            g2.fillRect(i * PIXELSIZE, j * PIXELSIZE, PIXELSIZE, PIXELSIZE);
          }
        }
      }
    }

    public void actionPerformed(ActionEvent e) {
      if (e.getSource() == start) {
        applyRules();
        repaint();
        thread.sleep();
      }
    }
  }

  public static void main(String[] args) {
    GameOfLife gol = new GameOfLife();
  }
}
import javax.swing.JFrame;
导入java.util.Random;
导入java.util.array;
导入javax.swing.JComponent;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Rectangle;
导入java.awt.Color;
导入java.awt.event.ActionListener;
导入java.awt.event.ActionEvent;
导入java.awt.event.*;
导入javax.swing.*;
导入java.awt.BorderLayout;
公共类GameOfLife扩展了JFrame{
int PIXELSIZE=10;
int ROW=75;
int列=75;
随机=新随机();
按钮启动;
公共生活游戏(){
JPanel面板=新的JPanel();
DrawCells cellsComp=新的DrawCells();
DrawCells buttonListener=新的DrawCells();
开始=新的JButton(“开始”);
start.addActionListener(cellscop);
panel.setLayout(新的BorderLayout());
setToolTipText(“点击开始生命游戏”);
setTitle(“生活游戏:Java”);
此.setSize(像素大小*行,像素大小*列);
此.setLocationRelativeTo(空);
此.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
面板。添加(开始,边界布局。南);
panel.add(cellscop,BorderLayout.CENTER);
本条添加(面板);
此.setVisible(true);
}
私有类DrawCells扩展JComponent实现ActionListener{
int x;
int-y;
整数网格[][]=新整数[行][列];
int updateGrid[][]=新的int[行][列];
public void createGrid(){
对于(int i=0;i否则,如果(neighboursCount>3&&neighboursCount我将假装您的gui工作。在您执行的操作中,您需要启动动画。在swing中执行动画的常见方法是使用


我使用了匿名类
taskPerformer
,因为它来自于提供的javadoc链接中的示例。

我将假设您的gui工作正常。在执行的操作中,您需要启动动画。在swing中制作动画的常见方法是使用


我使用了匿名类
taskPerformer
,因为这来自于提供的javadoc链接中的示例。

为什么要创建两个绘图单元?我认为可以删除
buttonListener
paintComponent
经常被调用,并且是随机调用的。我怀疑您是否想在其中使用
createGrid
。在您的“actionPer”中formed'方法,这是EDT上的内容。运行该程序时,该程序的当前状态是什么?@matt hi感谢您的帮助,我本想删除
按钮Listener
,所以谢谢您,我忘了。关于运行该程序时的状态,它编译和运行时没有错误,但我会添加您为什么创建两个绘图单元?我想您可以Love
buttonListener
paintComponent
经常被随机调用。我怀疑您是否想在其中使用
createGrid
。在您的“actionPerformed”方法中,这是EDT上的内容。运行该程序时,该程序的当前状态是什么?@matt hi感谢您的帮助,我的意思是删除该
buttonListener
谢谢,我忘了。关于运行它时的状态,它在编译和运行时没有错误,但我会添加您的
Timer animation;
public void actionPerformed(ActionEvent e) {
  if (e.getSource() == start && animation == null) {
      createGrid();  //remove this from paint component.
      int delay = 1000; //milliseconds
      ActionListener taskPerformer = new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
              applyRules();
              repaint();
          }
      };
      animation = new Timer(delay, taskPerformer);
      animation.start();
  }
}