IonOne
IonOne

Reputation: 385

no repaint while resizing when using .setPaint(gradient)

As soon a I use gradients in my code, the repaint isn't done while resizing I get something like that while resizing (black rectangles where it has been resized, see image in the link below). And when i stop resizing, everything is drawn again, but only then.

if I don't use g2d.setPaint(gradient); I have a quick redraw

http://gui-builder.com/C41142775162.rar

public void paintComponent(Graphics g)  
{  

        super.paintComponent(g);  

        Graphics2D g2d = (Graphics2D)g;  

        //sample of the code  
        GradientPaint gradient = new GradientPaint(startX, startY, greyColor1, endX, endY, new Color(120,120,120));  
        g2d.setPaint(gradient);  
        g.drawLine(i, startY, i, endY);  
}  

I tried to repaint() on resize, I tried to repaint() when mouse is dragged but nothing.


here is some SSCCE (sorry i didn't post it before):

BufferedImage aa;

@Override  
public void paintComponent(Graphics g)  
{  
        super.paintComponent(g);  

        Graphics gr = aa.getGraphics();  
        Graphics2D g2d = (Graphics2D)gr;  

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,  
                    RenderingHints.VALUE_ANTIALIAS_ON);  


        for (int i = 0; i < this.getWidth(); i++)  
        {  
            LinearGradientPaint lgp = new LinearGradientPaint(
            new Point2D.Float(0, 0),
            new Point2D.Float(0, this.getHeight()),
            new float[] {0f, 0.5f, 1f},
            new Color[] {Color.BLUE, Color.RED, Color.BLUE}
            ); 
            g2d.setPaint(lgp);  
            gr.drawLine(i, 0, i, this.getHeight());  
        }  
        g.drawImage(aa, 0, 0, frame);  
}  

and in your constructor :

aa = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);

i still need an answer why the redraw isn't done when i resize the window (while i move the resize corner of the window)


Okay so to sum up : i tried the three main methods of drawing in Java which are BufferStrategy, double Swing buffered image and simple swing with no image buffer. And i found that the faster one is the last one (surprisingly).

Now i'm using the fast one and i found that first resizing the window to a small size then resizing the window to a big size makes the problem disappear. Don't laugh that's my problem and that's a total mystery. here is a video of it : C41142775162.rar

what happens when i resize to a small size? i dunno. But if you know any help would be greatly appreciated.

thanks

Jeff


also i found out that it's best to use setPaint as little aas possible. You can run tests and you will see that it's much faster not to use too often setPaint(). for example, instead of using:

LinearGradientPaint gradient1 = new LinearGradientPaint(
        new Point2D.Float(0, 0),
        new Point2D.Float(0, 10),
        new float[] {0f, 1f},
        new Color[] {new Color(40,40,40), new Color(110,110,110)}
    );
LinearGradientPaint gradient2 = new LinearGradientPaint(
        new Point2D.Float(0, 10),
        new Point2D.Float(0, 20),
        new float[] {0f, 1f},
        new Color[] {new Color(110,110,110), new Color(190,190,190)}
    );
LinearGradientPaint gradient3 = new LinearGradientPaint(
        new Point2D.Float(0, 20),
        new Point2D.Float(0, 30),
        new float[] {0f, 1f},
        new Color[] {new Color(190,190,190), new Color(250,250,250)}
    );                        
for (int i = 0; i < this.getWidth(); i++)
{
    g2d.setPaint(gradient1);
    gr.drawLine(i, 0, i, 10);
    g2d.setPaint(gradient2);
    gr.drawLine(i, 10, i, 20);
    g2d.setPaint(gradient3);
    gr.drawLine(i, 20, i, 30);                            
}

use :

LinearGradientPaint gradient1 = new LinearGradientPaint(
        new Point2D.Float(0, 0),
        new Point2D.Float(0, 10),
        new float[] {0f, 1f},
        new Color[] {new Color(40,40,40), new Color(110,110,110)}
    );
LinearGradientPaint gradient2 = new LinearGradientPaint(
        new Point2D.Float(0, 10),
        new Point2D.Float(0, 20),
        new float[] {0f, 1f},
        new Color[] {new Color(110,110,110), new Color(190,190,190)}
    );
LinearGradientPaint gradient3 = new LinearGradientPaint(
        new Point2D.Float(0, 20),
        new Point2D.Float(0, 30),
        new float[] {0f, 1f},
        new Color[] {new Color(190,190,190), new Color(250,250,250)}
    );                         

g2d.setPaint(gradient1);
for (int i = 0; i < this.getWidth(); i++)
     gr.drawLine(i, 0, i, 10);

g2d.setPaint(gradient2);
for (int i = 0; i < this.getWidth(); i++)
    gr.drawLine(i, 10, i, 20);

g2d.setPaint(gradient3);
for (int i = 0; i < this.getWidth(); i++)
    gr.drawLine(i, 20, i, 30); 

even if you have a lot of computations, it will be almost every time faster!

Upvotes: 1

Views: 777

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347314

I put together a test and found that the GradientPaint has woeful performance. Taking an average render time from 1.2 seconds (at 400x400 pixles) out to 20+ seconds.

I changed the GradientPaint for a LinearGradientPaint and found that the render time was around 1.3 seconds instead.

LinearGradientPaint lgp = new LinearGradientPaint(
                new Point2D.Float(0, minY),
                new Point2D.Float(0, maxY),
                new float[] {0f, 0.5f, 1f},
                new Color[] {Color.BLUE, Color.RED, Color.BLUE}
                );
g2d.setPaint(lgp);
    // Render all your samples, don't reapply or change you paint...

Sorry, my sample isn't very exciting...

enter image description here

You may find it better to render to a backing buffer in a background thread instead and paint the whole image to the screen once it's complete. This will stop the screen from becoming "paused"

Upvotes: 2

huseyin tugrul buyukisik
huseyin tugrul buyukisik

Reputation: 11916

If this is an applet, put that thing in

public void start()
{
}

and

public void stop()
{
}

Upvotes: 1

Related Questions