001: /* ====================================================================
002: * The JRefactory License, Version 1.0
003: *
004: * Copyright (c) 2001 JRefactory. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by the
021: * JRefactory (http://www.sourceforge.org/projects/jrefactory)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. The names "JRefactory" must not be used to endorse or promote
026: * products derived from this software without prior written
027: * permission. For written permission, please contact seguin@acm.org.
028: *
029: * 5. Products derived from this software may not be called "JRefactory",
030: * nor may "JRefactory" appear in their name, without prior written
031: * permission of Chris Seguin.
032: *
033: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
034: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
035: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
036: * DISCLAIMED. IN NO EVENT SHALL THE CHRIS SEGUIN OR
037: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
038: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
039: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
040: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
041: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
042: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
043: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
044: * SUCH DAMAGE.
045: * ====================================================================
046: *
047: * This software consists of voluntary contributions made by many
048: * individuals on behalf of JRefactory. For more information on
049: * JRefactory, please see
050: * <http://www.sourceforge.org/projects/jrefactory>.
051: */
052: package org.acm.seguin.uml.refactor;
053:
054: import java.awt.Dimension;
055: import java.awt.FlowLayout;
056: import java.awt.GridBagConstraints;
057: import java.awt.GridBagLayout;
058: import java.awt.Insets;
059: import java.awt.Point;
060: import java.awt.Toolkit;
061: import javax.swing.BorderFactory;
062: import javax.swing.ButtonGroup;
063: import javax.swing.JButton;
064: import javax.swing.JFrame;
065: import javax.swing.JLabel;
066: import javax.swing.JList;
067: import javax.swing.JOptionPane;
068: import javax.swing.JPanel;
069: import javax.swing.JRadioButton;
070: import javax.swing.JTextField;
071: import org.acm.seguin.awt.CenterDialog;
072: import org.acm.seguin.awt.OrderableList;
073: import org.acm.seguin.refactor.Refactoring;
074: import org.acm.seguin.refactor.RefactoringException;
075: import org.acm.seguin.refactor.RefactoringFactory;
076: import org.acm.seguin.refactor.method.ExtractMethodRefactoring;
077: import org.acm.seguin.summary.VariableSummary;
078: import org.acm.seguin.uml.UMLPackage;
079:
080: /**
081: * User interface to enter the name of the method that was just extracted
082: *
083: *@author Chris Seguin
084: *@created September 12, 2001
085: */
086: public abstract class ExtractMethodDialog extends RefactoringDialog {
087: // Instance Variables
088: private JTextField newName;
089: private ExtractMethodRefactoring emr;
090: private OrderableList list;
091: private JRadioButton privateButton;
092: private JRadioButton packageButton;
093: private JRadioButton protectedButton;
094: private JRadioButton publicButton;
095: private JList returnList;
096: private JTextField returnTextField;
097: private JLabel signatureLabel;
098: private SignatureUpdateAdapter sua;
099: private JLabel sizer;
100: private Dimension originalSize;
101:
102: /**
103: * Constructor for the ExtractMethodDialog object
104: *
105: *@param parent the parent frame
106: *@exception RefactoringException problem in setting up the refactoring
107: */
108: public ExtractMethodDialog(JFrame parent)
109: throws RefactoringException {
110: super (null, parent);
111:
112: sua = new SignatureUpdateAdapter(this );
113:
114: init();
115:
116: // Set the window size and layout
117: setTitle(getWindowTitle());
118:
119: GridBagLayout gridbag = new GridBagLayout();
120: GridBagConstraints gbc = new GridBagConstraints();
121: getContentPane().setLayout(gridbag);
122: setSize(310, 120);
123:
124: Insets zeroInsets = new Insets(0, 0, 0, 0);
125:
126: // Add components
127: int currentRow = 1;
128: JLabel newNameLabel = new JLabel(getLabelText());
129: gbc.gridx = 1;
130: gbc.gridy = currentRow;
131: gbc.gridwidth = 1;
132: gbc.gridheight = 1;
133: gbc.insets = new Insets(0, 0, 0, 10);
134: gridbag.setConstraints(newNameLabel, gbc);
135: getContentPane().add(newNameLabel);
136:
137: newName = new JTextField();
138: newName.setColumns(40);
139: newName.getDocument().addDocumentListener(sua);
140: newName.addFocusListener(sua);
141: gbc.gridx = 2;
142: gbc.gridy = currentRow;
143: gbc.gridwidth = 2;
144: gbc.gridheight = 1;
145: gbc.insets = zeroInsets;
146: gbc.fill = GridBagConstraints.HORIZONTAL;
147: gridbag.setConstraints(newName, gbc);
148: getContentPane().add(newName);
149:
150: currentRow++;
151:
152: JLabel parameterLabel = new JLabel("Parameters: ");
153: gbc.gridx = 1;
154: gbc.gridy = currentRow;
155: gbc.gridwidth = 2;
156: gbc.gridheight = 1;
157: gbc.insets = new Insets(10, 0, 0, 0);
158: getContentPane().add(parameterLabel, gbc);
159:
160: currentRow++;
161:
162: VariableSummary[] vs = emr.getParameters();
163: if (vs.length > 1) {
164: list = new OrderableList(vs, new VariableListCellRenderer());
165: list.addListDataListener(sua);
166: gbc.gridx = 1;
167: gbc.gridy = currentRow;
168: gbc.gridwidth = 3;
169: gbc.gridheight = 1;
170: gbc.insets = zeroInsets;
171: gbc.fill = GridBagConstraints.CENTER;
172: gridbag.setConstraints(list, gbc);
173: getContentPane().add(list);
174: } else {
175: JLabel label;
176: if (vs.length == 0) {
177: label = new JLabel(
178: "There are no parameters required for this method");
179: } else {
180: label = new JLabel(
181: "There is only one parameter required for this method: "
182: + vs[0].getName());
183: }
184:
185: list = null;
186: gbc.gridx = 1;
187: gbc.gridy = currentRow;
188: gbc.gridwidth = 3;
189: gbc.gridheight = 1;
190: gbc.insets = zeroInsets;
191: gbc.fill = GridBagConstraints.CENTER;
192: gridbag.setConstraints(label, gbc);
193: getContentPane().add(label);
194: }
195:
196: currentRow++;
197:
198: JPanel panel = initRadioButtons();
199: gbc.gridx = 1;
200: gbc.gridy = currentRow;
201: gbc.gridwidth = 3;
202: gbc.gridheight = 1;
203: gbc.insets = zeroInsets;
204: gbc.fill = GridBagConstraints.CENTER;
205: gridbag.setConstraints(panel, gbc);
206: getContentPane().add(panel);
207:
208: currentRow++;
209:
210: JLabel returnNameLabel = new JLabel("Return:");
211: gbc.gridx = 1;
212: gbc.gridy = currentRow;
213: gbc.gridwidth = 1;
214: gbc.gridheight = 1;
215: gbc.insets = new Insets(10, 0, 10, 10);
216: gridbag.setConstraints(returnNameLabel, gbc);
217: getContentPane().add(returnNameLabel);
218:
219: gbc.gridx = 2;
220: gbc.gridy = currentRow;
221: gbc.gridwidth = 2;
222: gbc.gridheight = 1;
223: gbc.insets = zeroInsets;
224: gbc.insets = new Insets(10, 0, 10, 0);
225: gbc.fill = GridBagConstraints.HORIZONTAL;
226:
227: if (emr.isStatement()) {
228: returnList = new JList(emr.getReturnTypes());
229: returnList.setSelectedIndex(0);
230: gridbag.setConstraints(returnList, gbc);
231: getContentPane().add(returnList);
232: returnList.addListSelectionListener(sua);
233: returnTextField = null;
234: } else {
235: returnTextField = new JTextField(emr.getReturnType()
236: .toString());
237: gridbag.setConstraints(returnTextField, gbc);
238: getContentPane().add(returnTextField);
239: returnTextField.getDocument().addDocumentListener(sua);
240: returnTextField.addFocusListener(sua);
241: returnList = null;
242: }
243:
244: currentRow++;
245:
246: JLabel signNameLabel = new JLabel("Signature:");
247: gbc.gridx = 1;
248: gbc.gridy = currentRow;
249: gbc.gridwidth = 1;
250: gbc.gridheight = 1;
251: gbc.insets = new Insets(10, 0, 10, 10);
252: gridbag.setConstraints(signNameLabel, gbc);
253: getContentPane().add(signNameLabel);
254:
255: signatureLabel = new JLabel("");
256: gbc.gridx = 2;
257: gbc.gridy = currentRow;
258: gbc.gridwidth = 2;
259: gbc.gridheight = 1;
260: gbc.insets = zeroInsets;
261: gbc.insets = new Insets(10, 0, 10, 0);
262: gbc.fill = GridBagConstraints.HORIZONTAL;
263: gridbag.setConstraints(signatureLabel, gbc);
264: getContentPane().add(signatureLabel);
265:
266: currentRow++;
267: JButton okButton = new JButton("OK");
268: gbc.gridx = 2;
269: gbc.gridy = currentRow;
270: gbc.gridwidth = 1;
271: gbc.gridheight = 1;
272: gbc.insets = zeroInsets;
273: gbc.fill = GridBagConstraints.NONE;
274: gridbag.setConstraints(okButton, gbc);
275: okButton.addActionListener(this );
276: getContentPane().add(okButton);
277:
278: JButton cancelButton = new JButton("Cancel");
279: gbc.gridx = 3;
280: gbc.gridy = currentRow;
281: gbc.gridwidth = 1;
282: gbc.gridheight = 1;
283: gridbag.setConstraints(cancelButton, gbc);
284: cancelButton.addActionListener(this );
285: getContentPane().add(cancelButton);
286:
287: update();
288:
289: pack();
290:
291: sizer = new JLabel();
292: originalSize = signatureLabel.getSize();
293:
294: CenterDialog.center(this , parent);
295: }
296:
297: /**
298: * Gets the WindowTitle attribute of the ExtractMethodDialog object
299: *
300: *@return The WindowTitle value
301: */
302: public String getWindowTitle() {
303: return "Extract Method Dialog";
304: }
305:
306: /**
307: * Gets the LabelText attribute of the ExtractMethodDialog object
308: *
309: *@return The LabelText value
310: */
311: public String getLabelText() {
312: return "Method name:";
313: }
314:
315: /**
316: * Performs the update to the signature line
317: */
318: public void update() {
319: createRefactoring();
320:
321: String signature = emr.getSignature();
322:
323: if (sizer != null) {
324: sizer.setText(signature);
325: Dimension current = sizer.getPreferredSize();
326: int length = signature.length();
327: while (current.width > originalSize.width) {
328: length--;
329: signature = signature.substring(0, length) + "...";
330: sizer.setText(signature);
331: current = sizer.getPreferredSize();
332: }
333: }
334:
335: signatureLabel.setText(signature);
336: }
337:
338: /**
339: * Sets the StringInIDE attribute of the ExtractMethodDialog object
340: *
341: *@param value The new StringInIDE value
342: */
343: protected abstract void setStringInIDE(String value);
344:
345: /**
346: * Gets the StringFromIDE attribute of the ExtractMethodDialog object
347: *
348: *@return The StringFromIDE value
349: */
350: protected abstract String getStringFromIDE();
351:
352: /**
353: * Gets the SelectionFromIDE attribute of the ExtractMethodDialog object
354: *
355: *@return The SelectionFromIDE value
356: */
357: protected abstract String getSelectionFromIDE();
358:
359: /**
360: * Follows up the refactoring by updating the text in the current window
361: *
362: *@param refactoring Description of Parameter
363: */
364: protected void followup(Refactoring refactoring) {
365: ExtractMethodRefactoring emr = (ExtractMethodRefactoring) refactoring;
366: setStringInIDE(emr.getFullFile());
367: }
368:
369: /**
370: * Creates the refactoring and fills in the data
371: *
372: *@return the extract method refactoring
373: */
374: protected Refactoring createRefactoring() {
375: emr.setMethodName(newName.getText());
376: if (list == null) {
377: // Don't need to set the parameter order!
378: } else {
379: emr.setParameterOrder(list.getData());
380: }
381:
382: int prot = ExtractMethodRefactoring.PRIVATE;
383: if (packageButton.isSelected()) {
384: prot = ExtractMethodRefactoring.PACKAGE;
385: }
386: if (protectedButton.isSelected()) {
387: prot = ExtractMethodRefactoring.PROTECTED;
388: }
389: if (publicButton.isSelected()) {
390: prot = ExtractMethodRefactoring.PUBLIC;
391: }
392: emr.setProtection(prot);
393:
394: if (returnTextField == null) {
395: Object result = returnList.getSelectedValue();
396: emr.setReturnType(result);
397: } else {
398: emr.setReturnType(returnTextField.getText());
399: }
400:
401: return emr;
402: }
403:
404: /**
405: * Initialize the extract method refactoring
406: *
407: *@exception RefactoringException Description of Exception
408: */
409: private void init() throws RefactoringException {
410: emr = RefactoringFactory.get().extractMethod();
411: String full = getStringFromIDE();
412: if (full == null) {
413: dispose();
414: throw new RefactoringException(
415: "Invalid file for extracting the source code");
416: } else {
417: emr.setFullFile(full);
418: }
419:
420: String selection = getSelectionFromIDE();
421: if (full == null) {
422: JOptionPane
423: .showMessageDialog(
424: null,
425: "You must select a series of statements or an expression to extract.",
426: "Extract Method Error",
427: JOptionPane.ERROR_MESSAGE);
428: dispose();
429: throw new RefactoringException("Empty selection.");
430: } else {
431: emr.setSelection(selection);
432: }
433:
434: emr.setMethodName("extractedMethod");
435: }
436:
437: /**
438: * Creates a panel of radio buttons with protection levels
439: *
440: *@return the panel
441: */
442: private JPanel initRadioButtons() {
443: JPanel panel = new JPanel();
444: panel.setLayout(new FlowLayout());
445: JLabel label = new JLabel("Protection:");
446: panel.add(label);
447:
448: ButtonGroup group = new ButtonGroup();
449:
450: privateButton = new JRadioButton("private");
451: privateButton.setSelected(true);
452: panel.add(privateButton);
453: group.add(privateButton);
454: privateButton.addActionListener(sua);
455:
456: packageButton = new JRadioButton("package");
457: panel.add(packageButton);
458: group.add(packageButton);
459: packageButton.addActionListener(sua);
460:
461: protectedButton = new JRadioButton("protected");
462: panel.add(protectedButton);
463: group.add(protectedButton);
464: protectedButton.addActionListener(sua);
465:
466: publicButton = new JRadioButton("public");
467: panel.add(publicButton);
468: group.add(publicButton);
469: publicButton.addActionListener(sua);
470:
471: panel.setBorder(BorderFactory.createEtchedBorder());
472:
473: return panel;
474: }
475: }
|