Java tutorial
/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Benjamin Muskalla <bmuskalla@eclipsesource.com> - [extract method] remember selected access modifier - https://bugs.eclipse.org/bugs/show_bug.cgi?id=101233 *******************************************************************************/ package ext.org.eclipse.jdt.internal.ui.refactoring.code; import java.util.Iterator; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.layout.PixelConverter; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.text.Document; import org.eclipse.ui.PlatformUI; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; import org.eclipse.jdt.core.dom.ClassInstanceCreation; import org.eclipse.jdt.core.dom.EnumConstantDeclaration; import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.ui.PreferenceConstants; import patch.org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration; import patch.org.eclipse.jdt.internal.ui.JavaPlugin; import ext.org.eclipse.jdt.internal.corext.dom.ASTNodes; import ext.org.eclipse.jdt.internal.corext.refactoring.ParameterInfo; import ext.org.eclipse.jdt.internal.corext.refactoring.code.ExtractMethodRefactoring; import ext.org.eclipse.jdt.internal.corext.util.Messages; import ext.org.eclipse.jdt.internal.ui.IJavaHelpContextIds; import ext.org.eclipse.jdt.internal.ui.JavaPluginImages; import ext.org.eclipse.jdt.internal.ui.dialogs.TextFieldNavigationHandler; import ext.org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer; import ext.org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; import ext.org.eclipse.jdt.internal.ui.refactoring.ChangeParametersControl; import ext.org.eclipse.jdt.internal.ui.refactoring.IParameterListChangeListener; import ext.org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages; import ext.org.eclipse.jdt.internal.ui.util.RowLayouter; import ext.org.eclipse.jdt.internal.ui.util.SWTUtil; import ext.org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; public class ExtractMethodInputPage extends UserInputWizardPage { public static final String PAGE_NAME = "ExtractMethodInputPage";//$NON-NLS-1$ private ExtractMethodRefactoring fRefactoring; private Text fTextField; private boolean fFirstTime; private JavaSourceViewer fSignaturePreview; private Document fSignaturePreviewDocument; private IDialogSettings fSettings; private static final String DESCRIPTION = RefactoringMessages.ExtractMethodInputPage_description; private static final String THROW_RUNTIME_EXCEPTIONS = "ThrowRuntimeExceptions"; //$NON-NLS-1$ private static final String GENERATE_JAVADOC = "GenerateJavadoc"; //$NON-NLS-1$ private static final String ACCESS_MODIFIER = "AccessModifier"; //$NON-NLS-1$ public ExtractMethodInputPage() { super(PAGE_NAME); setImageDescriptor(JavaPluginImages.DESC_WIZBAN_REFACTOR_CU); setDescription(DESCRIPTION); fFirstTime = true; fSignaturePreviewDocument = new Document(); } public void createControl(Composite parent) { fRefactoring = (ExtractMethodRefactoring) getRefactoring(); loadSettings(); Composite result = new Composite(parent, SWT.NONE); setControl(result); GridLayout layout = new GridLayout(); layout.numColumns = 2; result.setLayout(layout); RowLayouter layouter = new RowLayouter(2); GridData gd = null; initializeDialogUnits(result); Label label = new Label(result, SWT.NONE); label.setText(getLabelText()); fTextField = createTextInputField(result, SWT.BORDER); fTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); layouter.perform(label, fTextField, 1); ASTNode[] destinations = fRefactoring.getDestinations(); if (destinations.length > 1) { label = new Label(result, SWT.NONE); label.setText(RefactoringMessages.ExtractMethodInputPage_destination_type); final Combo combo = new Combo(result, SWT.READ_ONLY | SWT.DROP_DOWN); SWTUtil.setDefaultVisibleItemCount(combo); for (int i = 0; i < destinations.length; i++) { ASTNode declaration = destinations[i]; combo.add(getLabel(declaration)); } combo.select(0); combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); combo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { fRefactoring.setDestination(combo.getSelectionIndex()); updatePreview(getText()); } }); } label = new Label(result, SWT.NONE); label.setText(RefactoringMessages.ExtractMethodInputPage_access_Modifiers); Composite group = new Composite(result, SWT.NONE); group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); layout = new GridLayout(); layout.numColumns = 4; layout.marginWidth = 0; group.setLayout(layout); String[] labels = new String[] { RefactoringMessages.ExtractMethodInputPage_public, RefactoringMessages.ExtractMethodInputPage_protected, RefactoringMessages.ExtractMethodInputPage_default, RefactoringMessages.ExtractMethodInputPage_private }; Integer[] data = new Integer[] { new Integer(Modifier.PUBLIC), new Integer(Modifier.PROTECTED), new Integer(Modifier.NONE), new Integer(Modifier.PRIVATE) }; Integer visibility = new Integer(fRefactoring.getVisibility()); for (int i = 0; i < labels.length; i++) { Button radio = new Button(group, SWT.RADIO); radio.setText(labels[i]); radio.setData(data[i]); if (data[i].equals(visibility)) radio.setSelection(true); radio.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { final Integer selectedModifier = (Integer) event.widget.getData(); fSettings.put(ACCESS_MODIFIER, selectedModifier.intValue()); setVisibility(selectedModifier); } }); } layouter.perform(label, group, 1); if (!fRefactoring.getParameterInfos().isEmpty()) { ChangeParametersControl cp = new ChangeParametersControl(result, SWT.NONE, RefactoringMessages.ExtractMethodInputPage_parameters, new IParameterListChangeListener() { public void parameterChanged(ParameterInfo parameter) { parameterModified(); } public void parameterListChanged() { parameterModified(); } public void parameterAdded(ParameterInfo parameter) { updatePreview(getText()); } }, ChangeParametersControl.Mode.EXTRACT_METHOD); gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 2; cp.setLayoutData(gd); cp.setInput(fRefactoring.getParameterInfos()); } Button checkBox = new Button(result, SWT.CHECK); checkBox.setText(RefactoringMessages.ExtractMethodInputPage_throwRuntimeExceptions); checkBox.setSelection(fSettings.getBoolean(THROW_RUNTIME_EXCEPTIONS)); checkBox.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { setRethrowRuntimeException(((Button) e.widget).getSelection()); } }); layouter.perform(checkBox); checkBox = new Button(result, SWT.CHECK); checkBox.setText(RefactoringMessages.ExtractMethodInputPage_generateJavadocComment); boolean generate = computeGenerateJavadoc(); setGenerateJavadoc(generate); checkBox.setSelection(generate); checkBox.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { setGenerateJavadoc(((Button) e.widget).getSelection()); } }); layouter.perform(checkBox); int duplicates = fRefactoring.getNumberOfDuplicates(); checkBox = new Button(result, SWT.CHECK); if (duplicates == 0) { checkBox.setText(RefactoringMessages.ExtractMethodInputPage_duplicates_none); } else if (duplicates == 1) { checkBox.setText(RefactoringMessages.ExtractMethodInputPage_duplicates_single); } else { checkBox.setText(Messages.format(RefactoringMessages.ExtractMethodInputPage_duplicates_multi, new Integer(duplicates))); } checkBox.setSelection(fRefactoring.getReplaceDuplicates()); checkBox.setEnabled(duplicates > 0); checkBox.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { fRefactoring.setReplaceDuplicates(((Button) e.widget).getSelection()); } }); layouter.perform(checkBox); label = new Label(result, SWT.SEPARATOR | SWT.HORIZONTAL); label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); layouter.perform(label); createSignaturePreview(result, layouter); Dialog.applyDialogFont(result); PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaHelpContextIds.EXTRACT_METHOD_WIZARD_PAGE); } private String getLabel(ASTNode node) { if (node instanceof AbstractTypeDeclaration) { return ((AbstractTypeDeclaration) node).getName().getIdentifier(); } else if (node instanceof AnonymousClassDeclaration) { if (node.getLocationInParent() == ClassInstanceCreation.ANONYMOUS_CLASS_DECLARATION_PROPERTY) { ClassInstanceCreation creation = (ClassInstanceCreation) node.getParent(); return Messages.format(RefactoringMessages.ExtractMethodInputPage_anonymous_type_label, BasicElementLabels.getJavaElementName(ASTNodes.asString(creation.getType()))); } else if (node.getLocationInParent() == EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY) { EnumConstantDeclaration decl = (EnumConstantDeclaration) node.getParent(); return decl.getName().getIdentifier(); } } return "UNKNOWN"; //$NON-NLS-1$ } private Text createTextInputField(Composite parent, int style) { Text result = new Text(parent, style); result.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { textModified(getText()); } }); TextFieldNavigationHandler.install(result); return result; } private String getText() { if (fTextField == null) return null; return fTextField.getText(); } private String getLabelText() { return RefactoringMessages.ExtractMethodInputPage_label_text; } private void setVisibility(Integer visibility) { fRefactoring.setVisibility(visibility.intValue()); updatePreview(getText()); } private void setRethrowRuntimeException(boolean value) { fSettings.put(THROW_RUNTIME_EXCEPTIONS, value); fRefactoring.setThrowRuntimeExceptions(value); updatePreview(getText()); } private boolean computeGenerateJavadoc() { boolean result = fRefactoring.getGenerateJavadoc(); if (result) return result; return fSettings.getBoolean(GENERATE_JAVADOC); } private void setGenerateJavadoc(boolean value) { fSettings.put(GENERATE_JAVADOC, value); fRefactoring.setGenerateJavadoc(value); } private void createSignaturePreview(Composite composite, RowLayouter layouter) { Label previewLabel = new Label(composite, SWT.NONE); previewLabel.setText(RefactoringMessages.ExtractMethodInputPage_signature_preview); layouter.perform(previewLabel); IPreferenceStore store = JavaPlugin.getDefault().getCombinedPreferenceStore(); fSignaturePreview = new JavaSourceViewer(composite, null, null, false, SWT.READ_ONLY | SWT.V_SCROLL | SWT.WRAP /*| SWT.BORDER*/, store); fSignaturePreview.configure(new JavaSourceViewerConfiguration( JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null)); fSignaturePreview.getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT)); fSignaturePreview.adaptBackgroundColor(composite); fSignaturePreview.setDocument(fSignaturePreviewDocument); fSignaturePreview.setEditable(false); //Layouting problems with wrapped text: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=9866 Control signaturePreviewControl = fSignaturePreview.getControl(); PixelConverter pixelConverter = new PixelConverter(signaturePreviewControl); GridData gdata = new GridData(GridData.FILL_BOTH); gdata.widthHint = pixelConverter.convertWidthInCharsToPixels(50); gdata.heightHint = pixelConverter.convertHeightInCharsToPixels(2); signaturePreviewControl.setLayoutData(gdata); layouter.perform(signaturePreviewControl); } private void updatePreview(String text) { if (fSignaturePreview == null) return; if (text.length() == 0) text = "someMethodName"; //$NON-NLS-1$ int top = fSignaturePreview.getTextWidget().getTopPixel(); String signature; try { signature = fRefactoring.getSignature(text); } catch (IllegalArgumentException e) { signature = ""; //$NON-NLS-1$ } fSignaturePreviewDocument.set(signature); fSignaturePreview.getTextWidget().setTopPixel(top); } private void loadSettings() { fSettings = getDialogSettings().getSection(ExtractMethodWizard.DIALOG_SETTING_SECTION); if (fSettings == null) { fSettings = getDialogSettings().addNewSection(ExtractMethodWizard.DIALOG_SETTING_SECTION); fSettings.put(THROW_RUNTIME_EXCEPTIONS, false); fSettings.put(GENERATE_JAVADOC, JavaPreferencesSettings .getCodeGenerationSettings(fRefactoring.getCompilationUnit().getJavaProject()).createComments); fSettings.put(ACCESS_MODIFIER, Modifier.PRIVATE); } fRefactoring.setThrowRuntimeExceptions(fSettings.getBoolean(THROW_RUNTIME_EXCEPTIONS)); final String accessModifier = fSettings.get(ACCESS_MODIFIER); if (accessModifier != null) { fRefactoring.setVisibility(Integer.parseInt(accessModifier)); } } //---- Input validation ------------------------------------------------------ @Override public void setVisible(boolean visible) { if (visible) { if (fFirstTime) { fFirstTime = false; setPageComplete(false); updatePreview(getText()); fTextField.setFocus(); } else { setPageComplete(validatePage(true)); } } super.setVisible(visible); } private void textModified(String text) { fRefactoring.setMethodName(text); RefactoringStatus status = validatePage(true); if (!status.hasFatalError()) { updatePreview(text); } else { fSignaturePreviewDocument.set(""); //$NON-NLS-1$ } setPageComplete(status); } private void parameterModified() { updatePreview(getText()); setPageComplete(validatePage(false)); } private RefactoringStatus validatePage(boolean text) { RefactoringStatus result = new RefactoringStatus(); if (text) { result.merge(validateMethodName()); result.merge(validateParameters()); } else { result.merge(validateParameters()); result.merge(validateMethodName()); } return result; } private RefactoringStatus validateMethodName() { RefactoringStatus result = new RefactoringStatus(); String text = getText(); if ("".equals(text)) { //$NON-NLS-1$ result.addFatalError(RefactoringMessages.ExtractMethodInputPage_validation_emptyMethodName); return result; } result.merge(fRefactoring.checkMethodName()); return result; } private RefactoringStatus validateParameters() { RefactoringStatus result = new RefactoringStatus(); List<ParameterInfo> parameters = fRefactoring.getParameterInfos(); for (Iterator<ParameterInfo> iter = parameters.iterator(); iter.hasNext();) { ParameterInfo info = iter.next(); if ("".equals(info.getNewName())) { //$NON-NLS-1$ result.addFatalError(RefactoringMessages.ExtractMethodInputPage_validation_emptyParameterName); return result; } } result.merge(fRefactoring.checkParameterNames()); result.merge(fRefactoring.checkVarargOrder()); return result; } }