This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I'm writing a graphics program. The problem I'm having is that whenever the menu drops over the graphics area, it erases the lines that I have drawn. Also when I minimize and the restore the window, all the graphics is lost. Is there something I'm missing to preserve the lines I've drawn in the graphics area.
I've included the code below. Could someone please advise me as to what to do.
I do have the steps that was listed in the thread you had kindly directly me to. However, my problem is not that I cannot draw graphics. That I can do. My problem is that once I have drawn the graphics and then bring up the menu, the area that the menu occupied on the graphics gets cleared. Also, if you minimize and then restore the window, the graphics is cleared.
Painting seems easy at first, and it really is, but there are some seemingly small details that require attention to insure success. Comments: In your app you are using getGraphics to access the graphics context of the JFrame for painting. This is not recommended.
Swing decides on its own when to repaint your gui. This can happen at any time and certainly after minimize/restore or re–exposure from beneath other apps.
During each of these episodes your painting code will be properly rendered only if Swing can get to it in this chain of paint calls.
Since getGraphics is only called in your event code it is not rendered during these Swing–initiated repaints.
This is why it is recommended that all painting code be in or originate from the paintComponent method (in Swing).
Trying to paint in the graphics context of a container such as JFrame is not a preferred practice. The paint method in JFrame will paint over everything in the JFrame (see api). Sometimes this is what you need to do but it requires care. The preferred way is to do the painting in a JComponent (JPanels are handy) and add this to your gui container.
The strategy for painting is fairly simple. Put everything in paintComponent that you want to be painted. Let the enclosing class keep state for any variables (like color, size, position) that you want to manipulate and update/display in your painting code. Manipulate these variables from your event code.
Keeping the event–related code separate from the paint–related code will make it easier to understand and write the code that does what you want. This sounds like a cliche but look at the class design/structure in the app below. One class paints graphics. Another class arranges and handles all the user interaction with the app and the subsequent manipulation of variables in the painting class. The challenge with this approach is in deciding how you want the two to communicate with one another.
[ June 26, 2004: Message edited by: Craig Wood ]
Joined: Mar 26, 2004
Thanks for stepping in here, Craig! Great contribution, thanks a lot!
Joined: May 15, 2003
Thanks Craig for your reply.
I understand what you are saying but still not sure where to make the changes to my code. I suppose I must still try tinkering around with this one.
I would strongly recommend following Craig's advice and implementing a paintComponent() method, for the record I'd like to point out another technique you can use. Try replacing DrawingPlanel with this version, also deleting the original mouse listener which has been moved into the drawing panel:
You've disabled resizing, although this code will work after resizing with the caveat that when you make it smaller the stuff off the edge is lost.
Joined: Jan 14, 2004
Additional comments: Added state to the DrawingPanel class in the form of two ArrayLists: one for the temporary, current–time drawing and the other for all previously–drawn lines.
Added repaint calls in JMenuItem listeners to update the view for changes in penColor.