Revision: 1269
Author:   mathiasbr
Date:     2006-08-05 13:11:52 -0700 (Sat, 05 Aug 2006)
ViewCVS:  http://svn.sourceforge.net/spring-rich-c/?rev=1269&view=rev

Log Message:
-----------
rollback of revision 1226 and a new fix for RCP-216
updating the overlay is now executed asynchronously to prevent a race condition.
again thanks a lot to Benoit Xhenseval!

ViewCVS Links:
-------------
    http://svn.sourceforge.net/spring-rich-c/?rev=1226&view=rev

Modified Paths:
--------------
    
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/DirtyIndicatorInterceptor.java
    
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/OverlayValidationInterceptorFactory.java
    
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/util/OverlayHelper.java
Modified: 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/DirtyIndicatorInterceptor.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/DirtyIndicatorInterceptor.java
    2006-08-05 07:06:41 UTC (rev 1268)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/DirtyIndicatorInterceptor.java
    2006-08-05 20:11:52 UTC (rev 1269)
@@ -97,9 +97,7 @@
                     }
                 });
 
-        JComponent overlayControl = overlay.getControl();
-        InterceptorOverlayHelper.attachOverlay(overlayControl, component, 
OverlayHelper.NORTH_WEST, overlayControl
-                .getPreferredSize().height / 2, 0);
+        InterceptorOverlayHelper.attachOverlay(overlay.getControl(), 
component, OverlayHelper.NORTH_WEST, 5, 0);
         overlay.setVisible(false);
     }
 

Modified: 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/OverlayValidationInterceptorFactory.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/OverlayValidationInterceptorFactory.java
  2006-08-05 07:06:41 UTC (rev 1268)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/OverlayValidationInterceptorFactory.java
  2006-08-05 20:11:52 UTC (rev 1269)
@@ -36,10 +36,11 @@
 import org.springframework.richclient.util.OverlayHelper;
 
 /**
- * Adds an "overlay" to a component that is triggered by a validation event. 
The overlaid image is retrieved by the
- * image key "severity.{severityShortCode}.overlay", where {severityShortCode} 
is the number returned by
- * [EMAIL PROTECTED] Severity#getShortCode()}. The image is placed at the 
bottom-left corner of the component, and the image's
- * tooltip is set to the validation message.
+ * Adds an "overlay" to a component that is triggered by a validation event. 
The overlaid
+ * image is retrieved by the image key "severity.{severityShortCode}.overlay", 
where
+ * {severityShortCode} is the number returned by [EMAIL PROTECTED] 
Severity#getShortCode()}. The
+ * image is placed at the bottom-left corner of the component, and the image's 
tooltip is
+ * set to the validation message.
  * 
  * @author Oliver Hutchison
  * @see OverlayHelper#attachOverlay
@@ -52,30 +53,26 @@
         textCompHeight = new JTextField().getPreferredSize().height;
     }
 
-    public FormComponentInterceptor getInterceptor(FormModel formModel) {
+    public FormComponentInterceptor getInterceptor( FormModel formModel ) {
         return new OverlayValidationInterceptor(formModel);
     }
 
     public class OverlayValidationInterceptor extends ValidationInterceptor {
 
-        public OverlayValidationInterceptor(FormModel formModel) {
+        public OverlayValidationInterceptor( FormModel formModel ) {
             super(formModel);
         }
 
-        public void processComponent(String propertyName, final JComponent 
component) {
+        public void processComponent( String propertyName, final JComponent 
component ) {
             final ErrorReportingOverlay overlay = new ErrorReportingOverlay();
 
-            if (component.getName() == null) {
-                component.setName(propertyName);
-            }
-
             registerGuarded(propertyName, overlay);
             registerMessageReceiver(propertyName, overlay);
 
-            if (component.getParent() == null) {
+            if( component.getParent() == null ) {
                 PropertyChangeListener waitUntilHasParentListener = new 
PropertyChangeListener() {
-                    public void propertyChange(PropertyChangeEvent e) {
-                        if (component.getParent() != null) {
+                    public void propertyChange( PropertyChangeEvent e ) {
+                        if( component.getParent() != null ) {
                             component.removePropertyChangeListener("ancestor", 
this);
                             attachOverlay(overlay, component);
                         }
@@ -87,9 +84,10 @@
             }
         }
 
-        private void attachOverlay(ErrorReportingOverlay overlay, JComponent 
component) {
+        private void attachOverlay( ErrorReportingOverlay overlay, JComponent 
component ) {
             int yOffset = component.getPreferredSize().height;
-            InterceptorOverlayHelper.attachOverlay(overlay, component, 
SwingConstants.SOUTH_WEST, 0, 0);
+            InterceptorOverlayHelper.attachOverlay(overlay, component, 
SwingConstants.NORTH_WEST, 0, Math.min(yOffset,
+                    textCompHeight));
         }
     }
 
@@ -100,17 +98,17 @@
             return true;
         }
 
-        public void setEnabled(final boolean enabled) {
+        public void setEnabled( boolean enabled ) {
             setVisible(!enabled);
         }
 
-        public void setMessage(Message message) {
+        public void setMessage( Message message ) {
             messageBuffer.setMessage(message);
             message = messageBuffer.getMessage();
             setToolTipText(message.getText());
             Severity severity = message.getSeverity();
 
-            if (severity != null) {
+            if( severity != null ) {
                 IconSource iconSource = (IconSource) 
ApplicationServicesLocator.services().getService(IconSource.class);
                 setIcon(iconSource.getIcon("severity." + severity.getLabel() + 
".overlay"));
             } else {

Modified: 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/util/OverlayHelper.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/util/OverlayHelper.java
        2006-08-05 07:06:41 UTC (rev 1268)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/util/OverlayHelper.java
        2006-08-05 20:11:52 UTC (rev 1269)
@@ -33,8 +33,9 @@
 import javax.swing.JLayeredPane;
 import javax.swing.JRootPane;
 import javax.swing.JViewport;
-import javax.swing.Scrollable;
 import javax.swing.SwingConstants;
+import javax.swing.Scrollable;
+import javax.swing.SwingUtilities;
 
 /**
  * A helper class that attaches one component (the overlay) on top of another
@@ -43,6 +44,7 @@
  * @author oliverh
  */
 public class OverlayHelper implements SwingConstants {
+
     private static final String LAYERED_PANE_PROPERTY = "overlayLayeredPane";
 
     private final OverlayTargetChangeHandler overlayTargetChangeHandler = new 
OverlayTargetChangeHandler();
@@ -59,8 +61,10 @@
 
     private final int yOffset;
 
-    private boolean isUpdating;
+    boolean isUpdating;
 
+    private Runnable overlayUpdater = new OverlayUpdater();
+
     /**
      * Attaches an overlay to the specified component.
      * 
@@ -94,7 +98,7 @@
         installListeners();
     }
 
-    private final class OverlayChangeHandler implements ComponentListener, 
PropertyChangeListener {
+    final class OverlayChangeHandler implements ComponentListener, 
PropertyChangeListener {
         public void componentHidden(ComponentEvent e) {
             hideOverlay();
         }
@@ -119,7 +123,7 @@
         }
     }
 
-    private class OverlayTargetChangeHandler implements HierarchyListener, 
HierarchyBoundsListener, ComponentListener {
+    class OverlayTargetChangeHandler implements HierarchyListener, 
HierarchyBoundsListener, ComponentListener {
         public void hierarchyChanged(HierarchyEvent e) {
             updateOverlay();
         }
@@ -157,31 +161,17 @@
         overlay.addPropertyChangeListener(overlayChangeHandler);
     }
 
-    private void updateOverlay() {
+    void updateOverlay() {
         if (isUpdating) {
             return;
         }
-        try {
-            isUpdating = true;
-            Container overlayCapableParent = 
getOverlayCapableParent(overlayTarget);
-            if (overlayCapableParent != null) {
-                JLayeredPane layeredPane = 
getLayeredPane(overlayCapableParent);
-                if (overlay.getParent() == null || overlay.getParent() != 
layeredPane) {
-                    putOverlay(layeredPane);
-                }
-            }
-            if (overlayCapableParent == null || !overlayTarget.isShowing() || 
!overlay.isVisible()) {
-                hideOverlay();
-            } else {
-                positionOverlay(overlayCapableParent);
-            }
-        }
-        finally {
-            isUpdating = false;
-        }
+        isUpdating = true;
+        // updating the overlay at the end of the event queue to avoid race 
conditions 
+        // see RCP-126 
(http://opensource.atlassian.com/projects/spring/browse/RCP-216)
+        SwingUtilities.invokeLater(overlayUpdater);
     }
 
-    private void putOverlay(final JLayeredPane layeredPane) {
+    void putOverlay(final JLayeredPane layeredPane) {
         if (overlay.getParent() != layeredPane) {
             JComponent parent = (JComponent)overlay.getParent();
             if (parent != null) {
@@ -192,26 +182,27 @@
         }
     }
 
-    private void positionOverlay(Container overlayCapableParent) {
-        Point position = determineComponentLocation(overlayTarget, 
overlayCapableParent);
-        Rectangle targetBounds = overlayTarget.getBounds();
-        Dimension overlayBounds = overlay.getPreferredSize();
-        int tlx = xOffset + position.x - overlayBounds.width / 2;
-        int tly = yOffset + position.y - overlayBounds.height / 2;;
+    void positionOverlay(JLayeredPane layeredPane) {
+        Point layOffset = layeredPane.getLocationOnScreen();
+        Point targetOffset = overlayTarget.getParent().getLocationOnScreen();
+        int centerX = xOffset + (targetOffset.x - layOffset.x);
+        int centerY = yOffset + (targetOffset.y - layOffset.y);
+        Rectangle overlayTargetBounds = overlayTarget.getBounds();
         switch (center) {
         case SwingConstants.NORTH:
         case SwingConstants.NORTH_WEST:
         case SwingConstants.NORTH_EAST:
+            centerY += overlayTargetBounds.y;
             break;
         case SwingConstants.CENTER:
         case SwingConstants.EAST:
         case SwingConstants.WEST:
-            tly += targetBounds.height / 2;
+            centerY += overlayTargetBounds.y + (overlayTargetBounds.height / 
2);
             break;
         case SwingConstants.SOUTH:
         case SwingConstants.SOUTH_EAST:
         case SwingConstants.SOUTH_WEST:
-            tly += targetBounds.height;
+            centerY += overlayTargetBounds.y + overlayTargetBounds.height;
             break;
         default:
             throw new IllegalArgumentException("Unknown value for center [" + 
center + "]");
@@ -220,50 +211,34 @@
         case SwingConstants.WEST:
         case SwingConstants.NORTH_WEST:
         case SwingConstants.SOUTH_WEST:
+            centerX += overlayTargetBounds.x;
             break;
         case SwingConstants.CENTER:
         case SwingConstants.NORTH:
         case SwingConstants.SOUTH:
-            tlx += targetBounds.width / 2;
+            centerX += overlayTargetBounds.x + (overlayTargetBounds.width / 2);
             break;
         case SwingConstants.EAST:
         case SwingConstants.NORTH_EAST:
         case SwingConstants.SOUTH_EAST:
-            tlx += targetBounds.width;
+            centerX += overlayTargetBounds.x + overlayTargetBounds.width;
             break;
         default:
             throw new IllegalArgumentException("Unknown value for center [" + 
center + "]");
         }
         Dimension size = overlay.getPreferredSize();
-        Rectangle newBound = new Rectangle(tlx, tly, size.width, size.height);
+        Rectangle newBound = new Rectangle(centerX - (size.width / 2), centerY 
- (size.height / 2), size.width,
+                                           size.height);
         setOverlayBounds(newBound);
     }
 
-    /**
-     * Determine the location of a component in the given container.
-     * The component must be in the component tree of the container
-     * 
-     * @param parent
-     * @param component
-     * @return
-     */
-    private Point determineComponentLocation(Component component, Container 
parent) {
-        Point location = component.getLocation();
-        if(component.getParent() == parent) {
-            return location;
-        }
-        Point parentLocation = 
determineComponentLocation(component.getParent(), parent);
-        location.translate(parentLocation.x, parentLocation.y);
-        return location;
-    }
-
-    private void setOverlayBounds(Rectangle newBounds) {        
+    private void setOverlayBounds(Rectangle newBounds) {
         if (!newBounds.equals(overlay.getBounds())) {
             overlay.setBounds(newBounds);
         }
     }
 
-    private void hideOverlay() {
+    void hideOverlay() {
         setOverlayBounds(new Rectangle(0, 0, 0, 0));
     }
 
@@ -377,4 +352,25 @@
             return this.scrollableDelegate.getScrollableTracksViewportHeight();
         }
     }
+
+    class OverlayUpdater implements Runnable {
+        public void run() {
+            try {
+                Container overlayCapableParent = 
getOverlayCapableParent(overlayTarget);
+                if (overlayCapableParent == null || !overlayTarget.isShowing() 
|| !overlay.isVisible()) {
+                    hideOverlay();
+                }
+                else {
+                    JLayeredPane layeredPane = 
getLayeredPane(overlayCapableParent);
+                    if( layeredPane.isVisible() && layeredPane.isShowing() ) {
+                        putOverlay(layeredPane);
+                        positionOverlay(layeredPane);
+                    }
+                }
+            }
+            finally {
+                isUpdating = false;
+            }
+        }
+    }
 }
\ No newline at end of file


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
spring-rich-c-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spring-rich-c-cvs

Reply via email to