Re: GtkComponentPeer realization

2006-03-03 Thread Mark Wielaard
Hi Tom,

On Mon, 2006-02-20 at 15:50 -0500, Thomas Fitzsimmons wrote:
 On Mon, 2006-02-20 at 17:47 +0100, Mark Wielaard wrote:
  Yes. We do defer creation of the gtk-peer till the actual addNotify()
  call. But then we also defer the parent/bound-setting if the container
  is already visible till the container is actually made valid. This is at
  least a problem with (sub) classes of Panel and Canvas where
  applications seem to expect to be able to paint on them before they are
  actually validated.
 
 This is a very strange requirement; they require the ability to draw on
 a Component that may not be sized correctly?  Presumably that component
 will not be in that invalid state for long, and so will be repainted
 correctly when it is validated?

I am not sure it is an requirement. But there are clearly programs that
call paint(), update() and/or getGraphics() on Components at the
weirdest times.

  Tom, do you have an example where the delayed realization of the gtk+
  component was necessary/gave strange visual effects? I like to get to
  the bottom of this one.
 
 Yes, the problem was with adding a container of widgets to another
 already-showing container.  Since we were force-realizing widgets on
 creation, each widget would be shown at 0,0 with size 1x1, then moved
 into place and resized upon validation.  At the time there were bugs in
 the peer resizing code that made some widgets, including buttons, show
 up at their natural sizes.  The result was that for a big button box in
 vte, you'd see all the buttons stack up at 0,0 at their natural sizes,
 then be moved and resized into the right spot.

 In an attempt to solve this, and to be more in-line with GTK
 conventions, I eliminated forced realization.  The idea is that widgets
 should be realized when GTK decides to realize them: after they've been
 properly sized and parented.  So with the current code, I leave
 realization up to GTK and I only set bounds and parents on the peer side
 after all the AWT validation has occurred, in
 GtkContainerPeer.endValidate().
 
 Unfortunately, as Mark points out, this approach relies on validation to
 occur before getGraphics is called on a component, which (apparently)
 isn't guaranteed.  In fact, getGraphics must work as soon as addNotify
 has been called on it which can happen anytime independent of
 validation.  So delayed realization is unworkable and we should change
 back to forced-realization.

OK, I did this and I tried to make the impact as little as possible.
This patch handles the most common case where the Component bounds have
not been set yet (so are zero) then it wont show the component yet. This
doesn't solve all the cases as seen with vte when a Component is set to
a particular size before being added though. (It does solve one other
issue I was seeing where my app was hiding an Component by setting its
size to 0, previously we would ignore such a reshape call...)

I think this is the best we can do for now without doing something much
more tricky such hooking into things like endLayout which we don't
currently seem to support anyway. And it solve the crashes I was seeing
which I think is a more important issue then the jumping components
problem.

2006-03-03  Mark Wielaard  [EMAIL PROTECTED]

* gnu/java/awt/peer/gtk/GtkComponentPeer.java (GtkComponentPeer):
Always call setParentAndBounds().
(setComponentBounds): Always call setBounds().
(setBounds): Call setVisible().
(setVisible): If no pixels are showing then don't make it visible.
* gnu/java/awt/peer/gtk/GtkContainerPeer.java (endValidate): No need
to call setParentAndBounds() anymore.

What do you think?
The hsqldb, VTE and MegaMek seem to look and work fine with this.

Cheers,

Mark
Index: gnu/java/awt/peer/gtk/GtkComponentPeer.java
===
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java,v
retrieving revision 1.106
diff -u -r1.106 GtkComponentPeer.java
--- gnu/java/awt/peer/gtk/GtkComponentPeer.java	23 Feb 2006 19:22:24 -	1.106
+++ gnu/java/awt/peer/gtk/GtkComponentPeer.java	3 Mar 2006 20:05:56 -
@@ -145,12 +145,7 @@
 
 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 (awtComponent instanceof Window
-|| (parent != null  ! parent.isShowing ()))
-  setParentAndBounds ();
+setParentAndBounds ();
 
 setNativeEventMask ();
 
@@ -201,11 +196,6 @@
   void setComponentBounds ()
   {
 Rectangle bounds = awtComponent.getBounds ();
-
-if (bounds.x == 0  bounds.y == 0
- bounds.width == 0  bounds.height == 0)
-  return;
-
 setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
   }
 
@@ -487,6 +477,10 @@
   }
 
 setNativeBounds (new_x, new_y, width, 

Re: GtkComponentPeer realization

2006-03-03 Thread Thomas Fitzsimmons
On Fri, 2006-03-03 at 21:30 +0100, Mark Wielaard wrote:
 Hi Tom,
 
 On Mon, 2006-02-20 at 15:50 -0500, Thomas Fitzsimmons wrote:
  On Mon, 2006-02-20 at 17:47 +0100, Mark Wielaard wrote:
   Yes. We do defer creation of the gtk-peer till the actual addNotify()
   call. But then we also defer the parent/bound-setting if the container
   is already visible till the container is actually made valid. This is at
   least a problem with (sub) classes of Panel and Canvas where
   applications seem to expect to be able to paint on them before they are
   actually validated.
  
  This is a very strange requirement; they require the ability to draw on
  a Component that may not be sized correctly?  Presumably that component
  will not be in that invalid state for long, and so will be repainted
  correctly when it is validated?
 
 I am not sure it is an requirement. But there are clearly programs that
 call paint(), update() and/or getGraphics() on Components at the
 weirdest times.
 
   Tom, do you have an example where the delayed realization of the gtk+
   component was necessary/gave strange visual effects? I like to get to
   the bottom of this one.
  
  Yes, the problem was with adding a container of widgets to another
  already-showing container.  Since we were force-realizing widgets on
  creation, each widget would be shown at 0,0 with size 1x1, then moved
  into place and resized upon validation.  At the time there were bugs in
  the peer resizing code that made some widgets, including buttons, show
  up at their natural sizes.  The result was that for a big button box in
  vte, you'd see all the buttons stack up at 0,0 at their natural sizes,
  then be moved and resized into the right spot.
 
  In an attempt to solve this, and to be more in-line with GTK
  conventions, I eliminated forced realization.  The idea is that widgets
  should be realized when GTK decides to realize them: after they've been
  properly sized and parented.  So with the current code, I leave
  realization up to GTK and I only set bounds and parents on the peer side
  after all the AWT validation has occurred, in
  GtkContainerPeer.endValidate().
  
  Unfortunately, as Mark points out, this approach relies on validation to
  occur before getGraphics is called on a component, which (apparently)
  isn't guaranteed.  In fact, getGraphics must work as soon as addNotify
  has been called on it which can happen anytime independent of
  validation.  So delayed realization is unworkable and we should change
  back to forced-realization.
 
 OK, I did this and I tried to make the impact as little as possible.
 This patch handles the most common case where the Component bounds have
 not been set yet (so are zero) then it wont show the component yet. This
 doesn't solve all the cases as seen with vte when a Component is set to
 a particular size before being added though. (It does solve one other
 issue I was seeing where my app was hiding an Component by setting its
 size to 0, previously we would ignore such a reshape call...)
 
 I think this is the best we can do for now without doing something much
 more tricky such hooking into things like endLayout which we don't
 currently seem to support anyway. And it solve the crashes I was seeing
 which I think is a more important issue then the jumping components
 problem.

Yes, I agree.  This patch looks good, and even avoids force-realizing
widgets with gtk_widget_realize, while satisfying the AWT's
peer-creation criteria.  One small request: that you expand
Component.addNotify's javadocs to describe these criteria clearly for
future reference.

Thanks,
Tom





Re: GtkComponentPeer realization

2006-03-03 Thread Mark Wielaard
On Fri, 2006-03-03 at 16:05 -0500, Thomas Fitzsimmons wrote:
 Yes, I agree.  This patch looks good, and even avoids force-realizing
 widgets with gtk_widget_realize, while satisfying the AWT's
 peer-creation criteria.  One small request: that you expand
 Component.addNotify's javadocs to describe these criteria clearly for
 future reference.

Good point. I only realized (pun intended) that setParent() would do the
right thing in the constructor because of the way addNotify() is called.
Documented as follows:

2006-03-03  Mark Wielaard  [EMAIL PROTECTED]

* java/awt/Component.java (addNotify): Expand documentation.

diff -u -r1.104 Component.java
--- java/awt/Component.java 28 Feb 2006 11:27:15 -  1.104
+++ java/awt/Component.java 3 Mar 2006 21:10:40 -
@@ -3426,10 +3426,11 @@
   }

   /**
-   * Called to inform this component it has been added to a container.
-   * A native peer - if any - is created at this time. This method is
-   * called automatically by the AWT system and should not be called by
-   * user level code.
+   * Called when the parent of this Component is made visible or when
+   * the Component is added to an already visible Container and needs
+   * to be shown.  A native peer - if any - is created at this
+   * time. This method is called automatically by the AWT system and
+   * should not be called by user level code.
*
* @see #isDisplayable()
* @see #removeNotify()



signature.asc
Description: This is a digitally signed message part


Re: GtkComponentPeer realization

2006-02-20 Thread Roman Kennke
Hi Mark,


 OK, I see now where the trouble comes from. In GtkComponentPeer
 constructor we have:
 
 // 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 (awtComponent instanceof Window
 || (parent != null  ! parent.isShowing ()))
   setParentAndBounds ();
 
 So if a component is added to an already showing Container its parent is
 not set. We try to set it later in GtkContainerPeer.endValidate(). But
 1) There is a small bug that doesn't setParentAndBounds for direct
 children of a Window. (That is easily fixed though.)
 2) That only works if the Container is actually revalidated before the
 just added Component is painted.
 
 I don't see how/if 2) ever happens/should happen after a
 Container.add(Component). The Container is invalid after an add().
 When/Where should validate[Tree]() be called after a new component has
 been added?

This is not performed automatically in AWT. We used to do it in
setVisible somewhere if I remember correctly, but tests have shown that
this is not right (and in fact leads to strange interactions with Swing,
where we _do_ perform validation automatically). The GTK peers therefore
should initialize correctly even when the component is not validated and
not try to defer things. (Actually, the AWT itself defers initialization
of the peers themselves, they are not created with the component, but
instead when the component receives a call to addNotify).

I hope this helps,
Roman


signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil


Re: GtkComponentPeer realization

2006-02-20 Thread Mark Wielaard
On Mon, 2006-02-20 at 15:20 +0100, Roman Kennke wrote:
  I don't see how/if 2) ever happens/should happen after a
  Container.add(Component). The Container is invalid after an add().
  When/Where should validate[Tree]() be called after a new component has
  been added?
 
 This is not performed automatically in AWT. We used to do it in
 setVisible somewhere if I remember correctly, but tests have shown that
 this is not right (and in fact leads to strange interactions with Swing,
 where we _do_ perform validation automatically).

OK. Thanks. That probably explains why the delayed parenting and
realization did work in the past.

  The GTK peers therefore
 should initialize correctly even when the component is not validated and
 not try to defer things. (Actually, the AWT itself defers initialization
 of the peers themselves, they are not created with the component, but
 instead when the component receives a call to addNotify).

Yes. We do defer creation of the gtk-peer till the actual addNotify()
call. But then we also defer the parent/bound-setting if the container
is already visible till the container is actually made valid. This is at
least a problem with (sub) classes of Panel and Canvas where
applications seem to expect to be able to paint on them before they are
actually validated.

Tom, do you have an example where the delayed realization of the gtk+
component was necessary/gave strange visual effects? I like to get to
the bottom of this one.

Cheers,

Mark


signature.asc
Description: This is a digitally signed message part


Re: GtkComponentPeer realization

2006-02-20 Thread Thomas Fitzsimmons
On Mon, 2006-02-20 at 17:47 +0100, Mark Wielaard wrote:
 On Mon, 2006-02-20 at 15:20 +0100, Roman Kennke wrote:
   I don't see how/if 2) ever happens/should happen after a
   Container.add(Component). The Container is invalid after an add().
   When/Where should validate[Tree]() be called after a new component has
   been added?
  
  This is not performed automatically in AWT. We used to do it in
  setVisible somewhere if I remember correctly, but tests have shown that
  this is not right (and in fact leads to strange interactions with Swing,
  where we _do_ perform validation automatically).
 
 OK. Thanks. That probably explains why the delayed parenting and
 realization did work in the past.
 
   The GTK peers therefore
  should initialize correctly even when the component is not validated and
  not try to defer things. (Actually, the AWT itself defers initialization
  of the peers themselves, they are not created with the component, but
  instead when the component receives a call to addNotify).
 
 Yes. We do defer creation of the gtk-peer till the actual addNotify()
 call. But then we also defer the parent/bound-setting if the container
 is already visible till the container is actually made valid. This is at
 least a problem with (sub) classes of Panel and Canvas where
 applications seem to expect to be able to paint on them before they are
 actually validated.

This is a very strange requirement; they require the ability to draw on
a Component that may not be sized correctly?  Presumably that component
will not be in that invalid state for long, and so will be repainted
correctly when it is validated?

 
 Tom, do you have an example where the delayed realization of the gtk+
 component was necessary/gave strange visual effects? I like to get to
 the bottom of this one.

Yes, the problem was with adding a container of widgets to another
already-showing container.  Since we were force-realizing widgets on
creation, each widget would be shown at 0,0 with size 1x1, then moved
into place and resized upon validation.  At the time there were bugs in
the peer resizing code that made some widgets, including buttons, show
up at their natural sizes.  The result was that for a big button box in
vte, you'd see all the buttons stack up at 0,0 at their natural sizes,
then be moved and resized into the right spot.

There are two cases that we must handle when adding a container to
another container and both cases must be handled differently when
implementing them on GTK:

1) the parent container is not showing

2) the parent container is showing

For case 1 forced realization works fine because the widgets aren't
actually shown until the parent is showing, and at that point everything
is correctly laid out.

For case 2 forced realization causes child components to be shown as
soon as their peers are created.  Container.validateTree does this:

  ContainerPeer.beginValidate()

  create peers for all child components in this container

  do layout, setting the child component and child component peers'
bounds

  validate child containers recursively

  ContainerPeer.endValidate()

With forced realization all the peers are shown when they are first
created, *then* moved and resized when layout is called.  This was a bug
in our AWT implementation which didn't affect other peer sets.

In an attempt to solve this, and to be more in-line with GTK
conventions, I eliminated forced realization.  The idea is that widgets
should be realized when GTK decides to realize them: after they've been
properly sized and parented.  So with the current code, I leave
realization up to GTK and I only set bounds and parents on the peer side
after all the AWT validation has occurred, in
GtkContainerPeer.endValidate().

Unfortunately, as Mark points out, this approach relies on validation to
occur before getGraphics is called on a component, which (apparently)
isn't guaranteed.  In fact, getGraphics must work as soon as addNotify
has been called on it which can happen anytime independent of
validation.  So delayed realization is unworkable and we should change
back to forced-realization.

Maybe we can solve the original problem using
gtk_widget_show/gtk_widget_hide.  I wonder how other toolkits (e.g.
Sun's Motif implementation) solve this validate-while-showing problem.
Perhaps it's not worth worrying about at this point (though I find
validating-while-showing very sloppy).

Tom





Re: GtkComponentPeer realization

2006-02-19 Thread Mark Wielaard
Hi Tom,

On Thu, 2006-02-09 at 09:53 -0500, Thomas Fitzsimmons wrote:
 An unrealized GtkComponentPeer is a GtkWidget that has an
 uninitialized X window field.  In other words, the X server doesn't
 have a window data structure allocated for it.  We used to
 force-realize every GtkComponentPeer on construction but that lead to
 strange behaviour when adding a hierarchy of components to an
 already-shown container (all components would be shown first at
 0,0-1x1 then layed out after that).
 Delayed realization makes the peer code much more complicated, and
 adding a container to an already-shown container is rare so I'm
 thinking it may be acceptable to switch the code back to
 force-realization-on-creation.  It would simplify GtkComponentPeer
 GdkGraphics and would probably eliminate these situations that you're
 describing.

OK, I see now where the trouble comes from. In GtkComponentPeer
constructor we have:

// 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 (awtComponent instanceof Window
|| (parent != null  ! parent.isShowing ()))
  setParentAndBounds ();

So if a component is added to an already showing Container its parent is
not set. We try to set it later in GtkContainerPeer.endValidate(). But
1) There is a small bug that doesn't setParentAndBounds for direct
children of a Window. (That is easily fixed though.)
2) That only works if the Container is actually revalidated before the
just added Component is painted.

I don't see how/if 2) ever happens/should happen after a
Container.add(Component). The Container is invalid after an add().
When/Where should validate[Tree]() be called after a new component has
been added?

Cheers,

Mark


signature.asc
Description: This is a digitally signed message part


Re: GtkComponentPeer realization

2006-02-13 Thread Thomas Fitzsimmons
On Sat, 2006-02-11 at 23:00 +0100, Mark Wielaard wrote:
 Hi Tom,
 
 On Fri, 2006-02-10 at 12:52 -0500, Thomas Fitzsimmons wrote:
   I am not sure how/where the GtkPanelPeer should have been realized
   and/or whether this comes from the delayed realization you talked
   about (I don't actually see where this Panel will ever get realized to
   be honest).
  
  Yes, panels are never realized because they do not have an X window
  associated with them.  Instead they draw on their parent's X window.  So
  GtkPanelPeer should probably override isRealized to check if it has a
  parent and if so, if that parent is realized.
 
 But then they should also override getGraphics() I presume to return the
 (translated) Graphics of their parent Container? And currently they
 don't. Also we seem to explicitly request an X window to be associated
 since in GtkPanelPeer.c we say:
   gtk_fixed_set_has_window (GTK_FIXED (widget), TRUE);
 We also request GTK_CAN_FOCUS. Is that possible on widgets without a
 window?
 
 And in fact Graphics object returned from a Panel is often correct. Only
 in situations like the example I gave does it never get realized
 correctly it seems.
 
 Puzzling...

You're right.  GtkPanelPeers do have their own windows now; I was
thinking of a previous revision of this code.  To answer your original
question, GtkPanelPeers are realized when they are shown.

Tom

 
 Cheers,
 
 Mark




Re: GtkComponentPeer realization

2006-02-10 Thread Thomas Fitzsimmons
On Fri, 2006-02-10 at 00:26 +0100, Mark Wielaard wrote:
 Hi Tom,
 
 On Thu, 2006-02-09 at 09:53 -0500, Thomas Fitzsimmons wrote:
  On Thu, 2006-02-09 at 13:52 +0100, Mark Wielaard wrote:
   I like to debug this a bit further, but I couldn't find good
   documentation on the handling of (un)realized GtkComponentPeers. Does
   anybody have a link or an explanation of whether or not the above should
   ever happen?
  
  Yes it can happen especially in multi-threaded applications.  You're
  probably right to just ignore the paint event.  It'd be useful to know
  if hsqldb makes calls into the peers from different threads.  For
  example if it shows a window in one thread and another thread handles
  painting on that window.
 
 No it doesn't. I was finally able to extract a simple testcase that
 shows the problem which also doesn't use any extra application Threads.
 See attached. If you update the tree to include Lillian's latest patches
 for GtkPanelPeer (which made the logic more clear to me, thanks Lillian)
 and add the following hack, you can see that the Panel doesn't seem to
 get realized. And always will print out the following after clicking on
 the button:
 
 getGraphics() called on unrealized:
 java.awt.Panel[panel0,4,25,66x25,invalid,parent=frame0,layout=java.awt.FlowLayout]
 
 I am not sure how/where the GtkPanelPeer should have been realized
 and/or whether this comes from the delayed realization you talked
 about (I don't actually see where this Panel will ever get realized to
 be honest).

Yes, panels are never realized because they do not have an X window
associated with them.  Instead they draw on their parent's X window.  So
GtkPanelPeer should probably override isRealized to check if it has a
parent and if so, if that parent is realized.

Tom

 
 The Hack (or workaround, if you only put in the return null, and not the
 dumpStack):
 
 --- gnu/java/awt/peer/gtk/GtkComponentPeer.java   9 Feb 2006 17:44:30 
 -   1.101
 +++ gnu/java/awt/peer/gtk/GtkComponentPeer.java   9 Feb 2006 23:14:19 
 -
 @@ -263,6 +262,13 @@
  
public Graphics getGraphics ()
{
 +if (! isRealized())
 +  {
 + System.err.println(getGraphics() called on unrealized:  + awtWidget);
 + Thread.dumpStack();
 + return null;
 +  }
 +
  if (GtkToolkit.useGraphics2D ())
  return new GdkGraphics2D (this);
  else
 
 Any insights on how to properly debug this welcome.
 
 I do have one patch to make the event passing a bit simpler. That
 doesn't change the result of this test case, but it makes it a little
 easier to follow the events that are fired. I'll post it in a second to
 the patches list.
 
 Cheers,
 
 Mark




Re: GtkComponentPeer realization

2006-02-09 Thread Thomas Fitzsimmons
On Thu, 2006-02-09 at 13:52 +0100, Mark Wielaard wrote:
 Hi,
 
 After a lot of debugging I finally found out why a program I was testing
 was crashing sometimes. (The hsqldb AWT frontend - try the
 org.hsqldb.util.DatabaseManager class from the hsqldb.jar as distributed
 with OpenOffice for example.) A GtkGraphics object is created
 differently for realized and un-realized components. When we get a paint
 event for an unrealized component and try to use the associated
 GdkGraphics object bad things happen (because NSA_GET_G_PTR returns null
 in such cases).
 
 The attached hack makes things work for now by just ignoring such paint
 events for such objects. It gives:
 
 NOT handling 
 java.awt.event.PaintEvent[UPDATE,updateRect=java.awt.Rectangle[x=0,y=0,width=360,height=300]]
  on org.hsqldb.util.Grid[panel0,0,0,360x300,invalid,parent=panel1] for 
 UNREALIZED org.hsqldb.util.Grid[panel0,0,0,360x300,invalid,parent=panel1]
 
 I like to debug this a bit further, but I couldn't find good
 documentation on the handling of (un)realized GtkComponentPeers. Does
 anybody have a link or an explanation of whether or not the above should
 ever happen?

Yes it can happen especially in multi-threaded applications.  You're
probably right to just ignore the paint event.  It'd be useful to know
if hsqldb makes calls into the peers from different threads.  For
example if it shows a window in one thread and another thread handles
painting on that window.

An unrealized GtkComponentPeer is a GtkWidget that has an uninitialized
X window field.  In other words, the X server doesn't have a window data
structure allocated for it.  We used to force-realize every
GtkComponentPeer on construction but that lead to strange behaviour when
adding a hierarchy of components to an already-shown container (all
components would be shown first at 0,0-1x1 then layed out after that).
Delayed realization makes the peer code much more complicated, and
adding a container to an already-shown container is rare so I'm thinking
it may be acceptable to switch the code back to
force-realization-on-creation.  It would simplify GtkComponentPeer
GdkGraphics and would probably eliminate these situations that you're
describing.

Tom





Re: GtkComponentPeer realization

2006-02-09 Thread Mark Wielaard
Hi Tom,

On Thu, 2006-02-09 at 09:53 -0500, Thomas Fitzsimmons wrote:
 On Thu, 2006-02-09 at 13:52 +0100, Mark Wielaard wrote:
  I like to debug this a bit further, but I couldn't find good
  documentation on the handling of (un)realized GtkComponentPeers. Does
  anybody have a link or an explanation of whether or not the above should
  ever happen?
 
 Yes it can happen especially in multi-threaded applications.  You're
 probably right to just ignore the paint event.  It'd be useful to know
 if hsqldb makes calls into the peers from different threads.  For
 example if it shows a window in one thread and another thread handles
 painting on that window.

No it doesn't. I was finally able to extract a simple testcase that
shows the problem which also doesn't use any extra application Threads.
See attached. If you update the tree to include Lillian's latest patches
for GtkPanelPeer (which made the logic more clear to me, thanks Lillian)
and add the following hack, you can see that the Panel doesn't seem to
get realized. And always will print out the following after clicking on
the button:

getGraphics() called on unrealized:
java.awt.Panel[panel0,4,25,66x25,invalid,parent=frame0,layout=java.awt.FlowLayout]

I am not sure how/where the GtkPanelPeer should have been realized
and/or whether this comes from the delayed realization you talked
about (I don't actually see where this Panel will ever get realized to
be honest).

The Hack (or workaround, if you only put in the return null, and not the
dumpStack):

--- gnu/java/awt/peer/gtk/GtkComponentPeer.java 9 Feb 2006 17:44:30 -   
1.101
+++ gnu/java/awt/peer/gtk/GtkComponentPeer.java 9 Feb 2006 23:14:19 -
@@ -263,6 +262,13 @@
 
   public Graphics getGraphics ()
   {
+if (! isRealized())
+  {
+   System.err.println(getGraphics() called on unrealized:  + awtWidget);
+   Thread.dumpStack();
+   return null;
+  }
+
 if (GtkToolkit.useGraphics2D ())
 return new GdkGraphics2D (this);
 else

Any insights on how to properly debug this welcome.

I do have one patch to make the event passing a bit simpler. That
doesn't change the result of this test case, but it makes it a little
easier to follow the events that are fired. I'll post it in a second to
the patches list.

Cheers,

Mark
import java.awt.*;
import java.awt.event.*;

public class PanelPanel extends Frame implements ActionListener
{
  public static void main(String[] args)
  {
new PanelPanel();
  }

  PanelPanel()
  {
Button b = new Button(Click me!);
b.addActionListener(this);
add(b);
pack();
show();
  }

  public void actionPerformed(ActionEvent ae)
  {
Panel p = new Panel();
p.setBounds(new Rectangle(20, 20));
removeAll();
add(p);
doLayout();
p.repaint();
  }
}


signature.asc
Description: This is a digitally signed message part