KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > forms > DetailsPart


1 /*******************************************************************************
2  * Copyright (c) 2000, 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 package org.eclipse.ui.forms;
12
13 import java.util.Enumeration JavaDoc;
14 import java.util.Hashtable JavaDoc;
15 import java.util.Iterator JavaDoc;
16
17 import org.eclipse.jface.viewers.*;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.custom.BusyIndicator;
20 import org.eclipse.swt.widgets.*;
21 import org.eclipse.ui.forms.widgets.ScrolledPageBook;
22 /**
23  * This managed form part handles the 'details' portion of the
24  * 'master/details' block. It has a page book that manages pages
25  * of details registered for the current selection.
26  * <p>By default, details part accepts any number of pages.
27  * If dynamic page provider is registered, this number may
28  * be excessive. To avoid running out of steam (by creating
29  * a large number of pages with widgets on each), maximum
30  * number of pages can be set to some reasonable value (e.g. 10).
31  * When this number is reached, old pages (those created first)
32  * will be removed and disposed as new ones are added. If
33  * the disposed pages are needed again after that, they
34  * will be created again.
35  *
36  * @since 3.0
37  */

38 public final class DetailsPart implements IFormPart, IPartSelectionListener {
39     private IManagedForm managedForm;
40     private ScrolledPageBook pageBook;
41     private IFormPart masterPart;
42     private IStructuredSelection currentSelection;
43     private Hashtable JavaDoc pages;
44     private IDetailsPageProvider pageProvider;
45     private int pageLimit=Integer.MAX_VALUE;
46     
47     private static class PageBag {
48         private static int counter;
49         private int ticket;
50         private IDetailsPage page;
51         private boolean fixed;
52         
53         public PageBag(IDetailsPage page, boolean fixed) {
54             this.page= page;
55             this.fixed = fixed;
56             this.ticket = ++counter;
57         }
58         public int getTicket() {
59             return ticket;
60         }
61         public IDetailsPage getPage() {
62             return page;
63         }
64         public void dispose() {
65             page.dispose();
66             page=null;
67         }
68         public boolean isDisposed() {
69             return page==null;
70         }
71         public boolean isFixed() {
72             return fixed;
73         }
74         public static int getCurrentTicket() {
75             return counter;
76         }
77     }
78 /**
79  * Creates a details part by wrapping the provided page book.
80  * @param mform the parent form
81  * @param pageBook the page book to wrap
82  */

83     public DetailsPart(IManagedForm mform, ScrolledPageBook pageBook) {
84         this.pageBook = pageBook;
85         pages = new Hashtable JavaDoc();
86         initialize(mform);
87     }
88 /**
89  * Creates a new details part in the provided form by creating
90  * the page book.
91  * @param mform the parent form
92  * @param parent the composite to create the page book in
93  * @param style the style for the page book
94  */

95     public DetailsPart(IManagedForm mform, Composite parent, int style) {
96         this(mform, mform.getToolkit().createPageBook(parent, style|SWT.V_SCROLL|SWT.H_SCROLL));
97     }
98 /**
99  * Registers the details page to be used for all the objects of
100  * the provided object class.
101  * @param objectClass an object of type 'java.lang.Class' to be used
102  * as a key for the provided page
103  * @param page the page to show for objects of the provided object class
104  */

105     public void registerPage(Object JavaDoc objectClass, IDetailsPage page) {
106         registerPage(objectClass, page, true);
107     }
108     
109     private void registerPage(Object JavaDoc objectClass, IDetailsPage page, boolean fixed) {
110         pages.put(objectClass, new PageBag(page, fixed));
111         page.initialize(managedForm);
112     }
113 /**
114  * Sets the dynamic page provider. The dynamic provider can return
115  * different pages for objects of the same class based on their state.
116  * @param provider the provider to use
117  */

118     public void setPageProvider(IDetailsPageProvider provider) {
119         this.pageProvider = provider;
120     }
121 /**
122  * Commits the part by committing the current page.
123  * @param onSave <code>true</code> if commit is requested as a result
124  * of the 'save' action, <code>false</code> otherwise.
125  */

126     public void commit(boolean onSave) {
127         IDetailsPage page = getCurrentPage();
128         if (page != null)
129             page.commit(onSave);
130     }
131 /**
132  * Returns the current page visible in the part.
133  * @return the current page
134  */

135     public IDetailsPage getCurrentPage() {
136         Control control = pageBook.getCurrentPage();
137         if (control != null) {
138             Object JavaDoc data = control.getData();
139             if (data instanceof IDetailsPage)
140                 return (IDetailsPage) data;
141         }
142         return null;
143     }
144     /*
145      * (non-Javadoc)
146      *
147      * @see org.eclipse.ui.forms.IFormPart#dispose()
148      */

149     public void dispose() {
150         for (Enumeration JavaDoc enm = pages.elements(); enm.hasMoreElements();) {
151             PageBag pageBag = (PageBag) enm.nextElement();
152             pageBag.dispose();
153         }
154     }
155     /*
156      * (non-Javadoc)
157      *
158      * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
159      */

160     public void initialize(IManagedForm form) {
161         this.managedForm = form;
162     }
163 /**
164  * Tests if the currently visible page is dirty.
165  * @return <code>true</code> if the page is dirty, <code>false</code> otherwise.
166  */

167     public boolean isDirty() {
168         IDetailsPage page = getCurrentPage();
169         if (page != null)
170             return page.isDirty();
171         return false;
172     }
173 /**
174  * Tests if the currently visible page is stale and needs refreshing.
175  * @return <code>true</code> if the page is stale, <code>false</code> otherwise.
176  */

177     public boolean isStale() {
178         IDetailsPage page = getCurrentPage();
179         if (page != null)
180             return page.isStale();
181         return false;
182     }
183
184 /**
185  * Refreshes the current page.
186  */

187     public void refresh() {
188         IDetailsPage page = getCurrentPage();
189         if (page != null)
190             page.refresh();
191     }
192 /**
193  * Sets the focus to the currently visible page.
194  */

195     public void setFocus() {
196         IDetailsPage page = getCurrentPage();
197         if (page != null)
198             page.setFocus();
199     }
200     /*
201      * (non-Javadoc)
202      *
203      * @see org.eclipse.ui.forms.IFormPart#setFormInput(java.lang.Object)
204      */

205     public boolean setFormInput(Object JavaDoc input) {
206         return false;
207     }
208     /*
209      * (non-Javadoc)
210      *
211      * @see org.eclipse.ui.forms.IPartSelectionListener#selectionChanged(org.eclipse.ui.forms.IFormPart,
212      * org.eclipse.jface.viewers.ISelection)
213      */

214     public void selectionChanged(IFormPart part, ISelection selection) {
215         this.masterPart = part;
216         if (currentSelection != null) {
217         }
218         if (selection instanceof IStructuredSelection)
219             currentSelection = (IStructuredSelection) selection;
220         else
221             currentSelection = null;
222         update();
223     }
224     private void update() {
225         Object JavaDoc key = null;
226         if (currentSelection != null) {
227             for (Iterator JavaDoc iter = currentSelection.iterator(); iter.hasNext();) {
228                 Object JavaDoc obj = iter.next();
229                 if (key == null)
230                     key = getKey(obj);
231                 else if (getKey(obj).equals(key) == false) {
232                     key = null;
233                     break;
234                 }
235             }
236         }
237         showPage(key);
238     }
239     private Object JavaDoc getKey(Object JavaDoc object) {
240         if (pageProvider!=null) {
241             Object JavaDoc key = pageProvider.getPageKey(object);
242             if (key!=null)
243                 return key;
244         }
245         return object.getClass();
246     }
247     private void showPage(final Object JavaDoc key) {
248         checkLimit();
249         final IDetailsPage oldPage = getCurrentPage();
250         if (key != null) {
251             PageBag pageBag = (PageBag)pages.get(key);
252             IDetailsPage page = pageBag!=null?pageBag.getPage():null;
253             if (page==null) {
254                 // try to get the page dynamically from the provider
255
if (pageProvider!=null) {
256                     page = pageProvider.getPage(key);
257                     if (page!=null) {
258                         registerPage(key, page, false);
259                     }
260                 }
261             }
262             if (page != null) {
263                 final IDetailsPage fpage = page;
264                 BusyIndicator.showWhile(pageBook.getDisplay(), new Runnable JavaDoc() {
265                     public void run() {
266                         if (!pageBook.hasPage(key)) {
267                             Composite parent = pageBook.createPage(key);
268                             fpage.createContents(parent);
269                             parent.setData(fpage);
270                         }
271                         //commit the current page
272
if (oldPage!=null && oldPage.isDirty())
273                             oldPage.commit(false);
274                         //refresh the new page
275
if (fpage.isStale())
276                             fpage.refresh();
277                         fpage.selectionChanged(masterPart, currentSelection);
278                         pageBook.showPage(key);
279                     }
280                 });
281                 return;
282             }
283         }
284         // If we are switching from an old page to nothing,
285
// don't loose data
286
if (oldPage!=null && oldPage.isDirty())
287             oldPage.commit(false);
288         pageBook.showEmptyPage();
289     }
290     private void checkLimit() {
291         if (pages.size() <= getPageLimit()) return;
292         // overflow
293
int currentTicket = PageBag.getCurrentTicket();
294         int cutoffTicket = currentTicket - getPageLimit();
295         for (Enumeration JavaDoc enm=pages.keys(); enm.hasMoreElements();) {
296             Object JavaDoc key = enm.nextElement();
297             PageBag pageBag = (PageBag)pages.get(key);
298             if (pageBag.getTicket()<=cutoffTicket) {
299                 // candidate - see if it is active and not fixed
300
if (!pageBag.isFixed() && !pageBag.getPage().equals(getCurrentPage())) {
301                     // drop it
302
pageBag.dispose();
303                     pages.remove(key);
304                     pageBook.removePage(key, false);
305                 }
306             }
307         }
308     }
309     /**
310      * Returns the maximum number of pages that should be
311      * maintained in this part. When an attempt is made to
312      * add more pages, old pages are removed and disposed
313      * based on the order of creation (the oldest pages
314      * are removed). The exception is made for the
315      * page that should otherwise be disposed but is
316      * currently active.
317      * @return maximum number of pages for this part
318      */

319     public int getPageLimit() {
320         return pageLimit;
321     }
322     /**
323      * Sets the page limit for this part.
324      * @see #getPageLimit()
325      * @param pageLimit the maximum number of pages that
326      * should be maintained in this part.
327      */

328     public void setPageLimit(int pageLimit) {
329         this.pageLimit = pageLimit;
330         checkLimit();
331     }
332 }
333
Popular Tags