KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > forms > widgets > SharedScrolledComposite


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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 package org.eclipse.ui.forms.widgets;
12
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.custom.ScrolledComposite;
15 import org.eclipse.swt.graphics.Color;
16 import org.eclipse.swt.graphics.Font;
17 import org.eclipse.swt.graphics.Point;
18 import org.eclipse.swt.graphics.Rectangle;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.Control;
21 import org.eclipse.swt.widgets.Event;
22 import org.eclipse.swt.widgets.Listener;
23 import org.eclipse.swt.widgets.ScrollBar;
24 import org.eclipse.ui.internal.forms.widgets.FormUtil;
25
26 /**
27  * This class is used to provide common scrolling services to a number of
28  * controls in the toolkit. Classes that extend it are not required to implement
29  * any method.
30  *
31  * @since 3.0
32  */

33 public abstract class SharedScrolledComposite extends ScrolledComposite {
34     private static final int H_SCROLL_INCREMENT = 5;
35
36     private static final int V_SCROLL_INCREMENT = 64;
37     
38     private boolean ignoreLayouts = true;
39
40     private boolean ignoreResizes = false;
41
42     private boolean expandHorizontal = false;
43
44     private boolean expandVertical = false;
45
46     private SizeCache contentCache = new SizeCache();
47
48     private boolean reflowPending = false;
49
50     private boolean delayedReflow = true;
51     
52     /**
53      * Creates the new instance.
54      *
55      * @param parent
56      * the parent composite
57      * @param style
58      * the style to use
59      */

60     public SharedScrolledComposite(Composite parent, int style) {
61         super(parent, style);
62         addListener(SWT.Resize, new Listener() {
63             public void handleEvent(Event e) {
64                 if (!ignoreResizes) {
65                     scheduleReflow(false);
66                 }
67             }
68         });
69         initializeScrollBars();
70     }
71
72     /**
73      * Sets the foreground of the control and its content.
74      *
75      * @param fg
76      * the new foreground color
77      */

78     public void setForeground(Color fg) {
79         super.setForeground(fg);
80         if (getContent() != null)
81             getContent().setForeground(fg);
82     }
83
84     /**
85      * Sets the background of the control and its content.
86      *
87      * @param bg
88      * the new background color
89      */

90     public void setBackground(Color bg) {
91         super.setBackground(bg);
92         if (getContent() != null)
93             getContent().setBackground(bg);
94     }
95
96     /**
97      * Sets the font of the form. This font will be used to render the title
98      * text. It will not affect the body.
99      */

100     public void setFont(Font font) {
101         super.setFont(font);
102         if (getContent() != null)
103             getContent().setFont(font);
104     }
105
106     /**
107      * Overrides 'super' to pass the proper colors and font
108      */

109     public void setContent(Control content) {
110         super.setContent(content);
111         if (content != null) {
112             content.setForeground(getForeground());
113             content.setBackground(getBackground());
114             content.setFont(getFont());
115         }
116     }
117
118     /**
119      * If content is set, transfers focus to the content.
120      */

121     public boolean setFocus() {
122         boolean result;
123         FormUtil.setFocusScrollingEnabled(this, false);
124         if (getContent() != null)
125             result = getContent().setFocus();
126         else
127             result = super.setFocus();
128         FormUtil.setFocusScrollingEnabled(this, true);
129         return result;
130     }
131
132     /*
133      * (non-Javadoc)
134      *
135      * @see org.eclipse.swt.widgets.Composite#layout(boolean)
136      */

137     public void layout(boolean changed) {
138         if (ignoreLayouts) {
139             return;
140         }
141
142         ignoreLayouts = true;
143         ignoreResizes = true;
144         super.layout(changed);
145         ignoreResizes = false;
146     }
147
148     /*
149      * (non-Javadoc)
150      *
151      * @see org.eclipse.swt.custom.ScrolledComposite#setExpandHorizontal(boolean)
152      */

153     public void setExpandHorizontal(boolean expand) {
154         expandHorizontal = expand;
155         super.setExpandHorizontal(expand);
156     }
157
158     /*
159      * (non-Javadoc)
160      *
161      * @see org.eclipse.swt.custom.ScrolledComposite#setExpandVertical(boolean)
162      */

163     public void setExpandVertical(boolean expand) {
164         expandVertical = expand;
165         super.setExpandVertical(expand);
166     }
167
168     /**
169      * Recomputes the body layout and the scroll bars. The method should be used
170      * when changes somewhere in the form body invalidate the current layout
171      * and/or scroll bars.
172      *
173      * @param flushCache
174      * if <code>true</code>, drop the cached data
175      */

176     public void reflow(boolean flushCache) {
177         Composite c = (Composite) getContent();
178         Rectangle clientArea = getClientArea();
179         if (c == null)
180             return;
181
182         contentCache.setControl(c);
183         if (flushCache) {
184             contentCache.flush();
185         }
186         setRedraw(false);
187         Point newSize = contentCache.computeSize(FormUtil.getWidthHint(
188                 clientArea.width, c), FormUtil.getHeightHint(clientArea.height,
189                 c));
190
191         // Point currentSize = c.getSize();
192
if (!(expandHorizontal && expandVertical)) {
193             c.setSize(newSize);
194         }
195
196         setMinSize(newSize);
197         FormUtil.updatePageIncrement(this);
198
199         ignoreLayouts = false;
200         layout(flushCache);
201         ignoreLayouts = true;
202
203         contentCache.layoutIfNecessary();
204         setRedraw(true);
205     }
206
207     private void updateSizeWhilePending() {
208         Control c = getContent();
209         Rectangle area = getClientArea();
210         setMinSize(area.width, c.getSize().y);
211     }
212
213     private void scheduleReflow(final boolean flushCache) {
214         if (delayedReflow) {
215             if (reflowPending) {
216                 updateSizeWhilePending();
217                 return;
218             }
219             getDisplay().asyncExec(new Runnable JavaDoc() {
220                 public void run() {
221                     if (!isDisposed())
222                         reflow(flushCache);
223                     reflowPending = false;
224                 }
225             });
226             reflowPending = true;
227         } else
228             reflow(flushCache);
229     }
230
231     private void initializeScrollBars() {
232         ScrollBar hbar = getHorizontalBar();
233         if (hbar != null) {
234             hbar.setIncrement(H_SCROLL_INCREMENT);
235         }
236         ScrollBar vbar = getVerticalBar();
237         if (vbar != null) {
238             vbar.setIncrement(V_SCROLL_INCREMENT);
239         }
240         FormUtil.updatePageIncrement(this);
241     }
242
243     /**
244      * Tests if the control uses delayed reflow.
245      * @return <code>true</code> if reflow requests will
246      * be delayed, <code>false</code> otherwise.
247      */

248     public boolean isDelayedReflow() {
249         return delayedReflow;
250     }
251
252     /**
253      * Sets the delayed reflow feature. When used,
254      * it will schedule a reflow on resize requests
255      * and reject subsequent reflows until the
256      * scheduled one is performed. This improves
257      * performance by
258      * @param delayedReflow
259      * The delayedReflow to set.
260      */

261     public void setDelayedReflow(boolean delayedReflow) {
262         this.delayedReflow = delayedReflow;
263     }
264 }
265
Popular Tags