• Post Reply Bookmark Topic Watch Topic
  • New Topic

How to update a JPanel rather than refresh it every time you call repaint()?  RSS feed

 
Zukias Trunchbull
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would like to be able to draw things onto the panel (via paintComponent), but I'd like it to draw 'on top' of what's already there. The default seems to be that it resets every time I call repaint.

Any advice would be great
 
Paul Clapham
Sheriff
Posts: 22520
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Normally the thing to do is for the object which is responsible for the contents of the JPanel to keep track of what's supposed to be there. Then when you call repaint(), its paintComponent() method will be called and your code will display all of the required contents.

So to paint over what is "already there", your object would first paint something and keep track of what it painted. Then when you want to paint something else over that, your object paints the original something again and then paints the additional something else. The key thing to remember is that you always have to paint everything you want to see in the JPanel.
 
Zukias Trunchbull
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:Normally the thing to do is for the object which is responsible for the contents of the JPanel to keep track of what's supposed to be there. Then when you call repaint(), its paintComponent() method will be called and your code will display all of the required contents.

So to paint over what is "already there", your object would first paint something and keep track of what it painted. Then when you want to paint something else over that, your object paints the original something again and then paints the additional something else. The key thing to remember is that you always have to paint everything you want to see in the JPanel.

How would I keep track of what it has painted? I am demonstrating graph theory algorithms, and currently it re draws every vertex and every edge every time i want to draw it, even when all i want to do is colour in an edge to show when the algorithm is traversing an edge. I've tried using a buffered image but I get exactly the same problem, I thought buffered images store their pixels :(
 
Tony Docherty
Bartender
Posts: 3268
82
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you show your paintComponent() method so we can see what you are doing.

I'll move this thread to the swing forum where you may get more help.
[Edit - someone beat me to it]
 
Paul Clapham
Sheriff
Posts: 22520
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Zukias Trunchbull wrote:How would I keep track of what it has painted?


In some kind of data structure. Maybe a list of lines, or points, or areas, or whatever it is you're painting. For a graph, maybe a list of vertices and edges. You're going to have to stop coding for a while and start designing. You need some kind of data structure which will represent the contents of your drawing. Once you have done that you can start writing code which draws that data structure.
 
Zukias Trunchbull
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tony Docherty wrote:Can you show your paintComponent() method so we can see what you are doing.

I'll move this thread to the swing forum where you may get more help.
[Edit - someone beat me to it]


I'll see what I can do, it's quite hard to read at the moment, the graphics parameter in paintComponent gets passed around a bit, but it all boils down to vertices, edges and graph classes implementing a 'Drawable' interface which is just a single operation 'draw(Graphics g)', i.e. vertices and edges draw themselves.

Paul Clapham wrote:
Zukias Trunchbull wrote:How would I keep track of what it has painted?


In some kind of data structure. Maybe a list of lines, or points, or areas, or whatever it is you're painting. For a graph, maybe a list of vertices and edges. You're going to have to stop coding for a while and start designing. You need some kind of data structure which will represent the contents of your drawing. Once you have done that you can start writing code which draws that data structure.


One of the algorithms I am demonstrating is pretty complex to demonstrate (the Auslander parter algorithm), and it relies on me being able to draw single vertices & edges, as i will need to draw vertices and edges which are part of a graph, but without the rest of the vertices and edges of the graph being drawn. At the moment I have a helper class, GraphTools which has static methods "drawVertex, drawEdge and drawGraph", if I were able to call these methods from anywhere else in the program and pass the corresponding graph components to them, it would make life a lot easier.

I was hoping there would be a way to somehow capture the contents of a panel and be able to redraw that, and then draw the new bits on top of that, then re-save, etc.
 
Paul Clapham
Sheriff
Posts: 22520
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Zukias Trunchbull wrote:One of the algorithms I am demonstrating is pretty complex to demonstrate (the Auslander parter algorithm), and it relies on me being able to draw single vertices & edges, as i will need to draw vertices and edges which are part of a graph, but without the rest of the vertices and edges of the graph being drawn.

I don't see any problem. Your data structure would have to have attributes which defined whether a vertex or an edge had to be drawn or not. In fact no matter what you say has to be drawn, it shouldn't be impossible to describe that in terms of some data structure.
At the moment I have a helper class, GraphTools which has static methods "drawVertex, drawEdge and drawGraph", if I were able to call these methods from anywhere else in the program and pass the corresponding graph components to them, it would make life a lot easier.

You say that as if you weren't able to call static methods of a class from anywhere in your code. What's stopping you from doing that?
 
Zukias Trunchbull
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:
Zukias Trunchbull wrote:One of the algorithms I am demonstrating is pretty complex to demonstrate (the Auslander parter algorithm), and it relies on me being able to draw single vertices & edges, as i will need to draw vertices and edges which are part of a graph, but without the rest of the vertices and edges of the graph being drawn.

I don't see any problem. Your data structure would have to have attributes which defined whether a vertex or an edge had to be drawn or not. In fact no matter what you say has to be drawn, it shouldn't be impossible to describe that in terms of some data structure.
At the moment I have a helper class, GraphTools which has static methods "drawVertex, drawEdge and drawGraph", if I were able to call these methods from anywhere else in the program and pass the corresponding graph components to them, it would make life a lot easier.

You say that as if you weren't able to call static methods of a class from anywhere in your code. What's stopping you from doing that?


Sorry I meant it would be nice to call them from anywhere in code and work. I think to 'save' what I am doing I will just give the jpanel 2 arrays corresponding to vertices and edges I want on the screen - but I cant help thinking that this would be inefficient for large graphs, but I can't be bothered with navigating my way around the java graphics library for much longer so I will stick with it :p
 
Paul Clapham
Sheriff
Posts: 22520
43
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Zukias Trunchbull wrote:but I cant help thinking that this would be inefficient for large graphs


I suspected this might be part of your hesitation to use normal processes. What you're doing there is called premature optimization and it's a bad thing to do. If you actually find that drawing a million or so graph edges is slowing your program down noticeably, then you should certainly consider optimizing the process. But worrying that drawing a couple of hundred graph edges will do that is just going to get into the way of designing your application properly.
 
Rob Camick
Ranch Hand
Posts: 2801
15
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Check out Custom Painting Approaches for the two common ways to do this:

1. Keep a List of objects you want to paint and then iterate through the List in your paintComponent() method
2. Draw the objects to a BufferedImage and then paint the image.
 
Zukias Trunchbull
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the replies, I will just go back to basics for now and iterate through a list. Will learn more about buffered images when I have time.
 
Paul Clapham
Sheriff
Posts: 22520
43
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sounds good -- it's always a good idea to do the simplest thing that could possibly work to start with.
 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!