JInternalFrame gets overdrawn by other frames plot.

I have a problem with multiple JInternalFrames: overlapping frames still get overlapped by lower frame's panel plots. Here's a screenshot that shows the problem:

http://sourceforge.net/tracker/download.php?group_id=181513&atid=897503&file_id=207557&aid=1617365

I would like the lower frames to keep drawing without "overdrawing" other frames on top. How can this be achieved?

[408 byte] By [MartinHilperta] at [2007-11-26 12:50:24]
# 1
Op likes to ask this question a lot, but refuses to provide any information to help us actually attempt to solve the problem. Here is my comment in his last posting: http://forum.java.sun.com/thread.jspa?threadID=5116557&tstart=0
camickra at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...
# 2

Well, I already described it more than once. And now I linked to a screenshot showing the "broken" image: the plot of the lower frame overlaps the upper frame.

I also don't do very fancy things in my overwritten paintComponent:

/**

* Panel to draw fractal on. This subclass is required to overwrite paintComponent() to draw the buffered/calculated image.

*/

private final class FractalPanel extends JPanel {

/**

* Constructor.

*/

public FractalPanel() {

super();

// setDoubleBuffered(true);

}

/**

* Overrides super.

* (Re-)paint BufferedImages to update image calculation progress.

*/

@Override

protected void paintComponent(final Graphics g) {

super.paintComponent(g);

if (bis != null) {

final int noOfBlocks = bis.length;

//paint complete image:

for (int i = 0; i < noOfBlocks; i++) { //for each block

g.drawImage(bis[i], rs[i].x, rs[i].y, this);

}//next block

}

}//paintComponent()

/**

* Only paint the section of the thread.

*

* @param index Index of BufferedImage to (re-)paint.

*/

public void paintComponent(final int index) {

//super.paintComponent(g);

Graphics g = getGraphics();

while (g == null) {

g = getGraphics();

}

g.drawImage(bis[index], rs[index].x, rs[index].y, this);

g.dispose();

}//paintComponent()

/**

* Description pending.

*/

public void clear() {

final Graphics g = getGraphics();

if (g != null) {

g.clearRect(0, 0, imageWidth, imageHeight);

//g.setColor(Color.gray);

//g.fillRect(0, 0, widthOfPlot, heightOfPlot);

g.dispose();

}

}//clear()

}//FractalPanel

MartinHilperta at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...
# 3

This not a SSCCE. We cannot compile the code and execute it or try to debug the problem.

> Well, I already described it more than once.

So, that doesn't mean it helps us know what you are doing. Also, you didn't get any help because nobody understands exactly what you are doing. The problem is in the code. For example, we don't know where or how your paintComponent(int) method is invoked.

If you can't solve the problem with all your debugging tools at your disposal, how to you expect us to help just by looking at a few random lines of code. Do you not understand that I have not seen the behaviour you are trying to describe and showed in your image. So how can I begin to guess what the problem is. Other people in forum have posted there entire fractal painting program withouth this kine of behaviour. Why do you refuse to provide us with the information we need to attempt to help solve the problem?

camickra at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...
# 4

The first post contains a link to an image that shows the problem. As you can see the second frame is on top (and overlaps the first frame) but the first frame's inner graphics panel is drawn over the second frame.

The JPanel of each frame that is used to draw on, is painted from separate threads. So the first frame is still painting on its JPanel while the second frame also paints on its JPanel. If both frames are painting on their JPanels, and the frames overlap, the overlapping region flickers as long as the first frame finished its painting.

If you want the full source code to have an executable "example" (is this the "SSCCE" you like?) can be downloaded [url=https://sourceforge.net/project/showfiles.php?group_id=181513&package_id=210323]here[/url].

MartinHilperta at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...
# 5
I tried version 0.9 and reproduced it.It seems you are updating frames from different threads, are you?At least it seems that repaints are happening independently and graphics of second frame is not aware of change of clipArea.
neigora at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...
# 6

Yes, each frame can have an arbitrary number of own threads painting on the frame's inner JPanel. So one thread has a specific rectangle of the JPanel (BufferedImage) that it draws on. I thought Java is handling the overlapping/clipping area and knows that the overlapping frame is covering this area. But it seems that drawing on a Graphics2D does not take into account that other (Swing) componente can overlap. Is this a bug - should I report it in the bug database?

MartinHilperta at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...
# 7

This is most likely a threading problem introduced on your part.

You must make the following assurance:

- The threads that draw the fractals must execute their painting code in a serialized fashion and do so in the same order that the painting events are generated.

That means if the UI repaints the back frame and then repaints the front frame, the following must happen: the thread for the back frame must paint it completely before the EDT has an opportunity to generate the repaint event the front frame. Otherwise you are executing painting code out of z-order, and you will expect to see such artifacts.

jvaudrya at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...
# 8
You may be able to fix: When the thread has updated the buffered image, it calls repaint() on your JInternalFrame instead of calling paintComponent() directly (assuming that's what you are doing).
jvaudrya at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...
# 9

Yes, repaint() seems to fix this problem. But I read that redrawing just the part that changed as I did:

g.drawImage(bis[index], rs[index].x, rs[index].y, this);

would be faster. So I overwrite paintComponent. With repaint(), this overlapping effect went away, but the drawing is now choppy instead of a steady, continuous draw of lines. :-/

MartinHilperta at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...
# 10
Drawing onto the screen using an application thread instead of the Event Dispatcher Thread is just asking for trouble.
jvaudrya at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...
# 11

> Drawing onto the screen using an application thread

> instead of the Event Dispatcher Thread is just asking

> for trouble.

That's bad news for Java in the field of multithreaded image processing. Not only for my multithreaded fractal program but also for other image processing software with heavy filtering and transforming algorithms.

MartinHilperta at 2007-7-7 16:36:32 > top of Java-index,Desktop,Core GUI APIs...