[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[albireo-dev] CleanResizeListener

I've added a listener (from the SAS contribution) that improves the look during window resizing. The listener paints the SWT background for the brief period before the embedded AWT frame repaints. It's needed because we use the sun.awt.noerasebackground property to reduce flicker. Because the property only applies to Windows, the listener is only installed on Windows.
### Eclipse Workspace Patch 1.0
#P org.eclipse.albireo.core
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.9
diff -u -r1.9 SwingControl.java
--- src/org/eclipse/albireo/core/SwingControl.java	27 Jan 2008 01:28:16 -0000	1.9
+++ src/org/eclipse/albireo/core/SwingControl.java	27 Jan 2008 01:50:14 -0000
@@ -20,6 +20,7 @@
 import javax.swing.JComponent;
 import javax.swing.RootPaneContainer;
 
+import org.eclipse.albireo.internal.Platform;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.SWTException;
 import org.eclipse.swt.awt.SWT_AWT;
@@ -79,6 +80,12 @@
         super(parent, style | SWT.EMBEDDED | SWT.NO_BACKGROUND);
         setLayout(new FillLayout());
         display = getDisplay();
+        
+        // This listener clears garbage during resizing, making it looker much cleaner. The garbage
+        // is due to use of the sun.awt.noerasebackground property, so this is done only under Windows. 
+        if (Platform.isWin32()) {
+            addControlListener(new CleanResizeListener());
+        }
     }
 
     // ========================================================================
@@ -122,6 +129,7 @@
         AwtEnvironment.getInstance(display);
         
         frame = SWT_AWT.new_Frame(this);
+        
     }
 
     protected void scheduleComponentCreation() {
Index: src/org/eclipse/albireo/core/CleanResizeListener.java
===================================================================
RCS file: src/org/eclipse/albireo/core/CleanResizeListener.java
diff -N src/org/eclipse/albireo/core/CleanResizeListener.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/albireo/core/CleanResizeListener.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2008 SAS Institute Inc., ILOG S.A.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     SAS Institute Inc. - initial API and implementation
+ *     ILOG S.A. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.albireo.core;
+
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+public class CleanResizeListener extends ControlAdapter {
+    private Rectangle oldRect = null;
+    public void controlResized(ControlEvent e) {
+        assert e != null;
+        assert Display.getCurrent() != null;     // On SWT event thread
+        
+        // Prevent garbage from Swing lags during resize. Fill exposed areas 
+        // with background color. 
+        Composite composite = (Composite)e.widget;
+        Rectangle newRect = composite.getClientArea();
+        if (oldRect != null) {
+            int heightDelta = newRect.height - oldRect.height;
+            int widthDelta = newRect.width - oldRect.width;
+            if ((heightDelta > 0) || (widthDelta > 0)) {
+                GC gc = new GC(composite);
+                try {
+                    gc.fillRectangle(newRect.x, oldRect.height, newRect.width, heightDelta);
+                    gc.fillRectangle(oldRect.width, newRect.y, widthDelta, newRect.height);
+                } finally {
+                    gc.dispose();
+                }
+            }
+        }
+        oldRect = newRect;
+    }
+}