KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > layout > CacheWrapper


1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.ui.internal.layout;
13
14 import org.eclipse.swt.SWT;
15 import org.eclipse.swt.graphics.Point;
16 import org.eclipse.swt.graphics.Rectangle;
17 import org.eclipse.swt.widgets.Composite;
18 import org.eclipse.swt.widgets.Control;
19 import org.eclipse.swt.widgets.Layout;
20
21 /**
22  * This class wraps a control with a complex computeSize method. It uses caching
23  * to reduce the number of times the control's computeSize method is called. This
24  * allows controls (such as Coolbars and wrapping text) with slow computeSize
25  * operations to be used inside layouts and composites that use inefficient caching.
26  * <p>
27  * For example, you want to use Coolbar A inside composite B. Rather than making A
28  * a direct child of B, place it inside a CacheWrapper and insert the CacheWrapper
29  * into B. Any layout data that would normally be attached to the control itself
30  * should be attached to the wrapper instead:
31  * </p>
32  * <code>
33  *
34  * // Unoptimized code
35  * Toolbar myToolbar = new Toolbar(someParent, SWT.WRAP);
36  * myToolbar.setLayoutData(someLayoutData);
37  * </code>
38  * <code>
39  *
40  * // Optimized code
41  * CacheWrapper myWrapper = new CacheWrapper(someParent);
42  * Toolbar myToolbar = new Toolbar(myWrapper.getControl(), SWT.WRAP);
43  * myWrapper.getControl().setLayoutData(someLayoutData);
44  * </code>
45  * <p>
46  * CacheWrapper creates a Composite which should have exactly one child: the control
47  * whose size should be cached. Note that CacheWrapper does NOT respect the flushCache
48  * argument to layout() and computeSize(). This is intentional, since the whole point of
49  * this class is to workaround layouts with poor caching, and such layouts will typically
50  * be too eager about flushing the caches of their children. However, this means that you
51  * MUST manually call flushCache() whenver the child's preferred size changes (and before
52  * the parent is layed out).
53  * </p>
54  *
55  * @since 3.0
56  */

57 public class CacheWrapper {
58     private Composite proxy;
59
60     private SizeCache cache = new SizeCache();
61
62     private Rectangle lastBounds = new Rectangle(0, 0, 0, 0);
63
64     private class WrapperLayout extends Layout implements ICachingLayout {
65         protected Point computeSize(Composite composite, int wHint, int hHint,
66                 boolean flushCache) {
67             Control[] children = composite.getChildren();
68             if (children.length != 1) {
69                 return new Point(0, 0);
70             }
71
72             cache.setControl(children[0]);
73
74             return cache.computeSize(wHint, hHint);
75         }
76
77         protected void layout(Composite composite, boolean flushCache) {
78             Control[] children = composite.getChildren();
79             if (children.length != 1) {
80                 return;
81             }
82
83             Control child = children[0];
84             Rectangle newBounds = composite.getClientArea();
85             if (!newBounds.equals(lastBounds)) {
86                 child.setBounds(newBounds);
87                 lastBounds = newBounds;
88             }
89
90         }
91
92         /* (non-Javadoc)
93          * @see org.eclipse.ui.internal.layout.ICachingLayout#flush(org.eclipse.swt.widgets.Control)
94          */

95         public void flush(Control dirtyControl) {
96             CacheWrapper.this.flushCache();
97         }
98     }
99
100     /**
101      * Creates a <code>CacheWrapper</code> with the given parent
102      *
103      * @param parent
104      */

105     public CacheWrapper(Composite parent) {
106         proxy = new Composite(parent, SWT.NONE);
107
108         proxy.setLayout(new WrapperLayout());
109     }
110
111     /**
112      * Flush the cache. Call this when the child has changed in order to force
113      * the size to be recomputed in the next resize event.
114      */

115     public void flushCache() {
116         cache.flush();
117     }
118
119     /**
120      * Use this as the parent of the real control.
121      *
122      * @return the proxy contol. It should be given exactly one child.
123      */

124     public Composite getControl() {
125         return proxy;
126     }
127
128     /**
129      * Dispose of any widgets created by this wrapper.
130      */

131     public void dispose() {
132         if (proxy != null) {
133             proxy.dispose();
134             proxy = null;
135         }
136     }
137 }
138
Popular Tags