001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.refactoring.spi.impl;
042:
043: import java.awt.*;
044: import java.awt.event.*;
045: import java.io.IOException;
046: import java.util.ArrayList;
047: import java.util.Iterator;
048: import javax.swing.*;
049: import javax.swing.border.EmptyBorder;
050: import javax.swing.event.ChangeEvent;
051: import javax.swing.event.ChangeListener;
052: import org.netbeans.api.javahelp.Help;
053: import org.netbeans.api.progress.ProgressHandle;
054: import org.netbeans.api.progress.ProgressHandleFactory;
055: import org.netbeans.modules.refactoring.api.AbstractRefactoring;
056: import org.netbeans.modules.refactoring.api.Problem;
057: import org.netbeans.modules.refactoring.api.ProblemDetails;
058: import org.netbeans.modules.refactoring.api.RefactoringSession;
059: import org.netbeans.modules.refactoring.spi.impl.UndoWatcher;
060: import org.netbeans.modules.refactoring.spi.ui.*;
061: import org.openide.DialogDescriptor;
062: import org.openide.DialogDisplayer;
063: import org.openide.ErrorManager;
064: import org.openide.util.*;
065: import org.netbeans.modules.refactoring.api.ProgressListener;
066: import org.netbeans.modules.refactoring.api.ProgressEvent;
067: import org.netbeans.modules.refactoring.api.impl.APIAccessor;
068: import org.netbeans.modules.refactoring.spi.impl.ProblemComponent.CallbackAction;
069: import org.openide.awt.Mnemonics;
070:
071: /** Main panel for refactoring parameters dialog. This panel is automatically displayed
072: * by refactoring action. It handles all the generic logic for displaying progress,
073: * checking for problems (during parameters validation and refactoring preparation) and
074: * accepting/canceling the refactoring. Refactoring-specific parameters panel is
075: * requested from {@link RefactoringUI} implementation (passed to this panel by {@link
076: * AbstractRefactoringAction}) and then displayed in the upper part of this panel.
077: * Refactoring-specific panel can use setPreviewEnabled method to enable/disable
078: * button that accepts the parameters. The button is disabled by default.
079: *
080: * @author Martin Matula, Jan Becicka
081: */
082: public class ParametersPanel extends JPanel implements
083: ProgressListener, ChangeListener, InvalidationListener {
084: // refactoring elements that will be returned as a result of showDialog method
085: private RefactoringSession result;
086:
087: // corresponding implementation of RefactoringUI
088: private final RefactoringUI rui;
089: // refactoring-specific panel returned from RefactoringUI.getPanel
090: private final JPanel customPanel;
091: private final CustomRefactoringPanel customComponent;
092:
093: // parent dialog
094: private transient JDialog dialog = null;
095: // disabled components that should be reenabled by a call to setPanelEnabled
096: private ArrayList components = null;
097:
098: private Problem problem;
099:
100: private ErrorPanel errorPanel;
101:
102: private final int PRE_CHECK = 0;
103: private final int INPUT_PARAMETERS = 1;
104: private final int POST_CHECK = 2;
105: private final int CHECK_PARAMETERS = 3;
106:
107: private transient int currentState = INPUT_PARAMETERS;
108:
109: private boolean cancelRequest = false;
110:
111: /** Enables/disables Preview button of dialog. Can be used by refactoring-specific
112: * parameters panel to disable accepting the parameters when needed (e.g. if
113: * not all parameters were entered). When the dialog is displayed, the button
114: * is disabled by default.
115: * @param enabled <code>true</code> to enable preview button, <code>false</code>
116: * to disable it.
117: */
118: public void setPreviewEnabled(boolean enabled) {
119: RefactoringPanel.checkEventThread();
120: next.setEnabled(enabled && !isPreviewRequired());
121: }
122:
123: /** Creates ParametersPanel
124: * @param rui Implementation of RefactoringUI for desired refactoring.
125: */
126: public ParametersPanel(RefactoringUI rui) {
127: RefactoringPanel.checkEventThread();
128: this .rui = rui;
129: initComponents();
130: innerPanel.setBorder(null);
131: label.setText(" ");//NOI18N
132: this .customComponent = rui.getPanel(this );
133: if (this .customComponent != null) {
134: this .customPanel = (JPanel) this .customComponent
135: .getComponent();
136: } else {
137: customPanel = null;
138: }
139: errorPanel = new ErrorPanel(rui);
140: calculatePrefferedSize();
141: setButtonsEnabled(false);
142: //cancel.setEnabled(false);
143: }
144:
145: private void calculatePrefferedSize() {
146: Dimension cpDim = new Dimension(0, 0);
147: Dimension ppDim = progressPanel.getPreferredSize();
148: Dimension epDim = new Dimension(0, 0);
149: if (customPanel != null) {
150: cpDim = customPanel.getPreferredSize();
151: }
152: if (errorPanel != null) {
153: epDim = errorPanel.getPreferredSize();
154: }
155:
156: setPreferredSize(new Dimension(Math.max(Math.max(cpDim.width,
157: ppDim.width), epDim.width), Math.max(cpDim.height,
158: epDim.height)
159: + ppDim.height));
160: //validate();
161: if (dialog != null && rui.isQuery()) {
162: dialog.setSize(getPreferredSize());
163: }
164: }
165:
166: /** This method is called from within the constructor to
167: * initialize the form.
168: * WARNING: Do NOT modify this code. The content of this method is
169: * always regenerated by the Form Editor.
170: */
171: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
172: private void initComponents() {
173:
174: progressPanel = new javax.swing.JPanel();
175: innerPanel = new javax.swing.JPanel();
176: label = new javax.swing.JLabel();
177: controlsPanel = new javax.swing.JPanel();
178: buttonsPanel = new javax.swing.JPanel();
179: back = new javax.swing.JButton();
180: previewButton = new javax.swing.JButton();
181: previewButton.setVisible(false);
182: next = new javax.swing.JButton();
183: cancel = new javax.swing.JButton();
184: help = new javax.swing.JButton();
185: containerPanel = new javax.swing.JPanel();
186: pleaseWait = new javax.swing.JLabel();
187:
188: setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0,
189: 0));
190: java.util.ResourceBundle bundle = java.util.ResourceBundle
191: .getBundle("org/netbeans/modules/refactoring/spi/impl/Bundle"); // NOI18N
192: setName(bundle.getString("LBL_FindUsagesDialog")); // NOI18N
193: setLayout(new java.awt.BorderLayout());
194:
195: progressPanel.setBorder(javax.swing.BorderFactory
196: .createEmptyBorder(0, 12, 0, 11));
197: progressPanel.setOpaque(false);
198: progressPanel.setLayout(new java.awt.BorderLayout());
199:
200: innerPanel.setBorder(javax.swing.BorderFactory
201: .createLineBorder(new java.awt.Color(128, 128, 128)));
202: innerPanel.setLayout(new java.awt.BorderLayout());
203:
204: label.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
205: innerPanel.add(label, java.awt.BorderLayout.WEST);
206:
207: progressPanel.add(innerPanel, java.awt.BorderLayout.CENTER);
208:
209: controlsPanel.setBorder(javax.swing.BorderFactory
210: .createEmptyBorder(5, 0, 5, 0));
211: controlsPanel.setLayout(new java.awt.BorderLayout());
212:
213: buttonsPanel.setBorder(javax.swing.BorderFactory
214: .createEmptyBorder(0, 0, 0, 0));
215: buttonsPanel.setLayout(new java.awt.GridLayout(1, 0, 4, 0));
216:
217: org.openide.awt.Mnemonics
218: .setLocalizedText(
219: back,
220: org.openide.util.NbBundle
221: .getBundle(
222: "org/netbeans/modules/refactoring/spi/impl/Bundle")
223: .getString("CTL_Back")); // NOI18N
224: back.addActionListener(new java.awt.event.ActionListener() {
225: public void actionPerformed(java.awt.event.ActionEvent evt) {
226: backActionPerformed(evt);
227: }
228: });
229: buttonsPanel.add(back);
230: back.getAccessibleContext().setAccessibleDescription(
231: bundle.getString("ACSD_Back")); // NOI18N
232:
233: org.openide.awt.Mnemonics.setLocalizedText(previewButton,
234: org.openide.util.NbBundle.getMessage(
235: ParametersPanel.class, "CTL_PreviewAll")); // NOI18N
236: previewButton
237: .addActionListener(new java.awt.event.ActionListener() {
238: public void actionPerformed(
239: java.awt.event.ActionEvent evt) {
240: preview(evt);
241: }
242: });
243: buttonsPanel.add(previewButton);
244: previewButton
245: .getAccessibleContext()
246: .setAccessibleDescription(
247: org.openide.util.NbBundle
248: .getMessage(ParametersPanel.class,
249: "ParametersPanel.previewButton.AccessibleContext.accessibleDescription")); // NOI18N
250:
251: org.openide.awt.Mnemonics
252: .setLocalizedText(
253: next,
254: org.openide.util.NbBundle
255: .getBundle(
256: "org/netbeans/modules/refactoring/spi/impl/Bundle")
257: .getString("CTL_Finish")); // NOI18N
258: next.addActionListener(new java.awt.event.ActionListener() {
259: public void actionPerformed(java.awt.event.ActionEvent evt) {
260: refactor(evt);
261: }
262: });
263: buttonsPanel.add(next);
264: next.getAccessibleContext().setAccessibleDescription(
265: bundle.getString("ACSD_finish")); // NOI18N
266:
267: org.openide.awt.Mnemonics
268: .setLocalizedText(
269: cancel,
270: org.openide.util.NbBundle
271: .getBundle(
272: "org/netbeans/modules/refactoring/spi/impl/Bundle")
273: .getString("CTL_Cancel")); // NOI18N
274: cancel.addActionListener(new java.awt.event.ActionListener() {
275: public void actionPerformed(java.awt.event.ActionEvent evt) {
276: cancelActionPerformed(evt);
277: }
278: });
279: buttonsPanel.add(cancel);
280: cancel.getAccessibleContext().setAccessibleDescription(
281: bundle.getString("ACSD_cancel")); // NOI18N
282:
283: org.openide.awt.Mnemonics
284: .setLocalizedText(
285: help,
286: org.openide.util.NbBundle
287: .getBundle(
288: "org/netbeans/modules/refactoring/spi/impl/Bundle")
289: .getString("CTL_Help")); // NOI18N
290: help.addActionListener(new java.awt.event.ActionListener() {
291: public void actionPerformed(java.awt.event.ActionEvent evt) {
292: helpActionPerformed(evt);
293: }
294: });
295: buttonsPanel.add(help);
296: help.getAccessibleContext().setAccessibleDescription(
297: bundle.getString("ACSD_help")); // NOI18N
298:
299: controlsPanel.add(buttonsPanel, java.awt.BorderLayout.EAST);
300:
301: progressPanel.add(controlsPanel, java.awt.BorderLayout.SOUTH);
302:
303: add(progressPanel, java.awt.BorderLayout.SOUTH);
304:
305: containerPanel.setBorder(javax.swing.BorderFactory
306: .createEmptyBorder(0, 0, 0, 0));
307: containerPanel.setLayout(new java.awt.BorderLayout());
308:
309: pleaseWait
310: .setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
311: org.openide.awt.Mnemonics
312: .setLocalizedText(
313: pleaseWait,
314: org.openide.util.NbBundle
315: .getBundle(
316: "org/netbeans/modules/refactoring/spi/impl/Bundle")
317: .getString("LBL_PleaseWait")); // NOI18N
318: containerPanel.add(pleaseWait, java.awt.BorderLayout.CENTER);
319: pleaseWait.getAccessibleContext().setAccessibleName(
320: org.openide.util.NbBundle.getMessage(
321: ParametersPanel.class, "LBL_PleaseWait")); // NOI18N
322:
323: add(containerPanel, java.awt.BorderLayout.CENTER);
324:
325: getAccessibleContext().setAccessibleName(
326: bundle.getString("LBL_FindUsagesDialog")); // NOI18N
327: getAccessibleContext().setAccessibleDescription(
328: bundle.getString("ACSD_FindUsagesDialog")); // NOI18N
329: }// </editor-fold>//GEN-END:initComponents
330:
331: private void preview(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_preview
332: refactor(true);
333: }//GEN-LAST:event_preview
334:
335: private void helpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_helpActionPerformed
336: Help help = (Help) Lookup.getDefault().lookup(Help.class);
337: help.showHelp(getHelpCtx());
338: }//GEN-LAST:event_helpActionPerformed
339:
340: private void backActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backActionPerformed
341: placeCustomPanel();
342: }//GEN-LAST:event_backActionPerformed
343:
344: private void cancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelActionPerformed
345: synchronized (this ) {
346: if (evt != null && evt.getSource() instanceof Cancellable) {
347: result = null;
348: dialog.setVisible(false);
349: } else {
350: rui.getRefactoring().cancelRequest();
351: result = null;
352: dialog.setVisible(false);
353: cancelRequest = true;
354: }
355: }
356: }//GEN-LAST:event_cancelActionPerformed
357:
358: private void refactor(final boolean previewAll) {
359: if (currentState == PRE_CHECK) {
360: //next is "Next>"
361: placeCustomPanel();
362: return;
363: }
364:
365: if (currentState == POST_CHECK && previewAll
366: && currentProblemAction != null) {
367: Cancellable doCloseParent = new Cancellable() {
368: public boolean cancel() {
369: cancelActionPerformed(new ActionEvent(this , 0, null));
370: return true;
371: }
372: };
373: currentProblemAction.showDetails(new CallbackAction(rui),
374: doCloseParent);
375: return;
376: }
377:
378: //next is Finish
379:
380: setPanelEnabled(false);
381: cancel.setEnabled(true);
382:
383: RequestProcessor rp = new RequestProcessor();
384: final int inputState = currentState;
385:
386: if (currentState != PRE_CHECK && currentState != POST_CHECK) {
387: if (rui instanceof RefactoringUIBypass
388: && ((RefactoringUIBypass) rui)
389: .isRefactoringBypassRequired()) {
390: try {
391: ((RefactoringUIBypass) rui).doRefactoringBypass();
392: } catch (final IOException ioe) {
393: currentState = POST_CHECK;
394: SwingUtilities.invokeLater(new Runnable() {
395: public void run() {
396: placeErrorPanel(new Problem(true, ioe
397: .getMessage()));
398: }
399: });
400: } finally {
401: if (inputState == currentState) {
402: setVisibleLater(false);
403: }
404: return;
405: }
406: } else if (currentState != POST_CHECK
407: && currentState != CHECK_PARAMETERS) {
408: result = RefactoringSession.create(rui.getName());
409: //setParameters and prepare is done asynchronously
410: rp.post(new Prepare());
411: } else if (currentState == CHECK_PARAMETERS) {
412: rp.post(new Prepare());
413: }
414: }
415:
416: //refactoring is done asynchronously
417:
418: rp.post(new Runnable() {
419: public void run() {
420: //inputState != currentState means, that panels changed and dialog will not be closed
421: if (inputState == currentState) {
422: try {
423: if (!previewAll && result != null) {
424: UndoWatcher.watch(result,
425: ParametersPanel.this );
426: result
427: .addProgressListener(ParametersPanel.this );
428: result.doRefactoring(true);
429: UndoWatcher
430: .stopWatching(ParametersPanel.this );
431: }
432: } finally {
433: if (!previewAll) {
434: result = null;
435: }
436: if (inputState == currentState) {
437: setVisibleLater(false);
438: }
439: }
440: }
441: }
442: });
443: }
444:
445: private void refactor(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refactor
446: refactor(rui.isQuery());
447: }//GEN-LAST:event_refactor
448:
449: // Variables declaration - do not modify//GEN-BEGIN:variables
450: private javax.swing.JButton back;
451: private javax.swing.JPanel buttonsPanel;
452: public javax.swing.JButton cancel;
453: private javax.swing.JPanel containerPanel;
454: private javax.swing.JPanel controlsPanel;
455: private javax.swing.JButton help;
456: private javax.swing.JPanel innerPanel;
457: private javax.swing.JLabel label;
458: private javax.swing.JButton next;
459: private javax.swing.JLabel pleaseWait;
460: private javax.swing.JButton previewButton;
461: private javax.swing.JPanel progressPanel;
462:
463: // End of variables declaration//GEN-END:variables
464:
465: /**
466: * dialog is closed asynchronously on the AWT event thread
467: */
468: private void setVisibleLater(final boolean visible) {
469: SwingUtilities.invokeLater(new Runnable() {
470: public void run() {
471: dialog.setVisible(visible);
472: }
473: });
474: }
475:
476: // disables/re-enables components in the custom panel
477: private void setPanelEnabled(boolean enabled) {
478: RefactoringPanel.checkEventThread();
479: setButtonsEnabled(enabled);
480: if (enabled) {
481: if (components == null)
482: return;
483: for (Iterator it = components.iterator(); it.hasNext();) {
484: ((Component) it.next()).setEnabled(true);
485: }
486: components = null;
487: } else {
488: if (components != null)
489: return;
490: components = new ArrayList();
491: disableComponents(customPanel);
492: }
493: }
494:
495: // disables all components in the custom panel
496: private void disableComponents(Container c) {
497: RefactoringPanel.checkEventThread();
498: Component children[] = c.getComponents();
499: for (int i = 0; i < children.length; i++) {
500: if (children[i].isEnabled()) {
501: children[i].setEnabled(false);
502: components.add(children[i]);
503: }
504: if (children[i] instanceof Container) {
505: disableComponents((Container) children[i]);
506: }
507: }
508: }
509:
510: /** Method used by AbstractRefactoringAction to display refactoring parameters
511: * dialog. Constructs a dialog consisting of this panel and Preview and Cancel
512: * buttons. Let's user to enter refactoring parameters.
513: * @return Collection of refactoring elements returned from the refactoring
514: * operation or <code>null</code> if the operation was cancelled.
515: */
516: public synchronized RefactoringSession showDialog() {
517: RefactoringPanel.checkEventThread();
518: if (rui != null) {
519: rui.getRefactoring().addProgressListener(this );
520: }
521: String title = (customPanel != null
522: && customPanel.getName() != null && !""
523: .equals(customPanel.getName())) ? customPanel.getName()
524: : rui.getName();
525: DialogDescriptor descriptor = new DialogDescriptor(this , title,
526: true, new Object[] {}, null, 0, null, null);
527:
528: dialog = (JDialog) DialogDisplayer.getDefault().createDialog(
529: descriptor);
530: dialog.validate();
531: if (customPanel != null) {
532: dialog.getAccessibleContext().setAccessibleName(
533: rui.getName());
534: dialog.getAccessibleContext().setAccessibleDescription(
535: NbBundle.getMessage(ParametersPanel.class,
536: "ACSD_FindUsagesDialog"));
537: }
538:
539: setCancelStuff();
540:
541: dialog.pack();
542:
543: RequestProcessor.Task task = RequestProcessor.getDefault()
544: .post(new Runnable() {
545: public void run() {
546: try {
547: problem = rui.getRefactoring().preCheck();
548: } catch (RuntimeException e) {
549: setVisibleLater(false);
550: throw e;
551: }
552: if (problem != null) {
553: currentState = PRE_CHECK;
554: if (!problem.isFatal()) {
555: customComponent.initialize();
556: }
557: SwingUtilities.invokeLater(new Runnable() {
558: public void run() {
559: placeErrorPanel(problem);
560: dialog.setVisible(true);
561: }
562: });
563: } else {
564: if (customPanel != null)
565: customComponent.initialize();
566: SwingUtilities.invokeLater(new Runnable() {
567: public void run() {
568: placeCustomPanel();
569: }
570: });
571: if (!rui.hasParameters()) {
572: result = RefactoringSession.create(rui
573: .getName());
574: try {
575: rui.getRefactoring()
576: .prepare(result);
577: } finally {
578: setVisibleLater(false);
579: }
580: }
581:
582: }
583: }
584: });
585:
586: if (!(customComponent == null && !rui.hasParameters() && !APIAccessor.DEFAULT
587: .hasPluginsWithProgress(rui.getRefactoring())))
588: dialog.setVisible(true);
589: dialog.dispose();
590:
591: if (rui != null) {
592: rui.getRefactoring().removeProgressListener(this );
593: }
594: if (!cancelRequest)
595: task.waitFinished();
596: RefactoringSession temp = result;
597: result = null;
598: return temp;
599: }
600:
601: private final void setCancelStuff() {
602: KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
603: Object actionKey = "cancel"; // NOI18N
604: getRootPane().getInputMap(
605: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(k,
606: actionKey);
607: Action cancelAction = new AbstractAction() {
608: public void actionPerformed(ActionEvent ev) {
609: if (cancel.isEnabled())
610: cancelActionPerformed(ev);
611: }
612: };
613:
614: getRootPane().getActionMap().put(actionKey, cancelAction);
615:
616: dialog.addWindowListener(new WindowAdapter() {
617: public void windowClosing(WindowEvent evt) {
618: if (cancel.isEnabled())
619: cancelActionPerformed(null);
620: }
621: });
622: }
623:
624: private ProblemDetails getDetails(Problem problem) {
625: if (problem.getNext() == null) {
626: return problem.getDetails();
627: }
628: return null;
629: }
630:
631: private ProblemDetails currentProblemAction;
632:
633: private void placeErrorPanel(Problem problem) {
634: containerPanel.removeAll();
635: errorPanel = new ErrorPanel(problem, rui);
636: errorPanel
637: .setBorder(new EmptyBorder(new Insets(12, 12, 11, 11)));
638: containerPanel.add(errorPanel, BorderLayout.CENTER);
639:
640: next.setEnabled(!problem.isFatal() && !isPreviewRequired());
641: dialog.getRootPane().setDefaultButton(next);
642: if (currentState == PRE_CHECK) {
643: //calculatePrefferedSize();
644: Mnemonics.setLocalizedText(next, NbBundle.getMessage(
645: ParametersPanel.class, "CTL_Next"));
646: back.setVisible(false);
647: } else {
648: ProblemDetails details = getDetails(problem);
649: if (details != null) {
650: Mnemonics.setLocalizedText(previewButton, details
651: .getDetailsHint());
652: previewButton.setVisible(true);
653: previewButton.setEnabled(true);
654: currentProblemAction = details;
655: }
656: back.setVisible(true);
657: back.setEnabled(true);
658: dialog.getRootPane().setDefaultButton(back);
659: if (details != null) {
660: setPreferredSize(null);
661: dialog.pack();
662: }
663: }
664: cancel.setEnabled(true);
665: previewButton.setEnabled(!problem.isFatal());
666: if (progressHandle != null) {
667: stop(null);
668: }
669: repaint();
670: }
671:
672: private void placeCustomPanel() {
673: if (customPanel == null)
674: return;
675: Mnemonics.setLocalizedText(next, NbBundle.getMessage(
676: ParametersPanel.class, rui.isQuery() ? "CTL_Find"
677: : "CTL_Finish"));
678: Mnemonics.setLocalizedText(previewButton, NbBundle.getMessage(
679: ParametersPanel.class, "CTL_PreviewAll"));
680: customPanel.setBorder(new EmptyBorder(
681: new Insets(12, 12, 11, 11)));
682: containerPanel.removeAll();
683: containerPanel.add(customPanel, BorderLayout.CENTER);
684: back.setVisible(false);
685: previewButton.setVisible(!rui.isQuery());
686: Boolean b = rui.getRefactoring().getContext().lookup(
687: Boolean.class);
688: next.setEnabled(!isPreviewRequired());
689: currentState = INPUT_PARAMETERS;
690: setPanelEnabled(true);
691: cancel.setEnabled(true);
692: dialog.getRootPane().setDefaultButton(next);
693: //Initial errors are ignored by on-line error checker
694: //stateChanged(null);
695: customPanel.requestFocus();
696: setOKorRefactor();
697: repaint();
698: }
699:
700: private boolean isPreviewRequired() {
701: UI.Constants b = rui.getRefactoring().getContext().lookup(
702: UI.Constants.class);
703: return b != null && b == UI.Constants.REQUEST_PREVIEW;
704: }
705:
706: private ProgressBar progressBar;
707: private ProgressHandle progressHandle;
708: private boolean isIndeterminate;
709:
710: /** Implementation of ProgressListener.start method. Displays progress bar and
711: * sets progress label and progress bar bounds.
712: * @param event Event object.
713: */
714: public void start(final ProgressEvent event) {
715: SwingUtilities.invokeLater(new Runnable() {
716: public void run() {
717: progressPanel.remove(innerPanel);
718: progressBar = ProgressBar
719: .create(progressHandle = ProgressHandleFactory
720: .createHandle("")); //NOI18N
721: progressPanel.add(progressBar, BorderLayout.CENTER);
722: //progressPanel.validate();
723: if (event.getCount() == -1) {
724: isIndeterminate = true;
725: progressHandle.start();
726: progressHandle.switchToIndeterminate();
727: } else {
728: isIndeterminate = false;
729: progressHandle.start(event.getCount());
730: }
731:
732: String text;
733: switch (event.getOperationType()) {
734: case AbstractRefactoring.PARAMETERS_CHECK:
735: text = NbBundle.getMessage(ParametersPanel.class,
736: "LBL_ParametersCheck");
737: break;
738: case AbstractRefactoring.PREPARE:
739: text = NbBundle.getMessage(ParametersPanel.class,
740: "LBL_Prepare");
741: break;
742: case AbstractRefactoring.PRE_CHECK:
743: text = NbBundle.getMessage(ParametersPanel.class,
744: "LBL_PreCheck");
745: break;
746: default:
747: text = NbBundle.getMessage(ParametersPanel.class,
748: "LBL_Usages");
749: break;
750: }
751: progressBar.setString(text); //NOI18N
752:
753: progressPanel.setVisible(true);
754:
755: setButtonsEnabled(false);
756: }
757: });
758: }
759:
760: /** Implementation of ProgressListener.step method. Increments progress bar value
761: * by 1.
762: * @param event Event object.
763: */
764: public void step(final ProgressEvent event) {
765: SwingUtilities.invokeLater(new Runnable() {
766: public void run() {
767: try {
768: progressHandle.progress(isIndeterminate ? -2
769: : event.getCount());
770: } catch (Throwable e) {
771: ErrorManager.getDefault().notify(
772: ErrorManager.INFORMATIONAL, e);
773: }
774: }
775: });
776: }
777:
778: /** Implementation of ProgressListener.stop method. Sets progress bar value to
779: * its maximum.
780: * @param event Event object.
781: */
782: public void stop(ProgressEvent event) {
783: Runnable run = new Runnable() {
784: public void run() {
785: progressHandle.finish();
786: progressPanel.remove(progressBar);
787: progressPanel.add(innerPanel, BorderLayout.CENTER);
788: //progressPanel.validate();
789: //setButtonsEnabled(true);
790: //validate();
791: }
792: };
793: if (SwingUtilities.isEventDispatchThread()) {
794: run.run();
795: } else {
796: SwingUtilities.invokeLater(run);
797: }
798: }
799:
800: public void stateChanged(ChangeEvent e) {
801: if (rui instanceof RefactoringUIBypass
802: && ((RefactoringUIBypass) rui)
803: .isRefactoringBypassRequired()) {
804: showProblem(null);
805: } else {
806: showProblem(rui.checkParameters());
807: }
808: setOKorRefactor();
809: }
810:
811: private void setOKorRefactor() {
812: if (rui instanceof RefactoringUIBypass) {
813: if (((RefactoringUIBypass) rui)
814: .isRefactoringBypassRequired()) {
815: next.setText(NbBundle.getMessage(DialogDisplayer.class,
816: "CTL_OK"));
817: previewButton.setVisible(false);
818: } else {
819: Mnemonics.setLocalizedText(next, NbBundle.getMessage(
820: ParametersPanel.class,
821: rui.isQuery() ? "CTL_Find" : "CTL_Finish"));
822: previewButton.setVisible(true);
823: }
824: }
825: }
826:
827: private void showProblem(Problem problem) {
828: if (problem == null) {
829: label.setText(" "); // NOI18N
830: innerPanel.setBorder(null);
831: next.setEnabled(!isPreviewRequired());
832: previewButton.setEnabled(true);
833: return;
834: }
835: innerPanel.setBorder(new javax.swing.border.LineBorder(
836: java.awt.Color.gray));
837: progressPanel.setVisible(true);
838: if (problem.isFatal()) {
839: displayError(problem.getMessage());
840: } else {
841: displayWarning(problem.getMessage());
842: }
843: }
844:
845: private void displayError(String error) {
846: next.setEnabled(false);
847: previewButton.setEnabled(false);
848: label.setText("<html><font color=\"red\">"
849: + NbBundle.getMessage(ParametersPanel.class,
850: "LBL_Error") + ": </font>" + error + "</html>"); //NOI18N
851: }
852:
853: private void displayWarning(String warning) {
854: next.setEnabled(!isPreviewRequired());
855: previewButton.setEnabled(true);
856: label.setText("<html><font color=\"red\">"
857: + NbBundle.getMessage(ParametersPanel.class,
858: "LBL_Warning") + ": </font>" + warning
859: + "</html>"); //NOI18N
860: }
861:
862: private class Prepare implements Runnable {
863: public void run() {
864: if (currentState != POST_CHECK
865: && currentState != CHECK_PARAMETERS) {
866: problem = rui.setParameters();
867: if (problem != null && currentState != POST_CHECK) {
868: currentState = CHECK_PARAMETERS;
869: try {
870: SwingUtilities.invokeAndWait(new Runnable() {
871: public void run() {
872: placeErrorPanel(problem);
873: }
874: });
875: } catch (Exception ie) {
876: throw (RuntimeException) new RuntimeException()
877: .initCause(ie);
878: }
879: return;
880: }
881: }
882:
883: try {
884: problem = rui.getRefactoring().prepare(result);
885: } catch (RuntimeException e) {
886: setVisibleLater(false);
887: throw e;
888: }
889:
890: if (problem != null) {
891: currentState = POST_CHECK;
892: SwingUtilities.invokeLater(new Runnable() {
893: public void run() {
894: placeErrorPanel(problem);
895: }
896: });
897: }
898: }
899: }
900:
901: private void setButtonsEnabled(boolean enabled) {
902: next.setEnabled(enabled && !isPreviewRequired());
903: //cancel.setEnabled(enabled);
904: back.setEnabled(enabled);
905: previewButton.setEnabled(enabled);
906: }
907:
908: public HelpCtx getHelpCtx() {
909: return rui.getHelpCtx();
910: }
911:
912: public void invalidateObject() {
913: }
914:
915: private static class ProgressBar extends JPanel {
916:
917: private JLabel label;
918:
919: private static ProgressBar create(ProgressHandle handle) {
920: ProgressBar instance = new ProgressBar();
921: instance.setLayout(new BorderLayout());
922: instance.label = new JLabel();
923: instance.label.setBorder(new EmptyBorder(0, 0, 2, 0));
924: instance.add(instance.label, BorderLayout.NORTH);
925: JComponent progress = ProgressHandleFactory
926: .createProgressComponent(handle);
927: instance.add(progress, BorderLayout.CENTER);
928: return instance;
929: }
930:
931: public void setString(String value) {
932: label.setText(value);
933: }
934:
935: private ProgressBar() {
936: }
937:
938: }
939:
940: }
|