KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > refactoring > ChangeTypeWizard


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.jdt.internal.ui.refactoring;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18
19 import org.eclipse.core.runtime.IProgressMonitor;
20 import org.eclipse.core.runtime.SubProgressMonitor;
21
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.graphics.Color;
24 import org.eclipse.swt.graphics.GC;
25 import org.eclipse.swt.graphics.Image;
26 import org.eclipse.swt.layout.GridData;
27 import org.eclipse.swt.layout.GridLayout;
28 import org.eclipse.swt.widgets.Composite;
29 import org.eclipse.swt.widgets.Display;
30 import org.eclipse.swt.widgets.Label;
31 import org.eclipse.swt.widgets.TreeItem;
32
33 import org.eclipse.jface.dialogs.Dialog;
34 import org.eclipse.jface.operation.IRunnableWithProgress;
35 import org.eclipse.jface.viewers.IColorProvider;
36 import org.eclipse.jface.viewers.ISelectionChangedListener;
37 import org.eclipse.jface.viewers.IStructuredSelection;
38 import org.eclipse.jface.viewers.LabelProviderChangedEvent;
39 import org.eclipse.jface.viewers.SelectionChangedEvent;
40 import org.eclipse.jface.viewers.TreeViewer;
41 import org.eclipse.jface.wizard.IWizardPage;
42
43 import org.eclipse.ui.PlatformUI;
44
45 import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
46 import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
47
48 import org.eclipse.jdt.core.dom.ITypeBinding;
49
50 import org.eclipse.jdt.internal.corext.refactoring.structure.ChangeTypeRefactoring;
51 import org.eclipse.jdt.internal.corext.util.Messages;
52
53 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
54 import org.eclipse.jdt.internal.ui.JavaPlugin;
55 import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
56
57
58 /**
59  * @author tip
60  */

61 public class ChangeTypeWizard extends RefactoringWizard {
62
63     private ChangeTypeRefactoring fCT;
64
65     public ChangeTypeWizard(ChangeTypeRefactoring ref) {
66         super(ref, DIALOG_BASED_USER_INTERFACE);
67         setDefaultPageTitle(RefactoringMessages.ChangeTypeWizard_title);
68         fCT= ref;
69     }
70
71     /* non java-doc
72      * @see RefactoringWizard#addUserInputPages
73      */

74     protected void addUserInputPages(){
75         addPage(new ChangeTypeInputPage());
76     }
77     
78     // For debugging
79
static String JavaDoc print(Collection JavaDoc/*<ITypeBinding>*/ types){
80         if (types.isEmpty())
81             return "{ }"; //$NON-NLS-1$
82
String JavaDoc result = "{ "; //$NON-NLS-1$
83
for (Iterator JavaDoc it=types.iterator(); it.hasNext(); ){
84             ITypeBinding type= (ITypeBinding)it.next();
85             result += type.getQualifiedName();
86             if (it.hasNext()){
87                 result += ", "; //$NON-NLS-1$
88
} else {
89                 result += " }"; //$NON-NLS-1$
90
}
91         }
92         return result;
93     }
94     
95     
96     /**
97      * A JavaElementLabelProvider that supports graying out of invalid types.
98      */

99     private class ChangeTypeLabelProvider extends BindingLabelProvider
100                                           implements IColorProvider {
101         
102         private Color fGrayColor;
103         private HashMap JavaDoc/*<Image color, Image gray>*/ fGrayImages;
104         
105         public ChangeTypeLabelProvider(){
106             fGrayColor= Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
107             fGrayImages= new HashMap JavaDoc();
108         }
109         
110         private Collection JavaDoc/*<ITypeBinding>*/ fInvalidTypes;
111         
112         public void grayOut(Collection JavaDoc/*<ITypeBinding>*/ invalidTypes){
113             fInvalidTypes= invalidTypes;
114             /*
115              * Invalidate all labels. Invalidating only invalid types doesn't
116              * work since there can be multiple nodes in the tree that
117              * correspond to the same invalid IType. The TreeViewer only updates
118              * the label of one of these ITypes and leaves the others in their
119              * old state.
120              */

121             fireLabelProviderChanged(new LabelProviderChangedEvent(this));
122         }
123
124         /* (non-Javadoc)
125          * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object)
126          */

127         public Color getForeground(Object JavaDoc element) {
128             if (isInvalid(element))
129                 return fGrayColor;
130             else
131                 return null;
132         }
133         
134         private boolean isInvalid(Object JavaDoc element) {
135             if (fInvalidTypes == null)
136                 return false; // initially, everything is enabled
137
else
138                 return fInvalidTypes.contains(element);
139         }
140         
141         /* (non-Javadoc)
142          * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object)
143          */

144         public Color getBackground(Object JavaDoc element) {
145             return null;
146         }
147         
148         /*
149          * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
150          */

151         public Image getImage(Object JavaDoc element) {
152             Image image= super.getImage(element);
153             if (isInvalid(element) && image != null) {
154                 Image grayImage= (Image) fGrayImages.get(image);
155                 if (grayImage == null) {
156                     grayImage= new Image(Display.getCurrent(), image, SWT.IMAGE_GRAY);
157                     fGrayImages.put(image, grayImage);
158                 }
159                 return grayImage;
160             } else {
161                 return image;
162             }
163         }
164         
165         public void dispose() {
166             for (Iterator JavaDoc iter= fGrayImages.values().iterator(); iter.hasNext();) {
167                 Image image= (Image) iter.next();
168                 image.dispose();
169             }
170             fGrayImages.clear();
171             super.dispose();
172         }
173     }
174     
175     private class ChangeTypeInputPage extends UserInputWizardPage{
176
177         public static final String JavaDoc PAGE_NAME= "ChangeTypeInputPage";//$NON-NLS-1$
178
private final String JavaDoc MESSAGE= RefactoringMessages.ChangeTypeInputPage_Select_Type;
179         private ChangeTypeLabelProvider fLabelProvider;
180         private TreeViewer fTreeViewer;
181         private boolean fTreeUpdated= false;
182         
183         public ChangeTypeInputPage() {
184             super(PAGE_NAME);
185             setMessage(MESSAGE);
186         }
187         
188         private class ValidTypesTask implements Runnable JavaDoc {
189             private Collection JavaDoc/*<ITypeBinding>*/ fInvalidTypes;
190             private Collection JavaDoc/*<ITypeBinding>*/ fValidTypes;
191             public void run() {
192                 IRunnableWithProgress runnable= new IRunnableWithProgress() {
193                     public void run(IProgressMonitor pm) {
194                         pm.beginTask(RefactoringMessages.ChangeTypeWizard_analyzing, 1000);
195                         ChangeTypeRefactoring ct= (ChangeTypeRefactoring)ChangeTypeWizard.this.getRefactoring();
196                         fInvalidTypes = new HashSet JavaDoc();
197                         fInvalidTypes.addAll(fCT.getAllSuperTypes(ct.getOriginalType()));
198                         fValidTypes= ct.computeValidTypes(new SubProgressMonitor(pm, 950));
199                         fInvalidTypes.add(ct.getOriginalType());
200                         fInvalidTypes.removeAll(fValidTypes);
201                         pm.worked(50);
202                         pm.done();
203                     }
204                 };
205                 boolean internalError= false;
206                 try {
207                     getWizard().getContainer().run(true, true, runnable);
208                 } catch (InvocationTargetException JavaDoc e) {
209                     internalError= true;
210                     JavaPlugin.log(e);
211                     ChangeTypeInputPage.this.setErrorMessage(RefactoringMessages.ChangeTypeWizard_internalError);
212                 } catch (InterruptedException JavaDoc e) {
213                     ChangeTypeInputPage.this.setMessage(RefactoringMessages.ChangeTypeWizard_computationInterrupted);
214                 }
215                                                     
216                 fLabelProvider.grayOut(fInvalidTypes);
217                 
218                 if (internalError) {
219                     setPageComplete(false);
220                 } else if (fValidTypes == null || fValidTypes.size() == 0){
221                     ChangeTypeInputPage.this.setErrorMessage(RefactoringMessages.ChangeTypeWizard_declCannotBeChanged);
222                     setPageComplete(false);
223                 } else {
224                     TreeItem selection= getInitialSelection(fValidTypes);
225                     fTreeViewer.getTree().setSelection(new TreeItem[]{ selection });
226                     setPageComplete(true);
227                     ChangeTypeInputPage.this.setMessage(""); //$NON-NLS-1$
228
}
229             }
230         }
231         
232         private TreeItem getInitialSelection(Collection JavaDoc/*<ITypeBinding>*/ types) {
233             
234             // first, find a most general valid type (there may be more than one)
235
ITypeBinding type= (ITypeBinding)types.iterator().next();
236             for (Iterator JavaDoc it= types.iterator(); it.hasNext(); ){
237                 ITypeBinding other= (ITypeBinding)it.next();
238                 if (getGeneralizeTypeRefactoring().isSubTypeOf(type, other)){
239                     type= other;
240                 }
241             }
242             
243             // now find a corresponding TreeItem (there may be more than one)
244
return findItem(fTreeViewer.getTree().getItems(), type);
245         }
246         
247         private TreeItem findItem(TreeItem[] items, ITypeBinding type){
248             for (int i=0; i < items.length; i++){
249                 if (items[i].getData().equals(type)) return items[i];
250             }
251             for (int i=0; i < items.length; i++){
252                 TreeItem item= findItem(items[i].getItems(), type);
253                 if (item != null) return item;
254             }
255             return null;
256         }
257         
258         
259         public void createControl(Composite parent) {
260             Composite composite= new Composite(parent, SWT.NONE);
261             setControl(composite);
262             composite.setLayout(new GridLayout());
263             composite.setLayoutData(new GridData());
264             
265             Label label= new Label(composite, SWT.NONE);
266             label.setText(Messages.format(
267                     RefactoringMessages.ChangeTypeWizard_pleaseChooseType,
268                     ((ChangeTypeRefactoring) getRefactoring()).getTarget()));
269             label.setLayoutData(new GridData());
270             
271             addTreeComponent(composite);
272             Dialog.applyDialogFont(composite);
273             PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaHelpContextIds.CHANGE_TYPE_WIZARD_PAGE);
274         }
275         
276         /**
277          * Tree-viewer that shows the allowable types in a tree view.
278          */

279         private void addTreeComponent(Composite parent) {
280             fTreeViewer= new TreeViewer(parent, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
281             GridData gd= new GridData(GridData.FILL_BOTH);
282             gd.grabExcessHorizontalSpace= true;
283             gd.grabExcessVerticalSpace= true;
284             GC gc= null;
285             try {
286                 gc= new GC(parent);
287                 gc.setFont(gc.getFont());
288                 gd.heightHint= Dialog.convertHeightInCharsToPixels(gc.getFontMetrics(), 6); // 6 characters tall
289
} finally {
290                 if (gc != null) {
291                     gc.dispose();
292                     gc= null;
293                 }
294             }
295             fTreeViewer.getTree().setLayoutData(gd);
296             
297             fTreeViewer.setContentProvider(new ChangeTypeContentProvider(((ChangeTypeRefactoring)getRefactoring())));
298             fLabelProvider= new ChangeTypeLabelProvider();
299             fTreeViewer.setLabelProvider(fLabelProvider);
300             ISelectionChangedListener listener= new ISelectionChangedListener(){
301                 public void selectionChanged(SelectionChangedEvent event) {
302                     IStructuredSelection selection= (IStructuredSelection)event.getSelection();
303                     typeSelected((ITypeBinding)selection.getFirstElement());
304                 }
305             };
306             fTreeViewer.addSelectionChangedListener(listener);
307             fTreeViewer.setInput(new ChangeTypeContentProvider.RootType(getGeneralizeTypeRefactoring().getOriginalType()));
308             fTreeViewer.expandToLevel(10);
309         }
310
311         private void typeSelected(ITypeBinding type) {
312             boolean isValid= getGeneralizeTypeRefactoring().getValidTypes().contains(type);
313             ChangeTypeInputPage.this.setPageComplete(isValid);
314             if (isValid) {
315                 ChangeTypeInputPage.this.setMessage(""); //$NON-NLS-1$
316
} else {
317                 if (getGeneralizeTypeRefactoring().getOriginalType().equals(type)) {
318                     ChangeTypeInputPage.this.setMessage(Messages.format(
319                         RefactoringMessages.ChangeTypeWizard_with_itself, type.getName()));
320                     
321                 } else {
322                     ChangeTypeInputPage.this.setMessage(Messages.format(
323                         RefactoringMessages.ChangeTypeWizard_grayed_types,
324                         new Object JavaDoc[] {type.getName(), getGeneralizeTypeRefactoring().getOriginalType().getName()}));
325                 }
326             }
327         }
328         
329         private ChangeTypeRefactoring getGeneralizeTypeRefactoring(){
330             return (ChangeTypeRefactoring)getRefactoring();
331         }
332         /*
333          * @see org.eclipse.jface.wizard.IWizardPage#getNextPage()
334          */

335         public IWizardPage getNextPage() {
336             initializeRefactoring();
337             return super.getNextPage();
338         }
339
340         private ITypeBinding getSelectedType() {
341             IStructuredSelection ss= (IStructuredSelection)fTreeViewer.getSelection();
342             return (ITypeBinding)ss.getFirstElement();
343         }
344
345         /*
346          * @see org.eclipse.jdt.internal.ui.refactoring.RefactoringWizardPage#performFinish()
347          */

348         public boolean performFinish(){
349             initializeRefactoring();
350             return super.performFinish();
351         }
352
353         private void initializeRefactoring() {
354             getGeneralizeTypeRefactoring().setSelectedType(getSelectedType());
355         }
356     
357         /*
358          * @see org.eclipse.jface.dialogs.IDialogPage#dispose()
359          */

360         public void dispose() {
361             fTreeViewer= null;
362             super.dispose();
363         }
364     
365         /* (non-Javadoc)
366          * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
367          */

368         public void setVisible(boolean visible) {
369             super.setVisible(visible);
370             if (visible && fTreeViewer != null)
371                 fTreeViewer.getTree().setFocus();
372                 if (!fTreeUpdated){
373                     fTreeViewer.getTree().getDisplay().asyncExec(new ValidTypesTask());
374                     fTreeUpdated= true;
375                 }
376         }
377     }
378 }
379
Popular Tags