Maintaining a partially changed window

All,

I have a GUI that does some custom painting and I would like it to maintain its changes as a user interacts with it or after the screen has been hidden.

Quick background:

I use a LinkedList data structure passed to my paintComponent() method that has at least two levels of detail information increasing in specificity as you go deeper in the data structure. When the GUI loads, it paints a series of Graphics2D objects (shapes, etc) that represents the first tier information in the data structure. Graphics are drawn in a JPanel which is within a JFrame. The user then has the option of clicking and displaying graphics representing the more detailed data.

So far I have been able to implement a solution that displays the detailed data in a new JPanel and which is lost when the screen is hidden by another window or when a new mouse event occurs (new call to draw details).

I would like to draw all detailed data within the first JPanel. This JPanel therefore needs to update itself while maintaining whatever it already had on the screen.

My objective:

On initial loading, the GUI application paints first tier data. The user selects an area to display more detailed data (area 1). Next the user selects a new area to display details (area 2). The GUI now displays graphics for area2 AND area1. This means that the GUI, upon repainting the JPanel remembered that it needed to paint area1 details.

Can someone at least point me in the right direction (reading materials, etc...) on finding an answer to the problem?

Thanks in advance!

[1604 byte] By [dmb71a] at [2007-10-3 3:53:03]
# 1

You should do your drawing in response *only* to the paint cycle, *not* to other events. So, you need to keep your shapes in some sort of collection.

eg

public class ShapePanel extends JPanel

{

private final List shapes = new ArrayList();

public void addShape(Shape s)

{

this.shapes.add(s);

}

public void removeShape(Shape s)

{

this.shapes.remove(s);

}

protected void paintComponent(Graphics g)

{

super.paintComponent(g);

Graphics2D g2d = (Graphics2D) g;

Iterator i = this.shapes.listIterator();

while (i.hasNext())

{

g2d.draw(s);

}

}

}

Obviously that's just a simple example - you may want methods to move the shapes, you may want a separate class which encapsulates shapes with colors/fills/strokes/etc, you may even want to do it a little more nicely and have a model object which manages the shape collection separately from the component which renders it.

But - short answer - keep a collection and iterate it in paintComponent().

itchyscratchya at 2007-7-14 21:50:48 > top of Java-index,Desktop,Core GUI APIs...
# 2

What's the difference between keeping a data structure of shape objects versus a data structure of shape coordinates like I already have?

Does this address the question of how to draw certain shape objects following certain user mouse events. And maintaining those new shape objects after the user selects for even more new shape objects to be drawn.

At GUI start, a finite and limited number (say 3) of shape objects will be drawn. After all possible mouse events that a user could make, many more (but finite, say 12) shape objects could be displayed in addition to the initial set. Are you saying I should create a collection of ALL possible shapes (3 + 12 = 15) that I would need to draw in the event a user calls for them being displayed?

Thanks for the response.

dmb71a at 2007-7-14 21:50:48 > top of Java-index,Desktop,Core GUI APIs...
# 3

What's the difference between keeping a data structure of shape objects versus a data structure of shape coordinates like I already have?

Nothing in principle. But I can't see your code, remember. The symptoms you describe are typical of drawing to a Graphics object outside of the paint cycle.

If you have the data, and you use it in paintComponent(), you should have what you want.

Does this address the question of how to draw certain shape objects following certain user mouse events.

On the mouse events, you'd add the shape and then repaint the panel. (Or if you're doing it properly with a model class, you'd add the shape to the model and it would fire an event to which the panel listens, causing a repaint). How you handle the dragging is up to you.

Are you saying I should create a collection of ALL possible shapes (3 + 12 = 15) that I would need to draw in the event a user calls for them being displayed?

Collections are, generally speaking, dynamic. You can add and remove from them as you go. In the above example the collection is initially empty. You can, however, add as many shapes as you like.

itchyscratchya at 2007-7-14 21:50:48 > top of Java-index,Desktop,Core GUI APIs...
# 4

I think I'm getting it now. The collection of details shapes is initially empty. As a user supplies mouse events which fire the creation of the more detailed shapes (not initially displayed at gui start), the application accesses the information in the data structure to build the appropriate new shape(s) and loads the new shape(s) objects into a collection. The application then needs to repaint the panel with the start-up shapes AND new ones just added to the collection. As more mouse evnts create new shapes, these are added to the collection and painted on the panel. A user interface could also be provided to allow the user to remove the shapes from the panel. (these shapes objects would then be removed from the collection and the panel repainted).

Is that close to it?

dmb71a at 2007-7-14 21:50:48 > top of Java-index,Desktop,Core GUI APIs...
# 5
Yes indeedy :o)
itchyscratchya at 2007-7-14 21:50:48 > top of Java-index,Desktop,Core GUI APIs...