我的绘画方法部分有效。我的循环中的绘图命令不执行。我该如何解决这个问题?
My paint method partially works. The draw commands inside my loops don't execute. How could I solve this issue?
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 元胞自动机的元胞自动机。我的绘画方法主要是从其他具有有效绘画方法的项目中复制的,所以我真的不知道该方法本身在做什么。
您的整个方法都被破坏了,我建议您遵循以下准则:
- 首先也是最重要的是在 JPanel 的 paintComponent 方法中绘制,并确保在您的方法覆盖中调用相同的超级方法。这些在 Swing 绘图教程中都有很好的描述:Lesson: Performing Custom Painting.
- 如果您的目标是为单元格显示的变化设置动画,则 while 循环不属于绘画方法,事实上我敢打赌您的代码不应该有 while 循环
- 而是使用 Swing Timer 来帮助您驱动动画。您将在 Timer 的 ActionListener 中调用下一代,然后调用
repaint()
这将向 JPanel 发出重新绘制自身的信号。
- 在 paintComponent 方法中,使用元胞自动机数据的状态来帮助决定要绘制的内容和位置。
另外:
- 切勿直接在 JFrame 中绘制,因为这是一个复杂的顶级 window 容器,直接在其中绘制会破坏其显示其包含的组件的能力
- 不要在绘画方法重写中调用
super.paintComponents
。在这种情况下,超级调用应该与覆盖调用相匹配。
- 同样,您甚至不应该覆盖 paint,而应该覆盖 JPanel 的 paintComponent 方法。
- 您似乎用面板 JPanel 掩盖了 JFrame
- 您的 class 扩展了 JFrame,这是您几乎不想做的事情。
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 元胞自动机的元胞自动机。我的绘画方法主要是从其他具有有效绘画方法的项目中复制的,所以我真的不知道该方法本身在做什么。
您的整个方法都被破坏了,我建议您遵循以下准则:
- 首先也是最重要的是在 JPanel 的 paintComponent 方法中绘制,并确保在您的方法覆盖中调用相同的超级方法。这些在 Swing 绘图教程中都有很好的描述:Lesson: Performing Custom Painting.
- 如果您的目标是为单元格显示的变化设置动画,则 while 循环不属于绘画方法,事实上我敢打赌您的代码不应该有 while 循环
- 而是使用 Swing Timer 来帮助您驱动动画。您将在 Timer 的 ActionListener 中调用下一代,然后调用
repaint()
这将向 JPanel 发出重新绘制自身的信号。 - 在 paintComponent 方法中,使用元胞自动机数据的状态来帮助决定要绘制的内容和位置。
另外:
- 切勿直接在 JFrame 中绘制,因为这是一个复杂的顶级 window 容器,直接在其中绘制会破坏其显示其包含的组件的能力
- 不要在绘画方法重写中调用
super.paintComponents
。在这种情况下,超级调用应该与覆盖调用相匹配。 - 同样,您甚至不应该覆盖 paint,而应该覆盖 JPanel 的 paintComponent 方法。
- 您似乎用面板 JPanel 掩盖了 JFrame
- 您的 class 扩展了 JFrame,这是您几乎不想做的事情。