This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bug (possibly only with xlib, but I doubt it): addNotify notalways called for AWT components


On Fri, 2005-01-21 at 18:45 -0500, Scott Gilbertson wrote:
> I have narrowed down the problem in my earlier posting ("AWT app not working
> with latest from cvs, seems to be CardLayout problem").  In my big
> application, some components under a CardLayout were not being displayed.
> The attached code illustrates the problem.
> 
> With my old gcc, which was "gcc (GCC) 3.5.0 20040603 (experimental)", on
> linux/x86, the program works OK.  With a recent main branch checkout from
> cvs, called "gcc (GCC) 4.0.0 20050108 (experimental)", I had to add the
> addNotify call you'll see in there.  I'm using the xlib peers, but I suspect
> the problem will occur with other peers as well.
> 
> I found that addNotify isn't called for components under the following
> conditions:
>   - The component is lightweight AWT
>   - The component is added to a container with a CardLayout
>      (I'm not sure that it has to be CardLayout, but that's what my app was
> doing)
>   - The container has already been shown on-screen before this component is
> added.
> That last one's the crux of the thing, I think.  It seems like in Container,
> invalidateTree should clear the valid flag, but it doesn't, so validateTree
> only works the first time it's called, and components added after that don't
> get an addNotify call.  Since addNotify isn't called, the component's peer
> is null, and isLightweight returns false, which essentially stops the
> component from painting.
> 
> Would somebody familiar with the validateTree, invalidateTree and add
> methods in Container be able to take a look?

This is probably caused by changes I made to the order in which
components are shown when added to an already-showing container.  These
changes were necessary to prevent GTK widgets from being shown before
they were properly sized and positioned.  I've attached the relevant
patches to Container.java and GtkContainerPeer.java.  You'll probably
need to make a similar change in the xlib container peer.

I tried your test on the GTK peers on the java-gui-branch and it works
fine.

Hope this helps,
Tom

--- gnu/java/awt/peer/gtk/GtkContainerPeer.java	6 Jul 2004 14:55:50
-0000	1.8.2.4
+++ gnu/java/awt/peer/gtk/GtkContainerPeer.java	7 Oct 2004 22:08:18
-0000
@@ -45,13 +45,16 @@
 import java.awt.Font;
 import java.awt.Graphics;
 import java.awt.Insets;
+import java.awt.Window;
 import java.awt.event.PaintEvent;
+import java.awt.peer.ComponentPeer;
 import java.awt.peer.ContainerPeer;
 
 public class GtkContainerPeer extends GtkComponentPeer
   implements ContainerPeer
 {
   Container c;
+  boolean isValidating;
 
   public GtkContainerPeer(Container c)
   {
@@ -59,22 +62,36 @@
     this.c = c;
   }
 
-  public void beginValidate() 
+  public void beginValidate ()
   {
+    isValidating = true;
   }
 
-  public void endValidate() 
+  public void endValidate ()
   {
-//      q.postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT,
-//  				 new Rectangle (x, y, width, height)));
-//      Graphics gc = getGraphics ();
-//      if (gc != null)
-//        {
-//  	awtComponent.update (gc);
-//  	gc.dispose ();
-//        }
-//      System.out.println ("got here");
-//      awtComponent.repaint ();
+    Component parent = awtComponent.getParent ();
+
+    // Only set our parent on the GTK side if our parent on the AWT
+    // side is not showing.  Otherwise the gtk peer will be shown
+    // before we've had a chance to position and size it properly.
+    if (parent != null && parent.isShowing ())
+      {
+        Component[] components = ((Container)
awtComponent).getComponents ();
+        int ncomponents = components.length;
+
+        for (int i = 0; i < ncomponents; i++)
+          {
+            ComponentPeer peer = components[i].getPeer ();
+
+            // Skip lightweight peers.
+            if (peer instanceof GtkComponentPeer)
+              ((GtkComponentPeer) peer).setParentAndBounds ();
+          }
+
+        setParentAndBounds ();
+      }
+
+    isValidating = false;
   }
 
   public Insets getInsets() 
--- java/awt/Container.java	27 Sep 2004 15:14:25 -0000	1.34.2.21
+++ java/awt/Container.java	7 Oct 2004 22:08:18 -0000
@@ -42,6 +42,8 @@
 import java.awt.event.ContainerListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
+import java.awt.event.KeyEvent;
+import java.awt.peer.ComponentPeer;
 import java.awt.peer.ContainerPeer;
 import java.awt.peer.LightweightPeer;
 import java.beans.PropertyChangeListener;
@@ -340,8 +342,6 @@
         comp.parent = this;
         if (peer != null)
           {
-            comp.addNotify();
-            
             if (comp.isLightweight ())
 	      {
 		enableEvents (comp.eventMask);
@@ -555,10 +555,19 @@
         cPeer.beginValidate();
       }
 
-    doLayout();
     for (int i = 0; i < ncomponents; ++i)
       {
         Component comp = component[i];
+
+        if (comp.getPeer () == null)
+          comp.addNotify();
+      }
+
+    doLayout ();
+    for (int i = 0; i < ncomponents; ++i)
+      {
+        Component comp = component[i];
+
         if (! comp.isValid())
           {
             if (comp instanceof Container)



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]