KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > refactoring > spi > impl > RefactoringPanel


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.refactoring.spi.impl;
20
21 import java.awt.*;
22 import java.awt.event.ActionEvent JavaDoc;
23 import java.awt.event.ActionListener JavaDoc;
24 import java.lang.ref.WeakReference JavaDoc;
25 import java.util.*;
26 import java.util.Collection JavaDoc;
27 import javax.swing.*;
28 import javax.swing.ImageIcon JavaDoc;
29 import javax.swing.border.EmptyBorder JavaDoc;
30 import javax.swing.text.Position JavaDoc;
31 import javax.swing.tree.DefaultTreeModel JavaDoc;
32 import javax.swing.tree.TreePath JavaDoc;
33 import org.netbeans.api.progress.ProgressHandle;
34 import org.netbeans.api.progress.ProgressHandleFactory;
35 import org.netbeans.api.project.*;
36 import org.netbeans.modules.refactoring.api.*;
37 import org.netbeans.modules.refactoring.api.impl.APIAccessor;
38 import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
39 import org.netbeans.modules.refactoring.spi.ui.RefactoringCustomUI;
40 import org.netbeans.modules.refactoring.spi.ui.RefactoringUI;
41 import org.netbeans.modules.refactoring.spi.ui.TreeElement;
42 import org.netbeans.modules.refactoring.spi.ui.TreeElementFactory;
43 import org.netbeans.modules.refactoring.spi.ui.TreeElementFactoryImplementation;
44 import org.openide.DialogDescriptor;
45 import org.openide.DialogDisplayer;
46 import org.openide.ErrorManager;
47 import org.openide.LifecycleManager;
48 import org.openide.text.CloneableEditorSupport;
49 import org.openide.text.PositionBounds;
50 import org.openide.util.Lookup;
51 import org.openide.util.NbBundle;
52 import org.openide.util.RequestProcessor;
53 import org.openide.util.Utilities;
54 import org.openide.windows.TopComponent;
55
56 /**
57  * Panel for showing proposed changes (refactoring elements) of any refactoring.
58  *
59  * @author Pavel Flaska, Martin Matula
60  */

61 public class RefactoringPanel extends JPanel implements InvalidationListener {
62     
63     // PRIVATE FIELDS
64
/* tree contains elements which will be changed by refactoring action */
65     private transient JTree tree = null;
66     /* toolbar button causing refresh of the data */
67     private transient JButton refreshButton = null;
68     /* button lying in the toolbar allows expansion of all nodes in a tree */
69     private transient JToggleButton expandButton = null;
70     private JToolBar toolBar = null;
71
72     private transient JButton refactorButton = null;
73     private transient JButton cancelButton = null;
74     private transient ButtonL buttonListener = null;
75     private transient JButton rerunButton = null;
76
77     private final RefactoringUI ui;
78     private final boolean isQuery;
79     
80     private transient boolean isVisible = false;
81     private transient RefactoringSession session = null;
82     private transient ParametersPanel parametersPanel = null;
83     private transient JScrollPane scrollPane = null;
84     private transient JPanel southPanel;
85     public JSplitPane splitPane;
86     private JPanel left;
87     private Action callback = null;
88     
89     private static final int MAX_ROWS = 50;
90     
91     private transient JToggleButton logicalViewButton = null;
92     private transient JToggleButton physicalViewButton = null;
93     private transient JToggleButton customViewButton = null;
94     private transient ProgressListener progressListener;
95
96     private transient JButton prevMatch = null;
97     private transient JButton nextMatch = null;
98     private WeakReference JavaDoc refCallerTC;
99     private boolean inited = false;
100
101     
102     static Image PACKAGE_BADGE = Utilities.loadImage( "org/netbeans/spi/java/project/support/ui/packageBadge.gif" ); // NOI18N
103

104     public RefactoringPanel(RefactoringUI ui) {
105         this(ui,null);
106     }
107     
108     public RefactoringPanel(RefactoringUI ui, TopComponent caller) {
109         if (caller!=null)
110             refCallerTC = new WeakReference JavaDoc(caller);
111         this.ui = ui;
112         this.isQuery = ui.isQuery();
113         refresh(true);
114     }
115     
116     public RefactoringPanel(RefactoringUI ui, RefactoringSession session, Action callback) {
117         this.session = session;
118         this.ui = ui;
119         this.isQuery = ui.isQuery();
120         this.callback = callback;
121         initialize();
122         refresh(false);
123     }
124     
125     public static void checkEventThread() {
126         if (!SwingUtilities.isEventDispatchThread()) {
127             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, new IllegalStateException JavaDoc("This must happen in event thread!")); //NOI18N
128
}
129     }
130     
131     /* initializes all the ui */
132     private void initialize() {
133         if (inited)
134             return ;
135         checkEventThread();
136         setFocusCycleRoot(true);
137         splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
138         left = new JPanel();
139         splitPane.setLeftComponent(left);
140         left.setLayout(new BorderLayout());
141         setLayout(new BorderLayout());
142         add(splitPane, BorderLayout.CENTER);
143         if (!isQuery) {
144             splitPane.setRightComponent(new JLabel("<Preview not Available>", SwingConstants.CENTER));
145         }
146         // add panel with buttons
147
JButton[] buttons = getButtons();
148         //if (buttons.length != 0) {
149
// there will be at least one button on panel
150
southPanel = new JPanel(new GridBagLayout());
151             for (int i = 0; i < buttons.length; i++) {
152                 GridBagConstraints c = new GridBagConstraints();
153                 c.gridy = 0;
154                 c.insets = new Insets(5, 5, 5, 0);
155                 southPanel.add(buttons[i], c);
156             }
157             JPanel pp = new JPanel(new BorderLayout());
158             GridBagConstraints c = new GridBagConstraints();
159             c.gridy = 0;
160             c.insets = new Insets(5, 5, 5, 5);
161             c.weightx = 1;
162             c.fill = c.HORIZONTAL;
163             southPanel.add(pp, c);
164             
165             if (!isQuery|| callback != null) {
166                 left.add(southPanel, BorderLayout.SOUTH);
167             }
168         //}
169
// put the toolbar to the panel. If the getToolBar() returns null,
170
// suppose the toolbar does not exist.
171
JToolBar toolBar = getToolBar();
172         if (toolBar != null)
173             left.add(toolBar, BorderLayout.WEST);
174         validate();
175         inited=true;
176     }
177
178     /**
179      * Returns the toolbar. In this default implementation, toolbar is
180      * oriented vertically in the west and contains 'expand tree' toggle
181      * button and refresh button.
182      * Override this method and return null if you do not want toolbar
183      * in your panel.
184      *
185      * @return toolBar with actions for refactoring panel
186      */

187     private JToolBar getToolBar() {
188         checkEventThread();
189         refreshButton = new JButton(
190             new ImageIcon JavaDoc(Utilities.loadImage(
191             "org/netbeans/modules/refactoring/api/resources/refresh.png")) // NOI18N
192
);
193         Dimension dim = new Dimension(24, 24);
194         refreshButton.setMaximumSize(dim);
195         refreshButton.setMinimumSize(dim);
196         refreshButton.setPreferredSize(dim);
197         refreshButton.setToolTipText(
198             NbBundle.getMessage(RefactoringPanel.class, "HINT_refresh") // NOI18N
199
);
200         refreshButton.setMnemonic(
201             NbBundle.getMessage(RefactoringPanel.class, "MNEM_refresh").charAt(0)
202         );
203         refreshButton.addActionListener(getButtonListener());
204         // expand button settings
205
expandButton = new JToggleButton(
206             new ImageIcon JavaDoc(Utilities.loadImage(
207             "org/netbeans/modules/refactoring/api/resources/expandTree.png")) // NOI18N
208
);
209         expandButton.setSelectedIcon(
210             new ImageIcon JavaDoc(Utilities.loadImage(
211             "org/netbeans/modules/refactoring/api/resources/colapseTree.png")) // NOI18N
212
);
213         expandButton.setMaximumSize(dim);
214         expandButton.setMinimumSize(dim);
215         expandButton.setPreferredSize(dim);
216         expandButton.setSelected(true);
217         expandButton.setToolTipText(
218             NbBundle.getMessage(RefactoringPanel.class, "HINT_expandAll") // NOI18N
219
);
220         expandButton.setMnemonic(
221             NbBundle.getMessage(RefactoringPanel.class, "MNEM_expandAll").charAt(0) // NOI18N
222
);
223         expandButton.addActionListener(getButtonListener());
224         // create toolbar
225
toolBar = new JToolBar(JToolBar.VERTICAL);
226         toolBar.setFloatable(false);
227         
228         logicalViewButton = new JToggleButton(
229             new ImageIcon JavaDoc(Utilities.loadImage(
230             "org/netbeans/modules/refactoring/api/resources/logical_view.png")) // NOI18N
231
);
232         
233         logicalViewButton.setMaximumSize(dim);
234         logicalViewButton.setMinimumSize(dim);
235         logicalViewButton.setPreferredSize(dim);
236         logicalViewButton.setSelected(currentView==LOGICAL);
237         logicalViewButton.setToolTipText(
238             NbBundle.getMessage(RefactoringPanel.class, "HINT_logicalView") // NOI18N
239
);
240         logicalViewButton.setMnemonic(
241             NbBundle.getMessage(RefactoringPanel.class, "MNEM_logicalView").charAt(0) // NOI18N
242
);
243         logicalViewButton.addActionListener(getButtonListener());
244
245         physicalViewButton = new JToggleButton(
246             new ImageIcon JavaDoc(Utilities.loadImage(
247             "org/netbeans/modules/refactoring/api/resources/file_view.png")) // NOI18N
248
);
249         
250         physicalViewButton.setMaximumSize(dim);
251         physicalViewButton.setMinimumSize(dim);
252         physicalViewButton.setPreferredSize(dim);
253         physicalViewButton.setSelected(currentView==PHYSICAL);
254         physicalViewButton.setToolTipText(
255             NbBundle.getMessage(RefactoringPanel.class, "HINT_physicalView") // NOI18N
256
);
257         physicalViewButton.setMnemonic(
258             NbBundle.getMessage(RefactoringPanel.class, "MNEM_physicalView").charAt(0) // NOI18N
259
);
260         physicalViewButton.addActionListener(getButtonListener());
261
262         
263         if (ui instanceof RefactoringCustomUI) {
264             customViewButton = new JToggleButton(((RefactoringCustomUI)ui).getCustomIcon());
265             customViewButton.setMaximumSize(dim);
266             customViewButton.setMinimumSize(dim);
267             customViewButton.setPreferredSize(dim);
268             customViewButton.setSelected(currentView==GRAPHICAL);
269             customViewButton.setToolTipText(((RefactoringCustomUI)ui).getCustomToolTip());
270             customViewButton.addActionListener(getButtonListener());
271         }
272         
273         nextMatch = new JButton(
274             new ImageIcon JavaDoc(Utilities.loadImage(
275             "org/netbeans/modules/refactoring/api/resources/nextmatch.png")) // NOI18N
276
);
277         
278         nextMatch.setMaximumSize(dim);
279         nextMatch.setMinimumSize(dim);
280         nextMatch.setPreferredSize(dim);
281         nextMatch.setToolTipText(
282             NbBundle.getMessage(RefactoringPanel.class, "HINT_nextMatch") // NOI18N
283
);
284         nextMatch.addActionListener(getButtonListener());
285
286         prevMatch = new JButton(
287             new ImageIcon JavaDoc(Utilities.loadImage(
288             "org/netbeans/modules/refactoring/api/resources/prevmatch.png")) // NOI18N
289
);
290         
291         prevMatch.setMaximumSize(dim);
292         prevMatch.setMinimumSize(dim);
293         prevMatch.setPreferredSize(dim);
294         prevMatch.setToolTipText(
295             NbBundle.getMessage(RefactoringPanel.class, "HINT_prevMatch") // NOI18N
296
);
297         prevMatch.addActionListener(getButtonListener());
298         
299         toolBar.add(refreshButton);
300         toolBar.add(expandButton);
301         toolBar.add(logicalViewButton);
302         toolBar.add(physicalViewButton);
303         if (ui instanceof RefactoringCustomUI) {
304             toolBar.add(customViewButton);
305         }
306         toolBar.add(prevMatch);
307         toolBar.add(nextMatch);
308         
309         return toolBar;
310     }
311     
312     /**
313      * Returns array of available buttons. Initially, it returns only
314      * basic "do refactoring/cancel refactoring" button. Override this method,
315      * if you want to provide any other buttons with different action to be
316      * performed.
317      *
318      * @return array of avasilable buttons.
319      */

320     private JButton[] getButtons() {
321         checkEventThread();
322         if (isQuery) {
323             refactorButton = null;
324             if (callback==null) {
325                 return new JButton[] {};
326             } else {
327                 rerunButton = new JButton((String JavaDoc) callback.getValue(callback.NAME)); // NOI18N
328
rerunButton.addActionListener(getButtonListener());
329                 return new JButton[] {rerunButton};
330             }
331         } else {
332             refactorButton = new JButton(NbBundle.getMessage(RefactoringPanel.class, "LBL_DoRefactor")); // NOI18N
333
refactorButton.setToolTipText(NbBundle.getMessage(RefactoringPanel.class, "HINT_DoRefactor")); // NOI18N
334
refactorButton.setMnemonic(NbBundle.getMessage(RefactoringPanel.class, "MNEM_DoRefactor").charAt(0));
335             refactorButton.addActionListener(getButtonListener());
336             cancelButton = new JButton(NbBundle.getMessage(RefactoringPanel.class, "LBL_CancelRefactor")); // NOI18N
337
cancelButton.setMnemonic(NbBundle.getMessage(RefactoringPanel.class, "MNEM_CancelRefactor").charAt(0));
338             cancelButton.setToolTipText(NbBundle.getMessage(RefactoringPanel.class, "HINT_CancelRefactor")); // NOI18N
339
cancelButton.addActionListener(getButtonListener());
340             return new JButton[] {refactorButton, cancelButton};
341         }
342     }
343     
344     private static final byte LOGICAL = 0;
345     private static final byte PHYSICAL = 1;
346     private static final byte GRAPHICAL = 2;
347     
348     private byte currentView = PHYSICAL;
349
350     void switchToLogicalView() {
351         logicalViewButton.setSelected(true);
352         if (currentView == LOGICAL)
353             return ;
354         currentView = LOGICAL;
355         physicalViewButton.setSelected(false);
356         if (customViewButton!=null) {
357             customViewButton.setSelected(false);
358             prevMatch.setEnabled(true);
359             nextMatch.setEnabled(true);
360             expandButton.setEnabled(true);
361         }
362         refresh(false);
363     }
364     
365     void switchToPhysicalView() {
366         physicalViewButton.setSelected(true);
367         if (currentView == PHYSICAL)
368             return ;
369         currentView = PHYSICAL;
370         logicalViewButton.setSelected(false);
371         if (customViewButton!=null) {
372             customViewButton.setSelected(false);
373             prevMatch.setEnabled(true);
374             nextMatch.setEnabled(true);
375             expandButton.setEnabled(true);
376         }
377         refresh(false);
378     }
379
380     void switchToCustomView() {
381         customViewButton.setSelected(true);
382         if (currentView == GRAPHICAL)
383             return ;
384         currentView = GRAPHICAL;
385         logicalViewButton.setSelected(false);
386         physicalViewButton.setSelected(false);
387         prevMatch.setEnabled(false);
388         nextMatch.setEnabled(false);
389         expandButton.setEnabled(false);
390         refresh(false);
391     }
392     
393     private CheckNode createNode(TreeElement representedObject, HashMap nodes, CheckNode root) {
394         //checkEventThread();
395
boolean isLogical = currentView == LOGICAL;
396         
397         CheckNode node = null;
398         if (representedObject instanceof SourceGroup) {
399             //workaround for issue 52541
400
node = (CheckNode) nodes.get(((SourceGroup) representedObject).getRootFolder());
401         } else {
402             node = (CheckNode) nodes.get(representedObject);
403         }
404         if (node != null) {
405             return node;
406         }
407         
408         TreeElement parent = representedObject.getParent(isLogical);
409         String JavaDoc displayName = representedObject.getText(isLogical);
410         Icon JavaDoc icon = representedObject.getIcon();
411         
412         boolean cannotEnable = false;
413         
414         node = new CheckNode(representedObject, displayName, icon);
415         if (cannotEnable)
416             node.setDisabled();
417         CheckNode parentNode = parent == null ? root : createNode(parent, nodes, root);
418         parentNode.add(node);
419         
420         if (representedObject instanceof SourceGroup) {
421             //workaround for issue 52541
422
nodes.put(((SourceGroup) representedObject).getRootFolder(), node);
423         } else {
424             nodes.put(representedObject, node);
425         }
426         return node;
427     }
428     
429     private static final String JavaDoc getString(String JavaDoc key) {
430         return NbBundle.getMessage(RefactoringPanel.class, key);
431     }
432
433     /**
434      * Overrides default ExplorerPanel behaviour. Does nothing now.
435      */

436     protected void updateTitle() {
437     }
438     
439     /**
440      * Method is responsible for making changes in sources.
441      */

442     private void refactor() {
443         checkEventThread();
444         disableComponents(RefactoringPanel.this);
445         progressListener = new ProgressL();
446         RequestProcessor.getDefault().post(new Runnable JavaDoc() {
447             public void run() {
448                 try {
449                     session.addProgressListener(progressListener);
450                     session.doRefactoring(true);
451                 } finally {
452                     session.removeProgressListener(progressListener);
453                     progressListener = null;
454                     SwingUtilities.invokeLater(new Runnable JavaDoc() {
455                         public void run() {
456                             RefactoringPanel.this.close();
457                         }
458                     });
459                 }
460             }
461         });
462     }
463
464     /**
465      * Cancel refactor action. This default implementation is closing window
466      * only. It can return result state. In this implementation it returns
467      * everytime 0.
468      *
469      * @return result of cancel operation. Zero represent successful cancel.
470      */

471     private int cancel() {
472         checkEventThread();
473         this.close();
474         return 0;
475     }
476     
477     void close() {
478         if (isQuery) {
479             RefactoringPanelContainer.getUsagesComponent().removePanel(this);
480         } else {
481             RefactoringPanelContainer.getRefactoringComponent().removePanel(this);
482         }
483         closeNotify();
484     }
485     
486     
487     /*
488      * Initializes button listener. The subclasses must not need this listener.
489      * This is the reason of lazy initialization.
490      */

491     private ButtonL getButtonListener() {
492         if (buttonListener == null)
493             buttonListener = new ButtonL();
494         
495         return buttonListener;
496     }
497
498     RequestProcessor rp = new RequestProcessor();
499
500     /* expandAll nodes in the tree */
501     public void expandAll() {
502         checkEventThread();
503         final Cursor old = getCursor();
504         expandButton.setEnabled(false);
505         scrollPane.getViewport().remove(tree);
506         setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
507         rp.post(new Runnable JavaDoc() {
508             public void run() {
509                 int row = 0;
510                 while (row < tree.getRowCount()) {
511                     tree.expandRow(row);
512                     row++;
513                 }
514                 SwingUtilities.invokeLater(new Runnable JavaDoc() {
515                     public void run() {
516                         scrollPane.setViewportView(tree);
517                         setCursor(old);
518                         expandButton.setEnabled(true);
519                         expandButton.setToolTipText(
520                             NbBundle.getMessage(RefactoringPanel.class, "HINT_collapseAll") // NOI18N
521
);
522                         requestFocus();
523                     }
524                 });
525             }});
526     }
527
528     /* collapseAll nodes in the tree */
529     public void collapseAll() {
530         checkEventThread();
531         expandButton.setEnabled(false);
532         final Cursor old = getCursor();
533         scrollPane.getViewport().remove(tree);
534         setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
535         rp.post(new Runnable JavaDoc() {
536             public void run() {
537                 int row = tree.getRowCount() - 1;
538                 while (row > 0) {
539                     tree.collapseRow(row);
540                     row--;
541                 }
542                 SwingUtilities.invokeLater(new Runnable JavaDoc() {
543                     public void run() {
544                         scrollPane.setViewportView(tree);
545                         setCursor(old);
546                         expandButton.setEnabled(true);
547                         expandButton.setToolTipText(
548                             NbBundle.getMessage(RefactoringPanel.class, "HINT_expandAll") // NOI18N
549
);
550                         requestFocus();
551                     }
552                 });
553             }});
554     }
555     
556     public void invalidateObject() {
557         if (isQuery) {
558             return;
559         }
560         Runnable JavaDoc invalidate = new Runnable JavaDoc() {
561             public void run() {
562                 setRefactoringEnabled(false, false);
563             }
564         };
565         if (SwingUtilities.isEventDispatchThread()) {
566             invalidate.run();
567         } else {
568             SwingUtilities.invokeLater(invalidate);
569         }
570     }
571     private void refresh(final boolean showParametersPanel) {
572         checkEventThread();
573         if (!isQuery)
574             LifecycleManager.getDefault().saveAll();
575         
576         if (showParametersPanel) {
577             // create parameters panel for refactoring
578
if (parametersPanel == null) {
579                 parametersPanel = new ParametersPanel(ui);
580             }
581             // show parameters dialog
582
RefactoringSession tempSession = parametersPanel.showDialog();
583             // if no elements were returned, action was either cancelled or preview
584
// was skipped -> finish
585
if (tempSession == null) {
586                 return;
587             }
588             
589             session = tempSession;
590         }
591         
592         initialize();
593
594         final String JavaDoc description = ui.getDescription();
595         setToolTipText("<html>" + description + "</html>"); // NOI18N
596
final Collection JavaDoc elements = session.getRefactoringElements();
597         setName(ui.getName());
598         Component c=null;
599         if (ui instanceof RefactoringCustomUI) {
600             c = ((RefactoringCustomUI) ui).getCustomComponent(elements);
601             this.left.remove(c);
602         }
603         final ProgressHandle progressHandle = ProgressHandleFactory.createHandle(NbBundle.getMessage(RefactoringPanel.class, isQuery ? "LBL_PreparingUsagesTree":"LBL_PreparingRefactoringTree"));
604         if (currentView == GRAPHICAL) {
605             assert ui instanceof RefactoringCustomUI;
606             assert c != null;
607             RefactoringCustomUI cui = (RefactoringCustomUI) ui;
608             this.left.remove(scrollPane);
609             this.left.add(c, BorderLayout.CENTER);
610             tree=null;
611             this.repaint();
612         } else {
613             RequestProcessor.getDefault().post(new Runnable JavaDoc() {
614                 public void run() {
615                     HashSet editorSupports = new HashSet();
616                     int errorsNum = 0;
617                     if (!isQuery) {
618                         for (Iterator iter = elements.iterator(); iter.hasNext(); ) {
619                             RefactoringElement elem = (RefactoringElement) iter.next();
620                             if (elem.getStatus() == RefactoringElement.GUARDED || elem.getStatus() == RefactoringElement.READ_ONLY) {
621                                 errorsNum++;
622                             }
623                         }
624                     }
625                     int occurencesNum = elements.size();
626                     StringBuffer JavaDoc errorsDesc = new StringBuffer JavaDoc();
627                     errorsDesc.append(" [" + occurencesNum); // NOI18N
628
errorsDesc.append(' ');
629                     errorsDesc.append(occurencesNum == 1 ?
630                         NbBundle.getMessage(RefactoringPanel.class, "LBL_Occurence") :
631                         NbBundle.getMessage(RefactoringPanel.class, "LBL_Occurences")
632                         );
633                     if (errorsNum > 0) {
634                         errorsDesc.append(',');
635                         errorsDesc.append(' ');
636                         errorsDesc.append("<font color=#CC0000>" + errorsNum); // NOI18N
637
errorsDesc.append(' ');
638                         errorsDesc.append(errorsNum == 1 ?
639                             NbBundle.getMessage(RefactoringPanel.class, "LBL_Error") :
640                             NbBundle.getMessage(RefactoringPanel.class, "LBL_Errors")
641                             );
642                         errorsDesc.append("</font>"); // NOI18N
643
}
644                     errorsDesc.append(']');
645                     final CheckNode root = new CheckNode(null, description + errorsDesc.toString(), new ImageIcon JavaDoc(Utilities.loadImage("org/netbeans/modules/refactoring/api/resources/" + (isQuery ? "findusages.png" : "refactoring.gif"))));
646                     HashMap nodes = new HashMap();
647                     
648                     final Cursor old = getCursor();
649                     setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
650                     
651                     progressHandle.start(elements.size()/10);
652                     int i=0;
653                     try {
654                         //[retouche] JavaModel.getJavaRepository().beginTrans(false);
655
try {
656                             // ui.getRefactoring().setClassPath();
657
for (Iterator it = elements.iterator(); it.hasNext();i++) {
658                                 RefactoringElement e = (RefactoringElement) it.next();
659                                 createNode(TreeElementFactory.getTreeElement(e), nodes, root);
660                                 PositionBounds pb = e.getPosition();
661                                 if (pb != null) {
662                                     CloneableEditorSupport ces = pb.getBegin().getCloneableEditorSupport();
663                                     editorSupports.add(ces);
664                                 }
665                                 
666                                 if (i % 10 == 0)
667                                     progressHandle.progress(i/10);
668                             }
669                         } finally {
670                             //[retouche] JavaModel.getJavaRepository().endTrans();
671
}
672                         UndoManager.getDefault().watch(editorSupports, RefactoringPanel.this);
673                     } catch (RuntimeException JavaDoc t) {
674                         cleanupTreeElements();
675                         throw t;
676                     } catch (Error JavaDoc e) {
677                         cleanupTreeElements();
678                         throw e;
679                     } finally {
680                         progressHandle.finish();
681                         setCursor(old);
682                     }
683                     
684                     SwingUtilities.invokeLater(new Runnable JavaDoc() {
685                         public void run() {
686                             if (tree == null) {
687                                 // add panel with appropriate content
688
tree = new JTree(root) {
689                                     public TreePath JavaDoc getNextMatch(String JavaDoc prefix, int startingRow, Position.Bias JavaDoc bias) {
690                                         try {
691                                             return super.getNextMatch(prefix,startingRow, bias);
692                                         } catch (NullPointerException JavaDoc e) {
693                                             //Work around for 43112
694
}
695                                         return null;
696                                     }
697                                 };
698                                 ToolTipManager.sharedInstance().registerComponent(tree);
699                                 tree.setCellRenderer(new CheckRenderer(isQuery));
700                                 String JavaDoc s = NbBundle.getMessage(RefactoringPanel.class, "ACSD_usagesTree"); // NOI18N
701
tree.getAccessibleContext().setAccessibleDescription(s);
702                                 tree.getAccessibleContext().setAccessibleName(s);
703                                 CheckNodeListener l = new CheckNodeListener(isQuery);
704                                 tree.addMouseListener(l);
705                                 tree.addKeyListener(l);
706                                 tree.setToggleClickCount(0);
707                                 scrollPane = new JScrollPane(tree);
708                                 RefactoringPanel.this.left.add(scrollPane, BorderLayout.CENTER);
709                                 RefactoringPanel.this.validate();
710                             } else {
711                                 tree.setModel(new DefaultTreeModel JavaDoc(root));
712                             }
713                             tree.setRowHeight((int) ((CheckRenderer) tree.getCellRenderer()).getPreferredSize().getHeight());
714                             
715                             if (showParametersPanel) {
716                                 splitPane.setDividerLocation(0.3);
717                                 if (elements.size() < MAX_ROWS) {
718                                     expandAll();
719                                     if (!isQuery)
720                                         selectNextUsage();
721                                 } else
722                                     expandButton.setSelected(false);
723                             } else {
724                                 if (expandButton.isSelected()) {
725                                     expandAll();
726                                     if (!isQuery)
727                                         selectNextUsage();
728                                 } else
729                                     expandButton.setSelected(false);
730                             }
731                             
732                             tree.setSelectionRow(0);
733                             requestFocus();
734                             setRefactoringEnabled(true, true);
735                         }
736                     });
737                 }
738             });
739         }
740         if (!isVisible) {
741             // dock it into output window area and display
742
RefactoringPanelContainer cont = isQuery ? RefactoringPanelContainer.getUsagesComponent() : RefactoringPanelContainer.getRefactoringComponent();
743             cont.open();
744             cont.requestActive();
745             cont.addPanel(this);
746             isVisible = true;
747         }
748         setRefactoringEnabled(false, true);
749     }
750     
751     public void requestFocus() {
752         super.requestFocus();
753         if (refactorButton != null) {
754             refactorButton.requestFocus();
755         } else {
756             if (tree!=null)
757                 tree.requestFocus();
758         }
759     }
760     
761     void setRefactoringEnabled(boolean enabled, boolean isRefreshing) {
762         checkEventThread();
763         if (tree != null) {
764             if (!enabled) {
765                 CheckNode c = (CheckNode) tree.getModel().getRoot();
766                 if (!isRefreshing) {
767                     c.setNeedsRefresh();
768                 } else {
769                     c.setDisabled();
770                 }
771                 tree.setModel(new DefaultTreeModel JavaDoc(c, false));
772             }
773 // tree.validate();
774
tree.setEnabled(enabled);
775             if (refactorButton != null) {
776                 refactorButton.setEnabled(enabled);
777             }
778         }
779     }
780
781     // disables all components in a given container
782
private static void disableComponents(Container c) {
783         checkEventThread();
784         Component children[] = c.getComponents();
785         for (int i = 0; i < children.length; i++) {
786             if (children[i].isEnabled()) {
787                 children[i].setEnabled(false);
788             }
789             if (children[i] instanceof Container) {
790                 disableComponents((Container) children[i]);
791             }
792         }
793     }
794     
795     void selectNextUsage() {
796         selectNextPrev(true);
797     }
798     
799     void selectPrevUsage() {
800         selectNextPrev(false);
801     }
802     
803     private void selectNextPrev(final boolean next) {
804         int newRow = getSelectedRow();
805         int maxcount = tree.getRowCount();
806         CheckNode node;
807         do {
808             if (next) {
809                 newRow++;
810                 if (newRow>=maxcount)
811                     newRow = 0;
812             } else {
813                 newRow--;
814                 if (newRow<0)
815                     newRow = maxcount-1;
816             }
817             TreePath JavaDoc path = tree.getPathForRow(newRow);
818             node = (CheckNode) path.getLastPathComponent();
819             if (!node.isLeaf()) {
820                 tree.expandRow(newRow);
821                 maxcount = tree.getRowCount();
822             }
823         }
824         while (!node.isLeaf());
825         tree.setSelectionRow(newRow);
826         tree.scrollRowToVisible(newRow);
827         if (isQuery) {
828             CheckNodeListener.findInSource(node);
829         } else {
830             CheckNodeListener.openDiff(node);
831         }
832     }
833     
834     private int getSelectedRow() {
835         int[] rows = tree.getSelectionRows();
836         if (rows == null || rows.length == 0)
837             return 0;
838         return rows[0];
839     }
840
841     ////////////////////////////////////////////////////////////////////////////
842
// INNER CLASSES
843
////////////////////////////////////////////////////////////////////////////
844

845     private class ButtonL implements ActionListener JavaDoc {
846         public void actionPerformed(ActionEvent JavaDoc event) {
847             Object JavaDoc o = event.getSource();
848             // Cancel button pressed, remove refactoring panel
849
if (o == cancelButton) {
850                 cancel();
851             } else if (o == refactorButton) {
852                 refactor();
853             } else if (o == rerunButton) {
854                 close();
855                 callback.actionPerformed(event);
856             }
857             // expandAll button selected/deselected
858
else if (o == expandButton && tree != null) {
859                 if (expandButton.isSelected())
860                     expandAll();
861                 else
862                     collapseAll();
863             } else if (o == refreshButton) {
864                 if (callback!=null) {
865                     close();
866                     callback.actionPerformed(event);
867                 } else {
868                     refresh(true);
869                 }
870             } else if (o == physicalViewButton) {
871                 switchToPhysicalView();
872             } else if (o == logicalViewButton) {
873                 switchToLogicalView();
874             } else if (o == customViewButton) {
875                 switchToCustomView();
876             } else if (o == nextMatch) {
877                 selectNextUsage();
878             } else if (o == prevMatch) {
879                 selectPrevUsage();
880             }
881         }
882     } // end ButtonL
883
////////////////////////////////////////////////////////////////////////////
884

885     private static String JavaDoc normalize(String JavaDoc input) {
886         int size = input.length();
887         char[] c = new char[size];
888         input.getChars(0, size, c, 0);
889         boolean wb = false;
890         int pos = 0;
891         char[] nc = new char[size];
892         
893         for (int i = 0; i < size; i++) {
894             if (Character.isWhitespace(c[i])) {
895                 if (!wb) {
896                     nc[pos++] = ' ';
897
898                     wb = true;
899                 }
900             }
901             else {
902                 nc[pos++] = c[i];
903                 wb = false;
904             }
905         }
906         return new String JavaDoc(nc, 0, pos);
907     }
908
909     /** Processes returned problems from refactoring operations and notifies
910      * user (in case of non-fatal problems gives user a chance to continue or cancel).
911      * @param problem Problems returned from a refactoring operation.
912      * @return <code>true</code> if no fatal problems were found and user decided
913      * to continue in case of non-fatal problems; <code>false</code> if there was at
914      * least one fatal problem or at least one non-fatal problem in response to which
915      * user decided to cancel the operation.
916      */

917     /* public static boolean confirmProblems(Problem problem) {
918         while (problem != null) {
919             int result;
920             if (problem.isFatal()) {
921                 JOptionPane.showMessageDialog(null, problem.getMessage(), NbBundle.getMessage(ParametersPanel.class, "LBL_Error"), JOptionPane.ERROR_MESSAGE);
922                 return false;
923             } else {
924                 if (JOptionPane.showConfirmDialog(
925                     null,
926                     problem.getMessage() + ' ' + NbBundle.getMessage(ParametersPanel.class, "QST_Continue"),
927                     NbBundle.getMessage(ParametersPanel.class, "LBL_Warning"),
928                     JOptionPane.YES_NO_OPTION,
929                     JOptionPane.WARNING_MESSAGE
930                 ) != JOptionPane.YES_OPTION) {
931                     return false;
932                 }
933             }
934             problem = problem.getNext();
935         }
936         return true;
937     } */

938     
939     protected void closeNotify() {
940         UndoWatcher.stopWatching(this);
941         if (tree!=null) {
942             ToolTipManager.sharedInstance().unregisterComponent(tree);
943             scrollPane.getViewport().remove(tree);
944         }
945         scrollPane.setViewport(null);
946         if (refCallerTC != null) {
947             TopComponent tc = (TopComponent) refCallerTC.get();
948             if (tc != null && tc.isShowing()) {
949                 tc.requestActive();
950             }
951         }
952         cleanupTreeElements();
953         //super.closeNotify();
954
}
955     
956     private void cleanupTreeElements() {
957         for (TreeElementFactoryImplementation tefi: Lookup.getDefault().lookupAll(TreeElementFactoryImplementation.class)) {
958             tefi.cleanUp();
959         }
960     }
961
962     private static class ProgressL implements ProgressListener {
963         
964         private ProgressHandle handle;
965         private Dialog d;
966         private int counter;
967         
968         public void start(final ProgressEvent event) {
969             SwingUtilities.invokeLater(new Runnable JavaDoc() {
970                 public void run() {
971                     counter = 0;
972                     final String JavaDoc lab = NbBundle.getMessage(RefactoringPanel.class, "LBL_RefactorProgressLabel");
973                     handle = ProgressHandleFactory.createHandle(lab);
974                     JComponent progress = ProgressHandleFactory.createProgressComponent(handle);
975                     JPanel component = new JPanel();
976                     component.setLayout(new BorderLayout());
977                     component.setBorder(new EmptyBorder JavaDoc(12,12,11,11));
978                     JLabel label = new JLabel(lab);
979                     label.setBorder(new EmptyBorder JavaDoc(0, 0, 6, 0));
980                     component.add(label, BorderLayout.NORTH);
981                     component.add(progress, BorderLayout.CENTER);
982                     DialogDescriptor desc = new DialogDescriptor(component, NbBundle.getMessage(RefactoringPanel.class, "LBL_RefactoringInProgress"), true, new Object JavaDoc[]{}, null, 0, null, null);
983                     desc.setLeaf(true);
984                     d = DialogDisplayer.getDefault().createDialog(desc);
985                     ((JDialog) d).setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
986                     
987                     handle.start(event.getCount());
988                     d.show();
989                 }
990             });
991         }
992         
993         public void step(ProgressEvent event) {
994             SwingUtilities.invokeLater(new Runnable JavaDoc() {
995                 public void run() {
996                     try {
997                         handle.progress(++counter);
998                     } catch (Throwable JavaDoc e) {
999                         ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
1000                    }
1001                }
1002            });
1003        }
1004        
1005        public void stop(ProgressEvent event) {
1006            SwingUtilities.invokeLater(new Runnable JavaDoc() {
1007                public void run() {
1008                    handle.finish();
1009                    d.hide();
1010                }
1011            });
1012        }
1013    }
1014} // end Refactor Panel
1015
Popular Tags