我最初制作程序如下。我使用了Extended Canvas和update方法来不断绘制更多点。我的理解是,每次调用repaint()时,都会通过使用update()方法将新点添加到现有的Canvas上。如果每次调用repaint()时方法是paint()而不是update(),则它将仅用五十个点绘制一个新的Canvas。这是我的BarnsleyFern类,它扩展了Canvas。
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Canvas;
import java.lang.Math;
import java.awt.event.*;
import javax.swing.*;
public class BarnsleyFern extends Canvas
{
private double newX,x=0;
private double newY,y=0;
public BarnsleyFern(int width, int height)
{
setBackground(Color.BLACK);
setSize(width,height);
setVisible(true);
ActionListener action = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
repaint();
}
};
Timer timer = new Timer(100,action);
timer.start();
}
public void update(Graphics window)
{
Graphics2D g2d = (Graphics2D)window;
window.translate(360,800);
//g2d.rotate(Math.toRadians(180));
fern(window);
}
public void fern(Graphics window)
{
Color newColor = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
for(int i=0;i<50;i++)
{
window.setColor(Color.BLUE);
int rand = (int)(Math.random()*100);
if(rand<1)
{
newX=0;
newY=0.16*y;
}
else if(rand<86)
{
newX=0.85*x + 0.04*y;
newY=0.85*y - 0.04*x + 1.6;
}
else if(rand<93)
{
newX=0.20*x - 0.26*y;
newY=0.23*x + 0.22*y + 1.6;
}
else
{
newX=0.28*y - 0.15*x;
newY=0.26*x + 0.24*y + 0.44;
}
window.fillOval((int)(newX*165.364),-(int)(newY*80.014),2,2);
x=newX;
y=newY;
}
}
}
以下代码是扩展JFrame的BarnsleyFernRunner类。这将设置JFrame并包含main方法。
import javax.swing.JFrame;
public class BarnsleyFernRunner extends JFrame
{
public BarnsleyFernRunner()
{
setTitle("Barnsley Fern");
setSize(800,800);
add(new BarnsleyFern(800,800));
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
BarnsleyFernRunner runner = new BarnsleyFernRunner();
}
}
然后我决定通过扩展JPanel而不是扩展Canvas来稍微更改代码。我选择这样做是因为JPanel和JFrame都来自javax.swing包。新的BarnsleyFern类从上面使用BarsnleyFernRunner类。该类的工作方式与以前不同。每次调用repaint()都会绘制五十个新点,而旧点会消失。我的理解是这种情况,因为每次调用repaint()都会创建一个新的JPanel。我的问题是如何在JPanel中调用repaint()方法而不创建一个全新的JPanel。有没有一种方法可以调用repaint()而不会“擦除”我已经绘制的内容。有没有一种方法可以使用update()方法复制我在第一堂课中所做的事情。这是我的BarnsleyFern类,它扩展了JPanel
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Canvas;
import java.lang.Math;
import java.awt.event.*;
import javax.swing.*;
public class BarnsleyFern extends JPanel
{
private double newX,x=0;
private double newY,y=0;
public BarnsleyFern(int width, int height)
{
setBackground(Color.BLACK);
setSize(width,height);
setVisible(true);
ActionListener action = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
repaint();
}
};
Timer timer = new Timer(100,action);
timer.start();
}
public void paintComponent(Graphics window)
{
super.paintComponent(window);
Graphics2D g2d = (Graphics2D)window;
window.translate(360,800);
//g2d.rotate(Math.toRadians(180));
fern(window);
}
public void fern(Graphics window)
{
Color newColor = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
for(int i=0;i<50;i++)
{
window.setColor(Color.BLUE);
int rand = (int)(Math.random()*100);
if(rand<1)
{
newX=0;
newY=0.16*y;
}
else if(rand<86)
{
newX=0.85*x + 0.04*y;
newY=0.85*y - 0.04*x + 1.6;
}
else if(rand<93)
{
newX=0.20*x - 0.26*y;
newY=0.23*x + 0.22*y + 1.6;
}
else
{
newX=0.28*y - 0.15*x;
newY=0.26*x + 0.24*y + 0.44;
}
window.fillOval((int)(newX*165.364),-(int)(newY*80.014),2,2);
x=newX;
y=newY;
}
}
}
答案 0 :(得分:0)
以super.paintComponent(window);
方法调用paintComponent()
时,您正在要求JPanel
绘制边框和背景。绘制背景意味着破坏以前的所有内容。
处理此问题的最简单方法是简单地忽略对super.paintComponent(window);
的调用。另一种方法是调用setOpaque(false);
。这告诉面板您有责任自己绘制背景。