Trung Bún
Trung Bún

Reputation: 1147

method paintComponent(Graphics g) doesn't work

I'm trying to display the Mandelbrot set on a JPanel, and this is my code. I really don't understand why the image drawn on BufferedImage wasn't display on my JPanel. Can anyone show me the problem in my code please ?

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));
    }

}

Upvotes: 0

Views: 1125

Answers (1)

Vishal K
Vishal K

Reputation: 13066

Within paintComponent() method the first line that you should write is:
super.paintComponent(g);
And by the way, while your first iteration in run() method after draw() method is returned , your thread hangs permanently because of wait. And you have nowhere called notify() .
And as suggested by @mKorbel , Instead of using Thread use javax.swing.Timer while dealing with Swing components. And apart from that javax.swing.SwingWorker is also an option for executing long running complex task. Watch this official tutorial to know how to use javax.swing.SwingWorker API. And here for javax.swing.Timer API.

Upvotes: 2

Related Questions