Hi list, hi Thomas, I am working on the Swing painting stuff in the hope to optimize it. I added some 'improvement' to JComponent (which is attached), which should enable double buffering in Swing painting, even if the paint request comes from the AWT side (which simply calls paint, instead of paintImmediatly that is called by Swing's RepaintManager).
The problem is, this hack triggers a segfault:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1395782736 (LWP 8688)]
0xae43e6b0 in Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative (
env=0x805f234, obj=0xafe83938, x=-5, y=-5)
at gnu_java_awt_peer_gtk_GdkGraphics.c:281
281 g->x_offset += x;
(gdb)
I really don't see why my JComponent hack could cause g to be NULL. I am
not doing something illegal in JComponent, do I?
BTW: You might think that my 'stunt act' in JComponent looks a little
weird. Meditate a little over it. The reason I do it this way and not
like it has been for some time is to provide more compatibility between
AWT and Swing, so that Swing components can be used inside an AWT tree
(and not only JRootPanes, like it has been before). I think this hack
should work as it is.
Any ideas on the segfault?
/Roman
Index: javax/swing/JComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v
retrieving revision 1.59
diff -u -r1.59 JComponent.java
--- javax/swing/JComponent.java 22 Sep 2005 20:58:34 -0000 1.59
+++ javax/swing/JComponent.java 24 Sep 2005 20:06:40 -0000
@@ -341,6 +341,12 @@
boolean autoscrolls = false;
/**
+ * Indicates whether the current paint call is already double buffered or
+ * not.
+ */
+ static boolean isPaintingDoubleBuffered = false;
+
+ /**
* Listeners for events other than [EMAIL PROTECTED] PropertyChangeEvent} are
* handled by this listener list. PropertyChangeEvents are handled in
* [EMAIL PROTECTED] #changeSupport}.
@@ -1449,9 +1455,24 @@
*/
public void paint(Graphics g)
{
- paintComponent(g);
- paintBorder(g);
- paintChildren(g);
+ RepaintManager rm = RepaintManager.currentManager(this);
+ // We do a little stunt act here to switch on double buffering if it's
+ // not already on. If we are not already doublebuffered, then we jump
+ // into the method paintDoubleBuffered, which turns on the double buffer
+ // and then calls paint(g) again. In the second call we go into the else
+ // branch of this if statement and actually paint things to the double
+ // buffer. When this method completes, the call stack unwinds back to
+ // paintDoubleBuffered, where the buffer contents is finally drawn to the
+ // screen.
+ if (!isPaintingDoubleBuffered && isDoubleBuffered()
+ && rm.isDoubleBufferingEnabled())
+ paintDoubleBuffered(g);
+ else
+ {
+ paintComponent(g);
+ paintBorder(g);
+ paintChildren(g);
+ }
}
/**
@@ -1604,10 +1625,13 @@
void paintImmediately2(Rectangle r)
{
RepaintManager rm = RepaintManager.currentManager(this);
+ Graphics g = getGraphics();
+ g.setClip(r.x, r.y, r.width, r.height);
if (rm.isDoubleBufferingEnabled() && isDoubleBuffered())
- paintDoubleBuffered(r);
+ paintDoubleBuffered(g);
else
- paintSimple(r);
+ paintSimple(g);
+ g.dispose();
}
/**
@@ -1615,38 +1639,40 @@
*
* @param r the area to be repainted
*/
- void paintDoubleBuffered(Rectangle r)
+ void paintDoubleBuffered(Graphics g)
{
+
+ Rectangle r = g.getClipBounds();
+ if (r == null)
+ r = new Rectangle(0, 0, getWidth(), getHeight());
RepaintManager rm = RepaintManager.currentManager(this);
// Paint on the offscreen buffer.
- Image buffer = rm.getOffscreenBuffer(this, getWidth(), getHeight());
- Graphics g = buffer.getGraphics();
- Graphics g2 = getComponentGraphics(g);
- g2.setClip(r.x, r.y, r.width, r.height);
- paint(g2);
- g2.dispose();
- g.dispose();
+ synchronized (paintLock)
+ {
+ Image buffer = rm.getOffscreenBuffer(this, getWidth(), getHeight());
+ Graphics g2 = buffer.getGraphics();
+ g2 = getComponentGraphics(g);
+ g2.setClip(r.x, r.y, r.width, r.height);
+ isPaintingDoubleBuffered = true;
+ paint(g2);
+ isPaintingDoubleBuffered = false;
+ g2.dispose();
- // Paint the buffer contents on screen.
- Graphics g3 = getGraphics();
- g3.setClip(r.x, r.y, r.width, r.height);
- g3.drawImage(buffer, 0, 0, this);
- g3.dispose();
+ // Paint the buffer contents on screen.
+ g.drawImage(buffer, 0, 0, this);
+ }
}
/**
* Performs normal painting without double buffering.
*
- * @param r the area to be repainted
+ * @param g the graphics context to use
*/
- void paintSimple(Rectangle r)
+ void paintSimple(Graphics g)
{
- Graphics g = getGraphics();
Graphics g2 = getComponentGraphics(g);
paint(g2);
- g2.dispose();
- g2.dispose();
}
/**
signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil
_______________________________________________ Classpath mailing list [email protected] http://lists.gnu.org/mailman/listinfo/classpath

