This is the mail archive of the java-patches@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]

FYI: patch to java/awt/Container.java


hi,

I've just committed this patch to gcc having seen tromey's response to it -- approving -- in my mail queue, but then I realized post-commit that I had only posted it for review on classpath list, not here. hopefully no objections?

-graydon

2004-01-07 Graydon Hoare <graydon@redhat.com>

	* java/awt/Container.java (LightweightDispatcher): Implement.
	(visitChild): Reuse graphics object.
	(dispatchEventImpl): Optionally dispatch to lightweight.
	(addNotifyContainerChildren): Build LightweightDispatcher.

--- java/awt/Container.java	7 Jan 2004 21:20:01 -0000	1.28
+++ java/awt/Container.java	8 Jan 2004 03:34:10 -0000
@@ -41,6 +41,7 @@
 import java.awt.event.ContainerEvent;
 import java.awt.event.ContainerListener;
 import java.awt.event.MouseEvent;
+import java.awt.event.KeyEvent;
 import java.awt.peer.ContainerPeer;
 import java.awt.peer.LightweightPeer;
 import java.beans.PropertyChangeListener;
@@ -1229,26 +1230,39 @@
                           Component comp)
   {
     Rectangle bounds = comp.getBounds();
-    Rectangle clip = gfx.getClipBounds().intersection(bounds);
+    Rectangle oldClip = gfx.getClipBounds();
+    if (oldClip == null)
+      oldClip = bounds;
+    Rectangle clip = oldClip.intersection(bounds);
 
     if (clip.isEmpty()) return;
 
-    Graphics gfx2 = gfx.create();
+    boolean clipped = false;
+    boolean translated = false;
     try
       {
-	gfx2.setClip(clip.x, clip.y, clip.width, clip.height);
-	gfx2.translate(bounds.x, bounds.y);
-
-	visitor.visit(comp, gfx2);
+        gfx.setClip(clip.x, clip.y, clip.width, clip.height);
+        clipped = true;
+        gfx.translate(bounds.x, bounds.y);
+        translated = true;
+        visitor.visit(comp, gfx);
       }
     finally
       {
-	gfx2.dispose ();
+        if (translated)
+          gfx.translate (-bounds.x, -bounds.y);
+        if (clipped)
+          gfx.setClip (oldClip.x, oldClip.y, oldClip.width, oldClip.height);
       }
   }
 
   void dispatchEventImpl(AWTEvent e)
   {
+    // Give lightweight dispatcher a chance to handle it.
+    if (dispatcher != null 
+        && dispatcher.handleEvent (e))
+      return;
+
     if ((e.id <= ContainerEvent.CONTAINER_LAST
              && e.id >= ContainerEvent.CONTAINER_FIRST)
         && (containerListener != null
@@ -1319,6 +1333,17 @@
             component[i].addNotify();
             if (component[i].isLightweight ())
 	      {
+
+                // If we're not lightweight, and we just got a lightweight
+                // child, we need a lightweight dispatcher to feed it events.
+                if (! this.isLightweight() 
+                    && dispatcher == null)
+                  {
+                    dispatcher = new LightweightDispatcher (this);
+                    dispatcher.enableEvents (component[i].eventMask);
+                  }	
+	  
+
 		enableEvents(component[i].eventMask);
 		if (peer != null && !isLightweight ())
 		  enableEvents (AWTEvent.PAINT_EVENT_MASK);
@@ -1495,22 +1520,25 @@
 } // class Container
 
 /**
- * Undocumented helper class.
- * STUBBED
+ * There is a helper class implied from stack traces called
+ * LightweightDispatcher, but since it is not part of the public API,
+ * rather than mimic it exactly we write something which does "roughly
+ * the same thing".
  */
-class LightweightDispatcher implements Serializable, AWTEventListener
+
+class LightweightDispatcher implements Serializable
 {
   private static final long serialVersionUID = 5184291520170872969L;
   private Container nativeContainer;
   private Component focus;
-  private transient Component mouseEventTarget;
-  private transient Component targetLastEntered;
-  private transient boolean isMouseInNativeContainer;
   private Cursor nativeCursor;
   private long eventMask;
   
+  private transient Component mouseEventTarget;
+  
   LightweightDispatcher(Container c)
   {
+    nativeContainer = c;
   }
 
   void dispose()
@@ -1519,40 +1547,106 @@
 
   void enableEvents(long l)
   {
+    eventMask |= l;
   }
 
-  boolean dispatchEvent(AWTEvent e)
+  void mouseExit (MouseEvent me, int x, int y)
   {
-    return true;
   }
 
-  boolean isMouseGrab(MouseEvent e)
+  void acquireComponentForMouseEvent (MouseEvent me)
   {
-    return true;
-  }
+    int x = me.getX ();
+    int y = me.getY ();
+
+    Component candidate = mouseEventTarget;
+
+    boolean candidate_is_container_with_children = 
+	    ((candidate != null)
+	     && (candidate instanceof Container)
+	     && (((Container)candidate).getComponentCount () > 0));
 
-  boolean processMouseEvent(MouseEvent e)
+    boolean candidate_does_not_contain_point =
+	    ((candidate != null)
+	     && (! candidate.contains (x - candidate.getX (),
+                                 y - candidate.getY ())));
+
+    if (candidate == null
+        || candidate_is_container_with_children
+        || candidate_does_not_contain_point)
   {
-    return true;
+        // Try to reacquire.
+        candidate = nativeContainer.findComponentAt (x, y);
   }
 
-  void trackMouseEnterExit(Component c, MouseEvent e)
+    if (mouseEventTarget != null
+        && mouseEventTarget != candidate)
   {
+        int nx = x - mouseEventTarget.getX ();
+        int ny = y - mouseEventTarget.getY ();
+        MouseEvent exited = new MouseEvent (mouseEventTarget, 
+                                            MouseEvent.MOUSE_EXITED,
+                                            me.getWhen (), 
+                                            me.getModifiers (), 
+                                            nx, ny,
+                                            me.getClickCount (),
+                                            me.isPopupTrigger (),
+                                            me.getButton ());
+        mouseEventTarget.dispatchEvent (exited); 
+        mouseEventTarget = null;
   }
 
-  void startListeningForOtherDrags()
+    if (candidate != null)
+	    {
+        // Possibly set new state.
+        if (candidate.isLightweight() 
+            && candidate != nativeContainer
+            && candidate != mouseEventTarget)
   {
+			
+            mouseEventTarget = candidate;
+			
+            int nx = x - mouseEventTarget.getX ();
+            int ny = y - mouseEventTarget.getY ();
+			
+            // If acquired, enter it.
+            MouseEvent entered = new MouseEvent (mouseEventTarget, 
+                                                 MouseEvent.MOUSE_ENTERED,
+                                                 me.getWhen (), 
+                                                 me.getModifiers (), 
+                                                 nx, ny,
+                                                 me.getClickCount (),
+                                                 me.isPopupTrigger (),
+                                                 me.getButton ());
+            mouseEventTarget.dispatchEvent (entered);
+          }
+	    }
   }
 
-  void stopListeningForOtherDrags()
+  boolean handleEvent (AWTEvent e)
   {
-  }
+    if ((eventMask & e.getID ()) == 0)
+	    return false;
 
-  public void eventDispatched(AWTEvent e)
+    if (e instanceof MouseEvent)
   {
-  }
+        MouseEvent me = (MouseEvent) e;
+        acquireComponentForMouseEvent (me);
 
-  void retargetMouseEvent(Component c, int i, MouseEvent e)
+        if (mouseEventTarget != null)
+          {
+            Component oldSource = (Component) me.getSource ();
+            me.setSource (mouseEventTarget);
+            mouseEventTarget.dispatchEvent (me);
+            me.setSource (oldSource);
+          }
+	    }
+    else if (e instanceof KeyEvent && focus != null)
   {
+        focus.processKeyEvent ((KeyEvent) e);
+	    }
+      
+    return e.isConsumed();
   }
+
 } // class LightweightDispatcher

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