views:

199

answers:

3

Hi

I have a panel that draws alot of things. To make drawing effecient I am using a BufferedImage so that I dont have to draw everything, everytime something happens.

My paintComponent only has to 'if' statements:

if(!extraOnly) //paint something

paint something

if(listener.getRectangle() != null) // Paint something

I like the idea of using state pattern, but I am not sure its the right moment to use it? I don't like the idea of having to set a boolean for extraOnly and maybe there has also gotten pattern fever in me :). Each state would only have one method, draw(Graphics g)

Since this is the view part of my application in a MVC pattern, I am also unsure of using state pattern is wrong. Shouldn't state be part of the model and not the view?

A: 

what about a list of drawables, each with a z level and a dirty flag? so your paint can look like:

paint()
{
    sort(drawables, by z-level)
    foreach(drawable in drawables)
       if (drawable.isDirty())
           drawable.paint()
}

you will need to consider dirtying overlapping objects, but generally this approach is pretty simple to implement.

edit: hmm, not so simple. if you move an object, you will need to repaint the surface below it. if you have a clear distinction between background elements and forground elements, you may want to draw them into different image buffers, this will allow you to quickly repaint the background without rendering it again.

Omry
+1  A: 

I see nothing wrong with having state in the view. This is clearly not the same state as in the model though.

An example would be a webbrowser. The model in this case is the web page DOM and the browser view is rendering the DOM into a screen presentation. While scrolling down the web page it would be very inefficient to do render the DOM on each frame. Clearly a buffered state is the solution to this. The state would only have to be updated if the underlying DOM is changed.

Peter Lillevold
Thx for the answer :)I am a little confused here by the mvc. So is it the controller that changes the state of view?
bobjink
Yes, if somewhat indirectly. The controllers task is to manage the functional logic while the view should manage the presentation logic. So e.g. the controller would say to the view that the model is updated with a shortest path. The view could then take action and display the shortest path.Not sure if this made things any clearer...
Peter Lillevold
It did. Thx again :)
bobjink
A: 

The general bigger question seems to be how to do efficient painting?

Partial painting is a good way of improving performance if drawing is slow.

However, first prove that drawing is slow! If profiling indicates that drawing is an issue, then you can migrate to partial updates.

One approach is to use 'dirty rectangle tracking'. This is a very widely used thing, and the terms are 'invalidation' (the area that needs redrawing) and 'validation' (the act of drawing the dirty bit). The windowing system is almost certainly doing this already, so it may be that you can piggyback this e.g. the Java Swing RepaintManager keeps a bounding rectangle of the dirty region.

However, you can easily roll your own. You can have a member variable - a "region", or simply a list of rectangles in a vector, or a bounding rectangle - to represent the area to be updated on the next paint. In your constructor or size-changed handlers, initialize this to the whole area. Any time you want to redraw part of the panel, invalidate that part by adding the rectangle to the dirty region. When painting, only draw parts in the dirty region, and then clear the dirty region. Partial drawing in this way works well with buffered images as an intermediary, for example. Easy!

Will