I'm trying something along these lines:
private static class TexturePanel extends JPanel {
#Override
protected void paintComponent(Graphics graphics) {
// drawing code
// calc fps
repaint();
}
}
Is calling repaint() in paintComponent() the right approach to this?
How to measure Java2D drawing performance in a JComponent?
A crude measure is to give the repaint Timer an arbitrarily short delay & count FPS.
Is calling repaint() in paintComponent() the right approach to this?
No. No it isn't. paintComponent() is fine, but don't trigger repaint() from within the method. See the Performing Custom Painting Lesson of the Java Tutorial for some tips.
If you cannot get it sorted from that, I suggest you prepare and post an SSCCE of your best effort.
Related
I am not new to Java, but somewhat inexperienced using graphics.
I am using JFreeChart to display strip charts of data that comes in very fast (every 10 ms). It works fine for a single chart, but I have multiple charts so my code cannot keep up with the server. I decided to override the paintComponent method in my JPanel and skip painting some of the frames. That did improve performance, but now there is strange behavior: I have 6 charts (each in a JPanel), and they do update as expected but 1 of the six charts flickers into the place of the other 5, then they all flicker back to themselves, then the 1 chart is in all 6, etc. This happens very fast. The chart that flickers in to all 5 is random every time I run this code, so maybe the others are also flickering in and out but I cannot see it.
#Override
public void paintComponent(Graphics g)
{
if ((count++ % UPDATESKIP) == 0)
{
super.paintComponent(g);
}
}
If UPDATESKIP = 1 then this code runs fine, but very slow.
You should not play with the painting method in that way. All the paintComponent() method of a JPanel does is paint the background of the panel. So I doubt that is where the performance problem is.
Every time the panel is repainted the child components of the panel need to be repainted, so not repainting the background will have little impact (relative to the complexity of painting 6 charts). However, if you don't paint the background every time then you can get painting artifacts on the panel.
Take a look at the Swing tutorial on A Closer Look at the Painting Mechanism
If the server data comes in too fast then maybe you need to consolidate the data before redoing the painting
I did more (better) searches and found the answer here:
Enabling/Disabling drawing of a JFreeChart.
The answer by Aleadam was perfect and did the job for me. I'd vote that answer up but I am too new to do so.
My question is that i need to make a GUI that keeps updating becuse i get values that can change from a DB and i got some problems in the graphical area.
well im using Drawline and Drawstring from Graphics2D that print values that are found on the database, this strings and lines move and change value, so i need to call repaint(); with a timer to make them apper in the jpanel, the problem is that repaint(); is not removing the old painting in the background before painting, but when i resize all updates perfecly.
i know a way to clear but the background color goes away too so,
There is a way to update the jpanel removing old paintings and keep the deafult background color?
Not updated
After changing a coordenate and a label text to "AXIS Y" (repaint called automatically from a timer)
Thanks.
From the looks of your image, it looks like you're just forgetting to call super.paintComponent in the paintComponent method. What this does is repaint the background for you, so aren't left with the previous paint artifacts.
#Override
protected voud paintComponent(Graphics g) {
super.paintComponent(g);
}
Note: For future reference, though the images gave us a good picture, it always best to post a Minimal, Complete, and Verifiable example along with those images, so we don't have to make guesses (educated or not)
I'm developing some kind of videogame, so I am not interested in calling paint, repaint or any sort of those methods on each updating from keylistening, since they call also the update(Graphics g) method which cleans the whole screen. That's why I do want to #Override the update method, not allowing it to cleaning the screen at first. Doing this I can update what I want when I want.
However, sometimes it goes in a loop auto painting the components (such as jButtons) cleaning the screen(I couldn't track anything special happening whenever this occurs, I have already tried overriding some methods in order to catch which one's the troublesome and I couldn't find it, I'm likely missing something). I do not want this happening, because this auto painting cleans the screen which makes me draw everything once again. Moreover I don't feel comfortable with something looping until the player press any key. Do you have any clue? One solution could simply be using a timer with a boolean that each time a screen is completed and the next one is being loaded it calls update(g) from my JFrame (which contains the jPanel). But I would like something better..
Maybe I am doing something wrong, even if I tried to improve my painting methods thousand times surfing throughout the net and netbeans's suggs.
This is how my painting methods looks with some flags written and the ones that are called after running:
#Override public void paint(java.awt.Graphics g){
paintComponents(g);
System.out.println("Flag");
update(g);
}
#Override
public synchronized void update(Graphics g)
{
g.setColor(java.awt.Color.GREEN);
w.getDrawer().draw(g);
g.drawRect (0, 0, w.getActive().getW(), w.getActive().getH());
}`
The overriding on paint(Graphics g) method is not needed at all, just did it in order to see what was going on. I never called repaint() but update(getGraphics()) and it just spam Flags all around. Also thought that maybe I was making it run in a loop with paint and paintComponents, but deleting paintComponents(g) line helps not at all.
Any help would be welcome, since I am trying to make this project "serious". Thanks in advance.
Sergi.
By the way, w.getDrawer().draw(g); is just calling some entities (like 100) with something like g.drawImage(image, locationX, locationY, null) inside. I don't think it has anything to do with my prob.
..this auto painting cleans the screen which makes me draw everything once again.
Draw it to a BufferedImage displayed in a JLabel. When the data (the image) updates call label.repaint().
E.G. as seen in:
This answer to How to draw an image over another image?
This answer to Dynamic Graphics Object Painting.
How can I use a image as background in a JPanel if the paint () method is already used for other purposes? (I'm tried to draw over a image in a panel).
Here is my code to draw as a pencil, but I donĀ“t know how to add the image as background ?
#Override
public void paint(Graphics g) {
if (x >= 0 && y >= 0) {
g.setColor(Color.BLACK);
g.fillRect(x, y, 4, 4);
}
}
Thanks Diego
Suggestions:
Don't draw in the JPanel's paint(...) method but rather use it's paintComponent(...) method. There are several reasons for this, one being that if you use the paint(...) method, then you are also responsible for drawing the JPanel's borders and child components and at risk of messing up the rendering of these guys. Also you lose Swing's automatic double buffering.
First call the parent class's super method before calling any other code in the method. This will allow the JPanel to refresh its background and do any graphics housekeeping that may need to be done.
Next draw your background image using g.drawImage(...),
Then do your pencil drawing.
Hovercraft Full Of Eels gave good advice on one direction to take. Here is another.
Display the image in a (ImageIcon in a) JLabel.
When it comes time to paint:
Call createGraphics() on the BufferedImage to gain a Graphics2D object.
paint the lines or other visual elements to the graphics instance.
dispose of the graphics instance.
Call repaint() on the label.
E.G. as seen in this answer.
I have the following problem in swing.
I'm implementing basic drawing operations (lines, shapes). When I'm moving mouse with pressed left button, I need to repaint current shape. So I clear the screen and repaint already drawn shapes and currently being drawn one.
Shapes are drawn in paint() method and on mouse move event I call repaint() (paint() is called automatically). The problem is that the screen is blinking strongly on each repaint and it looks really ugly. Please tell me, what I'm doing wrong? Thanks.
I think what you are looking for is double buffering.
Shapes are drawn in paint()
Custom painting should be done in the paintComponent() method and make sure you invoke super.paintComponent() as the first line.
Also custom painting is done on a JPanel (or JComponent), not on the JFrame directly.
I had flickering or blinking problem. I solved it using the following code.
public void update(Graphics g) {
paint(g);
}
#Override
public void paint(Graphics g) {
//super.repaint();
if (myimg != null) {
g.drawImage(myimg, 0, 0, this);
}
//update(g);
}
You don't need to clear the screen, you just call repaint() then it's enough. If you have to clear the screen, it'll blink if you don't use synchronization, because the painting job is done in a separate thread.