Swing - null

In a multithreaded application, some of my repaint requests are getting dropped.

The application does audio signal processing. There's a JPanel that displays the results in real time. Several asynchronous threads are operating simultaneously. One thread does the signal processing, and as each piece of the result gets generated, it issues a repaint for the vertical stripe of the display that's affected. Another thread scrolls the display horizontally. Each time the image is scrolled, the newly exposed stripe on the right edge of the screen gets repainted.

Sometimes a piece of the result doesn't get drawn. I've inserted print statements in the code to find out why. It turns out that if the signal processing thread calls repaint between the time the scrollbar gets adjusted, and the redrawing of the right edge of the screen, then the repaint never happens -- the request just gets dropped.

There seems to be some strange interaction between repaint and the scrollbars. Even though repaint() is supposed to be a thread-safe operation, there appear to be some times when it fails. Is this a known issue? Is there a simple workaround?

[1168 byte] By [JerryAgina] at [2007-11-26 23:10:12]
# 1

Here's some additional information. I'm trying to deal with this by setting thread priorities, but I'm having no luck. Here's what appears to be happening:

1. The signal processing thread starts to work on a segment of data.

2. The horizontal scrolling thread wakes up, and queues up a Runnable on the event dispatch thread.

3. The event dispatch thread executes the Runnable, which adjusts the horizontal scrollbar value. A whole chain of events follows, which I'm not able to trace directly, but my paintComponent() gets called twice with a clip region corresponding to the right edge of the screen.

4. The signal processing thread finishes its computation, and calls repaint for a stripe somewhere near the middle of the screen. If this occurs before step 3 is complete, the repaint gets lost.

I had hoped that by lowering the thread priority of the signal processing thread, I could prevent step 4 from occurring while the event dispatch thread still had work to do, but it doesn't work. I'm running Windows XP.

A possible workaround would be to have step 4 repaint not only its data, but the data from the preceding segment just in case it got lost, but I'd rather not do that if I don't have to.

JerryAgina at 2007-7-10 14:06:02 > top of Java-index,Desktop,Core GUI APIs...
# 2
If understand correctly, you need the repaint call to occur after the current work on the EDT is done. Are you using invokeLater when you call the repaint?
pthorsona at 2007-7-10 14:06:04 > top of Java-index,Desktop,Core GUI APIs...
# 3
Thanks! Calling invokeLater to do the repaint makes the program behave properly.There still appears to be a bug in Swing. The repaint requests should not have been dropped in the first place. But I'm not going to pursue it further.
JerryAgina at 2007-7-10 14:06:04 > top of Java-index,Desktop,Core GUI APIs...
# 4

There still appears to be a bug in Swing. The

repaint requests should not have been dropped in the

first place. But I'm not going to pursue it further.

This is not a bug. Taken from [1]

NOTE: if multiple calls to repaint() occur on a component or any of its Swing ancestors before the repaint request is processed, those multiple requests may be collapsed into a single call back to paintImmediately() on the topmost Swing component on which repaint() was invoked. For example, if a JTabbedPane contains a JTable and both issue calls to repaint() before any pending repaint requests on that hierarchy are processed, the result will be a single call to paintImmediately() on the JTabbedPane, which will cause paint() to be executed on both components.

[1] http://java.sun.com/products/jfc/tsc/articles/painting/index.html#paint_process

kirillga at 2007-7-10 14:06:04 > top of Java-index,Desktop,Core GUI APIs...
# 5

This is not a bug. Taken from [1]

I don't think that's what's happening here. If the scrolling requests a repaint for a narrow stripe on the right edge of the screen, and the signal processing requests a repaint for a narrow stripe in the middle of the screen, and the requests are merged, then I expect the merged clip rectangle should include the entire region from the middle to the right. But the paintComponents() that I'm seeing are for a narrow stripe on the right only. The mechanism described in [1] tries to be a more efficient way to satisfy both requests. It doesn't imply that one of the requests will be unsatisfied.

JerryAgina at 2007-7-10 14:06:04 > top of Java-index,Desktop,Core GUI APIs...
# 6
Maybe http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html contains the answer. It -sounds- like a threading issue (specifically GUI updates from a thread which is not AWT-0), and since using invokeLater fixes it...
deepravea at 2007-7-10 14:06:04 > top of Java-index,Desktop,Core GUI APIs...