Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[albireo-dev] avoiding layout flickering

Hi Gordon,

The RelayoutExample shows a flickering effect that comes from SWT Layout:
The SWT panel containing the SwingControl relayouts itself after the latter
has determined its size, and the SwingControl's contents also relayouts itself
once initially. Buttons and labels are shifted around. It makes it look
unprofessional.

I've found a method setLayoutDeferred(), which does the trick. It requires
to generalize the preferredSizeChanged() method; I'm replacing it with a
getLayoutableAncestor() method.

Do you think this should be customizable (ability to turn off), or is the
result now always satisfactory?

Bruno


Index: src/org/eclipse/albireo/core/SwingControl.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.core/src/org/eclipse/albireo/core/SwingControl.java,v
retrieving revision 1.31
diff -c -3 -r1.31 SwingControl.java
*** src/org/eclipse/albireo/core/SwingControl.java	13 Feb 2008 20:01:18 -0000	1.31
--- src/org/eclipse/albireo/core/SwingControl.java	13 Feb 2008 21:11:22 -0000
***************
*** 59,64 ****
--- 59,65 ----
          }
      };
      private Display display;
+     private Composite layoutDeferredAncestor;
  
      private Frame frame;
      private RootPaneContainer rootPaneContainer;
***************
*** 106,111 ****
--- 107,128 ----
  
          display.addListener(SWT.Settings, settingsListener);
  
+         // Avoid a layout() on the outer Controls until we have been able to
+         // determine our preferred size - which takes a roundtrip to the AWT
+         // thread and back.
+         layoutDeferredAncestor = getLayoutableAncestor();
+         if (layoutDeferredAncestor != null) {
+             layoutDeferredAncestor.setLayoutDeferred(true);
+             // Ensure populate() is called nevertheless.
+             ThreadingHandler.getInstance().asyncExec(
+                 display,
+                 new Runnable() {
+                     public void run() {
+                         populate();
+                     }
+                 });
+         }
+ 
          // Clean up on dispose
          addListener(SWT.Dispose, new Listener() {
              public void handleEvent(Event event) {
***************
*** 191,196 ****
--- 208,220 ----
                          display,
                          new Runnable() {
                              public void run() {
+                                 // Now that the preferred size is known, enable
+                                 // the layout on the layoutable ancestor.
+                                 if (layoutDeferredAncestor != null) {
+                                     layoutDeferredAncestor.layout();
+                                     layoutDeferredAncestor.setLayoutDeferred(false);
+                                 }
+                                 // Invoke hooks, for use by the application.
                                  afterComponentCreatedSWTThread();
                              }
                          });
***************
*** 579,584 ****
--- 603,619 ----
      }
  
      /**
+      * Returns the uppermost parent of this control that is influenced by size
+      * changes of this control. It is usually on this ancestor control that
+      * you want to call <code>layout()</code> when the preferred size of this
+      * control has changed.
+      * @return the parent, grandparent, or other ancestor of this control, or
+      *         <code>null</code>
+      * @see #preferredSizeChanged(Point, Point, Point)
+      */
+     public abstract Composite getLayoutableAncestor();
+ 
+     /**
       * Called when the preferred sizes of this control, as computed by
       * {@link #computeSize(int, int, boolean)}, have changed. This method
       * should change the size of this SWT control and of other SWT controls
***************
*** 590,597 ****
       * You should implement this method, usually by calling
       * <code>layout()</code> on the uppermost parent of this control that
       * is influenced by size changes of this control. Usually this is done
!      * through a call <code>getParent().layout()</code>, or
!      * <code>getParent().getParent().layout()</code>, or similar.
       * <p>
       * The parameters <var>minPoint</var>, <var>prefPoint</var>,
       * <var>maxPoint</var> can usually be ignored: It is enough to rely on the
--- 625,633 ----
       * You should implement this method, usually by calling
       * <code>layout()</code> on the uppermost parent of this control that
       * is influenced by size changes of this control. Usually this is done
!      * through a call <code>getLayoutableAncestor().layout()</code>.
!      * The default implementation calls
!      * <code>getLayoutableAncestor().layout()</code>.
       * <p>
       * The parameters <var>minPoint</var>, <var>prefPoint</var>,
       * <var>maxPoint</var> can usually be ignored: It is enough to rely on the
***************
*** 600,606 ****
       * @param prefSize The new preferred size for this control, as reported by AWT.
       * @param maxSize The new maximum size for this control, as reported by AWT.
       */
!     public abstract void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize);
  
      // This is called by the layout when it assigns a size and position to this
      // Control.
--- 636,646 ----
       * @param prefSize The new preferred size for this control, as reported by AWT.
       * @param maxSize The new maximum size for this control, as reported by AWT.
       */
!     public void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
!         Composite ancestor = getLayoutableAncestor();
!         if (ancestor != null)
!             ancestor.layout();
!     }
  
      // This is called by the layout when it assigns a size and position to this
      // Control.
Index: src/org/eclipse/albireo/examples/plugin/views/EmbeddedJTableView.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.examples.plugin/src/org/eclipse/albireo/examples/plugin/views/EmbeddedJTableView.java,v
retrieving revision 1.7
diff -c -3 -r1.7 EmbeddedJTableView.java
*** src/org/eclipse/albireo/examples/plugin/views/EmbeddedJTableView.java	12 Feb 2008 14:08:23 -0000	1.7
--- src/org/eclipse/albireo/examples/plugin/views/EmbeddedJTableView.java	13 Feb 2008 21:11:36 -0000
***************
*** 9,15 ****
  
  import org.eclipse.albireo.core.SwingControl;
  import org.eclipse.swt.SWT;
- import org.eclipse.swt.graphics.Point;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.Display;
  import org.eclipse.ui.PlatformUI;
--- 9,14 ----
***************
*** 53,60 ****
                  return scrollPane;
              }
  
!             public void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
!                 parent.layout();
              }
              
          };
--- 52,59 ----
                  return scrollPane;
              }
  
!             public Composite getLayoutableAncestor() {
!                 return parent;
              }
              
          };
Index: src/org/eclipse/albireo/examples/plugin/views/EventLoggerView.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.examples.plugin/src/org/eclipse/albireo/examples/plugin/views/EventLoggerView.java,v
retrieving revision 1.5
diff -c -3 -r1.5 EventLoggerView.java
*** src/org/eclipse/albireo/examples/plugin/views/EventLoggerView.java	12 Feb 2008 14:08:23 -0000	1.5
--- src/org/eclipse/albireo/examples/plugin/views/EventLoggerView.java	13 Feb 2008 21:11:36 -0000
***************
*** 26,32 ****
  
  import org.eclipse.albireo.core.SwingControl;
  import org.eclipse.swt.SWT;
- import org.eclipse.swt.graphics.Point;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.ui.part.ViewPart;
  
--- 26,31 ----
***************
*** 60,67 ****
                  }
              }
  
!             public void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
!                 parent.layout();
              }
          };
          
--- 59,66 ----
                  }
              }
  
!             public Composite getLayoutableAncestor() {
!                 return parent;
              }
          };
          
Index: src/org/eclipse/albireo/examples/plugin/views/GridLayoutView.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.examples.plugin/src/org/eclipse/albireo/examples/plugin/views/GridLayoutView.java,v
retrieving revision 1.5
diff -c -3 -r1.5 GridLayoutView.java
*** src/org/eclipse/albireo/examples/plugin/views/GridLayoutView.java	12 Feb 2008 14:08:23 -0000	1.5
--- src/org/eclipse/albireo/examples/plugin/views/GridLayoutView.java	13 Feb 2008 21:11:36 -0000
***************
*** 12,18 ****
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.events.SelectionEvent;
  import org.eclipse.swt.events.SelectionListener;
- import org.eclipse.swt.graphics.Point;
  import org.eclipse.swt.layout.GridData;
  import org.eclipse.swt.layout.GridLayout;
  import org.eclipse.swt.widgets.Button;
--- 12,17 ----
***************
*** 59,66 ****
              return new JButton(text);
          }
  
!         public void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
!             getParent().layout();
          }
      }
  
--- 58,65 ----
              return new JButton(text);
          }
  
!         public Composite getLayoutableAncestor() {
!             return getParent();
          }
      }
  
***************
*** 103,110 ****
              return scrollPane;
          }
  
!         public void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
!             getParent().layout();
          }
      }
      
--- 102,109 ----
              return scrollPane;
          }
  
!         public Composite getLayoutableAncestor() {
!             return getParent();
          }
      }
      
Index: src/org/eclipse/albireo/examples/plugin/views/RelayoutExampleView.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.examples.plugin/src/org/eclipse/albireo/examples/plugin/views/RelayoutExampleView.java,v
retrieving revision 1.9
diff -c -3 -r1.9 RelayoutExampleView.java
*** src/org/eclipse/albireo/examples/plugin/views/RelayoutExampleView.java	12 Feb 2008 14:08:23 -0000	1.9
--- src/org/eclipse/albireo/examples/plugin/views/RelayoutExampleView.java	13 Feb 2008 21:11:36 -0000
***************
*** 16,22 ****
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.events.SelectionEvent;
  import org.eclipse.swt.events.SelectionListener;
- import org.eclipse.swt.graphics.Point;
  import org.eclipse.swt.layout.GridData;
  import org.eclipse.swt.layout.GridLayout;
  import org.eclipse.swt.widgets.Button;
--- 16,21 ----
***************
*** 75,82 ****
                  addSwingWidgets();
                  return panel;
              }
!             public void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
!                 composite.layout();
              }
          };
          data = new GridData();
--- 74,81 ----
                  addSwingWidgets();
                  return panel;
              }
!             public Composite getLayoutableAncestor() {
!                 return composite;
              }
          };
          data = new GridData();
Index: src/org/eclipse/albireo/examples/plugin/views/SWTBug58308.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.examples.plugin/src/org/eclipse/albireo/examples/plugin/views/SWTBug58308.java,v
retrieving revision 1.5
diff -c -3 -r1.5 SWTBug58308.java
*** src/org/eclipse/albireo/examples/plugin/views/SWTBug58308.java	12 Feb 2008 14:08:23 -0000	1.5
--- src/org/eclipse/albireo/examples/plugin/views/SWTBug58308.java	13 Feb 2008 21:11:37 -0000
***************
*** 11,17 ****
  import org.eclipse.albireo.core.SwingControl;
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.awt.SWT_AWT;
- import org.eclipse.swt.graphics.Point;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.Control;
  import org.eclipse.ui.part.ViewPart;
--- 11,16 ----
***************
*** 53,60 ****
                      protected JComponent createSwingComponent() {
                          return button;
                      }
!                     public void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
!                         parent.layout();
                      }
                  };
          }
--- 52,59 ----
                      protected JComponent createSwingComponent() {
                          return button;
                      }
!                     public Composite getLayoutableAncestor() {
!                         return parent;
                      }
                  };
          }
Index: src/org/eclipse/albireo/examples/plugin/views/SwingSetView.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.examples.plugin/src/org/eclipse/albireo/examples/plugin/views/SwingSetView.java,v
retrieving revision 1.4
diff -c -3 -r1.4 SwingSetView.java
*** src/org/eclipse/albireo/examples/plugin/views/SwingSetView.java	12 Feb 2008 14:08:23 -0000	1.4
--- src/org/eclipse/albireo/examples/plugin/views/SwingSetView.java	13 Feb 2008 21:11:37 -0000
***************
*** 13,19 ****
  import org.eclipse.albireo.core.SwingControl;
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.custom.ScrolledComposite;
- import org.eclipse.swt.graphics.Point;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.FileDialog;
  import org.eclipse.ui.PlatformUI;
--- 13,18 ----
***************
*** 83,90 ****
                  return null;
              }
  
!             public void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
                  // Size is fixed within scrolled composite
              }
          };
          
--- 82,90 ----
                  return null;
              }
  
!             public Composite getLayoutableAncestor() {
                  // Size is fixed within scrolled composite
+                 return null;
              }
          };
          
Index: src/org/eclipse/albireo/examples/plugin/views/TestResizeView.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.examples.plugin/src/org/eclipse/albireo/examples/plugin/views/TestResizeView.java,v
retrieving revision 1.3
diff -c -3 -r1.3 TestResizeView.java
*** src/org/eclipse/albireo/examples/plugin/views/TestResizeView.java	12 Feb 2008 14:08:23 -0000	1.3
--- src/org/eclipse/albireo/examples/plugin/views/TestResizeView.java	13 Feb 2008 21:11:37 -0000
***************
*** 92,99 ****
                              c.addMouseListener(listener);
                              c.addMouseMotionListener(listener);
                          }
!                         public void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
!                             parent.layout();
                          }
                      };
              }
--- 92,99 ----
                              c.addMouseListener(listener);
                              c.addMouseMotionListener(listener);
                          }
!                         public Composite getLayoutableAncestor() {
!                             return parent;
                          }
                      };
              }
Index: src/org/eclipse/albireo/examples/plugin/views/TestScreenCoordinatesView.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.examples.plugin/src/org/eclipse/albireo/examples/plugin/views/TestScreenCoordinatesView.java,v
retrieving revision 1.4
diff -c -3 -r1.4 TestScreenCoordinatesView.java
*** src/org/eclipse/albireo/examples/plugin/views/TestScreenCoordinatesView.java	12 Feb 2008 14:08:23 -0000	1.4
--- src/org/eclipse/albireo/examples/plugin/views/TestScreenCoordinatesView.java	13 Feb 2008 21:11:37 -0000
***************
*** 22,28 ****
  
  import org.eclipse.albireo.core.SwingControl;
  import org.eclipse.swt.SWT;
- import org.eclipse.swt.graphics.Point;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.ui.part.ViewPart;
  
--- 22,27 ----
***************
*** 217,224 ****
                  return entirePanel;
              }
  
!             public void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
!                 parent.layout();
              }
          };
      }
--- 216,223 ----
                  return entirePanel;
              }
  
!             public Composite getLayoutableAncestor() {
!                 return parent;
              }
          };
      }
Index: src/org/eclipse/albireo/examples/plugin/views/ZooView.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.examples.plugin/src/org/eclipse/albireo/examples/plugin/views/ZooView.java,v
retrieving revision 1.4
diff -c -3 -r1.4 ZooView.java
*** src/org/eclipse/albireo/examples/plugin/views/ZooView.java	12 Feb 2008 14:08:23 -0000	1.4
--- src/org/eclipse/albireo/examples/plugin/views/ZooView.java	13 Feb 2008 21:11:37 -0000
***************
*** 91,100 ****
                  }
                  return scrollable;
              }
!             public void preferredSizeChanged(org.eclipse.swt.graphics.Point minSize,
!                                              org.eclipse.swt.graphics.Point prefSize,
!                                              org.eclipse.swt.graphics.Point maxSize) {
!                 parent.layout();
              }
          };
      }
--- 91,98 ----
                  }
                  return scrollable;
              }
!             public Composite getLayoutableAncestor() {
!                 return parent;
              }
          };
      }


Back to the top