Reputation: 385
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
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...
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
Reputation: 11916
If this is an applet, put that thing in
public void start()
{
}
and
public void stop()
{
}
Upvotes: 1