我正在尝试在 JPanel 上显示 Mandelbrot 集,这是我的代码。我真的不明白为什么在 BufferedImage 上绘制的图像没有显示在我的 JPanel 上。任何人都可以告诉我我的代码中的问题吗?
public class MainPanel1 extends JPanel implements Runnable, MouseListener, MouseMotionListener{
BufferedImage image;// = new BufferedImage();
BufferedImage imageToSave; // off screen image for saving image
int number_of_iteration;
int width, height; // current width and height of the drawing panel
int widthToSave, heightToSave; // off screen width and height for saving image
double real_portion_max, real_portion_min, imagin_portion_max, imagin_portion_min;
boolean dragging;
double zoom = 1, viewX = 0.0, viewY = 0.0;
private int mouseX, mouseY; // mouse position when the button was pressed
private int dragX, dragY; // current mouse position during dragging
Graphics graphics;
Graphics graphicsToSave; // off screen graphics for saving image
Thread thread;
public MainPanel1(){
this.setPreferredSize(new Dimension(500, 400));
this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
this.imagin_portion_max = 1.6;
this.imagin_portion_min = -1.6;
this.real_portion_max = 2;
this.real_portion_min = -2;
this.number_of_iteration = 100;
this.setDoubleBuffered(true);
this.thread = null;
addMouseListener(this);
addMouseMotionListener(this);
}
@Override
public void run() {
while (thread != null) {
while (draw());
synchronized (this){
try {
wait();
}catch (InterruptedException exp){
}
}
}
}
public void start(){
redraw();
}
private void redraw() {
if (thread != null && thread.isAlive()) {
thread.interrupt();
} else {
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
}
public boolean draw(){
Dimension size = this.getPreferredSize();
if(image == null || width != size.width || height != size.height){
width = size.width;
height = size.height;
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
graphics = image.getGraphics();
}
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
double r = zoom / Math.min(width, height);
double dx = (real_portion_max - real_portion_min) * ( x * r + viewX) + real_portion_min;
double dy = (imagin_portion_max - imagin_portion_min) * (y * r + viewY) + imagin_portion_min;
Color color = color(dx, dy);
graphics.setColor(color);
graphics.fillRect(x, y, 1, 1);
}
}
repaint();
return false;
}
public Color color(double x, double y){
double color_index;
color_index = computeMaldenbrot(new Complex(0.0, 0.0), new Complex(x, y));
float h = (float) (color_index/number_of_iteration);
float b = 1.0f -h*h;
return Color.getHSBColor((float) (0.1+h), 0.95f, b);
}
public double computeMaldenbrot(Complex number, Complex point){
int iteration = 0;
while (iteration < number_of_iteration && number.modulusSquared() < 4){
number = number.square().add(point);
iteration++;
}
return iteration;
}
@Override
public void paintComponent(Graphics g){
//super.paint(g);
g.drawImage(image, 0, 0, this);
if (dragging) {//Draw dragging rectangular
g.setColor(Color.green);
g.setXORMode(Color.white);
int x = Math.min(mouseX, dragX);
int y = Math.min(mouseY, dragY);
double w = mouseX + dragX - 2 * x;
double h = mouseY + dragY - 2 * y;
double r = Math.max(w / width, h / height);//make sure this rectangular self-similar to screen
g.drawRect(x, y, (int) (width * r), (int) (height * r));
}
}