0

我正在尝试在 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));
    }

}
4

1 回答 1

2

paintComponent()方法中,您应该编写的第一行是:顺便说一下,当您在方法
super.paintComponent(g);
中的第一次迭代方法被返回时,您的线程会因为. 而且你无处可打电话。 正如@mKorbel 所建议的那样,在处理 Swing 组件时不要使用use javax.swing.Timer 。除此之外,javax.swing.SwingWorker也是执行长时间运行的复杂任务的一个选项。观看此官方教程以了解如何使用API。这里是API run()draw()waitnotify()
Threadjavax.swing.SwingWorkerjavax.swing.Timer

于 2013-03-04T17:06:03.717 回答