I am running into an issue with a particular Swing application I am working on, which oddly enough manifests itself all over this application... but I've never encountered it in any other Swing apps I've ever done.
This app is a typical one. It consists of a JFrame; at the top of the JFrame is a JMenuBar, and below that is a JToolBar; then there is a content area which consists of a JTabbedPane--it contains four tabs, each of which consists primarily of a JScrollPane that contains a custom JPanel. Finally, there is a JPanel at the bottom serving as a status bar.
So basically, think Firefox, with four tabs open.
It's also important to note that each JPanel--contained by a JScrollPane within the main JTabbedPane--is used as a canvas; that is, I don't add() components, but rather I simply override paint() and do my own drawing.
Here's my problem: whenever one of those JPanels is larger than the viewport of its JScrollPane, it begins painting artifacts on top of the rest of my application. For example, let's say that in a particular JPanel, at the top I draw the String "This is a Header" in a large bold font. Then I scroll down. The large-bold-font-String "This is a Header" will begin to appear on the JToolBar, or the JMenuBar, at the top of my frame. Similarly, stuff that I draw at the bottom of the JPanel will start appearing overtop of my status bar. This problem becomes more pronounced as I, say, resize the JFrame.
Obviously, my overriding paint() has something to do with this. I realize that most documentation says to override paintComponent() rather than paint(); I tried that, but still have the same problem. I figure maybe I'm skipping some step, such as setting a clipping rect or something, but I'm not sure exactly where to go from here.
Any advice? Thanks in advance!
Dave Taubler<br />Specializing in <a href="http://taubler.com/articles/" target="_blank" rel="nofollow">Java and Web Development</a>
Joined: Jan 14, 2004
When you do drawing in an overridden painting method inside a lightweight, opaque component you need to clear the background before each trip through the painting method unless you fill in all the background yourself, eg, drawing an offscreen image that fills the component. An easy way to do this is to call super which directs the parent component (enclosing class whose painting method you are overriding) to draw itself. In java:
This is the main cause of artifacts in drawing. I think that the paintComponent method is recommended because the paint method calls paintComponent and two other methods and is capable of drawing on top of child components (sometimes this is what you want) so it is easier to get into trouble with it.
Joined: May 15, 2001
Thanks; I tried that, but unfortunately it didn't work. The main problem is that the artifacts aren't appearing on the JPanel itself, but rather on completely different JComponents throughout the panel. For example, pretend that your web browser is my application. Probably there is a banner ad at the top of this page, and furthermore, the entire page doesn't fit within the window, e.g. there is a scrollbar to the right. Imagine if you scrolled down about 50 pixels or so, and then the banner ad started covering up your browser's toolbar or address bar. That's what my app is doing.
Joined: May 15, 2001
Turns out I was causing it (go figure), and it did have to do with clipping. Basically, hidden well within the call stack, one of my custom components was setting a clip on the Graphics, and then soon after setting the clip to null. So the overall "correct" clip was being effectively removed, thus giving my JPanels free reign to muck up the rest of my app.