Java tutorial
/******************************************************************************* * Copyright (c) 2008, 2011 Mateusz Matela 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: * Mateusz Matela <mateusz.matela@gmail.com> - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070 * Mateusz Matela <mateusz.matela@gmail.com> - [toString] Template edit dialog has usability issues - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267916 * Mateusz Matela <mateusz.matela@gmail.com> - [toString] finish toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=267710 * Mateusz Matela <mateusz.matela@gmail.com> - [toString] toString() generator: Fields in declaration order - https://bugs.eclipse.org/bugs/show_bug.cgi?id=279924 *******************************************************************************/ package ext.org.eclipse.jdt.internal.ui.dialogs; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import com.ibm.icu.text.Collator; import ext.org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.GenerateToStringOperation; import ext.org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringGenerationSettings; import ext.org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringTemplateParser; import ext.org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringGenerationSettings.CustomBuilderSettings; import ext.org.eclipse.jdt.internal.corext.util.JavaConventionsUtil; import ext.org.eclipse.jdt.internal.corext.util.JavaModelUtil; 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.JavaUIMessages; import ext.org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; import ext.org.eclipse.jdt.internal.ui.util.SWTUtil; import ext.org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider; import ext.org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider; import ext.org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil; 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.events.SelectionListener; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowLayout; 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.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Spinner; import org.eclipse.swt.widgets.Text; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.StatusDialog; import org.eclipse.jface.fieldassist.IContentProposal; import org.eclipse.jface.fieldassist.IContentProposalProvider; import org.eclipse.jface.fieldassist.TextContentAdapter; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ISelectionStatusValidator; import org.eclipse.ui.dialogs.SelectionDialog; import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.IVariableBinding; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.ui.IJavaElementSearchConstants; import org.eclipse.jdt.ui.JavaElementImageDescriptor; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jdt.ui.dialogs.TypeSelectionExtension; import patch.org.eclipse.jdt.internal.ui.JavaPlugin; /** * Dialog for the generate toString() action. * * @since 3.5 */ public class GenerateToStringDialog extends SourceActionDialog { private static class GenerateToStringContentProvider implements ITreeContentProvider { private static final Object[] EMPTY = new Object[0]; private IVariableBinding[] fFields; private IMethodBinding[] fMethods; private IVariableBinding[] fInheritedFields; private IMethodBinding[] fInheritedMethods; private String[] mainNodes; private static final String fieldsNode = JavaUIMessages.GenerateToStringDialog_fields_node; private static final String methodsNode = JavaUIMessages.GenerateToStringDialog_methods_node; private static final String inheritedFieldsNode = JavaUIMessages.GenerateToStringDialog_inherited_fields_node; private static final String inheritedMethodsNode = JavaUIMessages.GenerateToStringDialog_inherited_methods_node; public GenerateToStringContentProvider(IVariableBinding[] fields, IVariableBinding[] inheritedFields, IMethodBinding[] methods, IMethodBinding[] inheritedMethods) { ArrayList<String> nodes = new ArrayList<String>(); fFields = fields.clone(); if (fFields.length > 0) nodes.add(fieldsNode); fInheritedFields = inheritedFields.clone(); if (fInheritedFields.length > 0) nodes.add(inheritedFieldsNode); fMethods = methods.clone(); if (fMethods.length > 0) nodes.add(methodsNode); fInheritedMethods = inheritedMethods.clone(); if (fInheritedMethods.length > 0) nodes.add(inheritedMethodsNode); mainNodes = nodes.toArray(new String[nodes.size()]); } private int getElementPosition(Object element, Object[] array) { for (int i = 0; i < array.length; i++) { if (array[i].equals(element)) { return i; } } return -1; } private Object[] getContainingArray(Object element) { if (element instanceof String) return mainNodes; if (element instanceof IVariableBinding) { if (getElementPosition(element, fFields) >= 0) return fFields; if (getElementPosition(element, fInheritedFields) >= 0) return fInheritedFields; } if (element instanceof IMethodBinding) { if (getElementPosition(element, fMethods) >= 0) return fMethods; if (getElementPosition(element, fInheritedMethods) >= 0) return fInheritedMethods; } return EMPTY; } public boolean canMoveDown(Object element) { Object[] array = getContainingArray(element); int position = getElementPosition(element, array); return position != -1 && position != array.length - 1; } public boolean canMoveUp(Object element) { return getElementPosition(element, getContainingArray(element)) > 0; } public void down(Object element, CheckboxTreeViewer tree) { move(element, tree, 1); } public void up(Object element, CheckboxTreeViewer tree) { move(element, tree, -1); } private void move(Object element, CheckboxTreeViewer tree, int direction) { Object[] array = getContainingArray(element); int position = getElementPosition(element, array); Object temp = array[position]; array[position] = array[position + direction]; array[position + direction] = temp; tree.setSelection(new StructuredSelection(element)); tree.refresh(); } public void sort() { Comparator<IBinding> comparator = new Comparator<IBinding>() { Collator collator = Collator.getInstance(); public int compare(IBinding b1, IBinding b2) { return collator.compare(b1.getName(), b2.getName()); } }; Arrays.sort(fFields, comparator); Arrays.sort(fMethods, comparator); Arrays.sort(fInheritedFields, comparator); Arrays.sort(fInheritedMethods, comparator); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) */ public Object[] getChildren(Object parentElement) { if (parentElement == fieldsNode) return fFields; if (parentElement == inheritedFieldsNode) return fInheritedFields; if (parentElement == methodsNode) return fMethods; if (parentElement == inheritedMethodsNode) return fInheritedMethods; return EMPTY; } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) */ public Object getParent(Object element) { Object[] array = getContainingArray(element); if (array == fFields) return fieldsNode; if (array == fInheritedFields) return inheritedFieldsNode; if (array == fMethods) return methodsNode; if (array == fInheritedMethods) return inheritedMethodsNode; return null; } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) */ public boolean hasChildren(Object element) { if (element instanceof String) return true; return false; } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) */ public Object[] getElements(Object inputElement) { return mainNodes; } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.IContentProvider#dispose() */ public void dispose() { } /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, * java.lang.Object, java.lang.Object) */ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } private static class GenerateToStringLabelProvider extends BindingLabelProvider { @Override public Image getImage(Object element) { ImageDescriptor descriptor = null; if (element == GenerateToStringContentProvider.fieldsNode || element == GenerateToStringContentProvider.inheritedFieldsNode) descriptor = JavaPluginImages.DESC_FIELD_PUBLIC; if (element == GenerateToStringContentProvider.methodsNode || element == GenerateToStringContentProvider.inheritedMethodsNode) descriptor = JavaPluginImages.DESC_MISC_PUBLIC; if (descriptor != null) { descriptor = new JavaElementImageDescriptor(descriptor, 0, JavaElementImageProvider.BIG_SIZE); return JavaPlugin.getImageDescriptorRegistry().get(descriptor); } return super.getImage(element); } } private class GenerateToStringValidator implements ISelectionStatusValidator { private int fNumFields; private int fNumMethods; private CustomBuilderValidator fValidator; public GenerateToStringValidator(int fields, int methods) { fNumFields = fields; fNumMethods = methods; } public IStatus validate(Object[] selection) { if (getGenerationSettings().toStringStyle == GenerateToStringOperation.CUSTOM_BUILDER) { if (fValidator == null) fValidator = new CustomBuilderValidator(getType().getJavaProject()); IStatus status = fValidator.revalidateAll(getGenerationSettings().getCustomBuilderSettings()); if (!status.isOK()) return new StatusInfo(IStatus.ERROR, JavaUIMessages.GenerateToStringDialog_selectioninfo_customBuilderConfigError); } int countFields = 0, countMethods = 0; for (int index = 0; index < selection.length; index++) { if (selection[index] instanceof IVariableBinding) countFields++; else if (selection[index] instanceof IMethodBinding) countMethods++; } return new StatusInfo(IStatus.INFO, Messages.format(JavaUIMessages.GenerateToStringDialog_selectioninfo_more, new String[] { String.valueOf(countFields), String.valueOf(fNumFields), String.valueOf(countMethods), String.valueOf(fNumMethods) })); } } private class ToStringTemplatesDialog extends StatusDialog { private class TemplateEditionDialog extends StatusDialog { /** * Template number, -1 for new template. */ private final int templateNumber; /** * Initial template name, can be <code>null</code>. */ private final String fInitialTemplateName; private Text templateName; private Text template; private String resultTemplateName; private String resultTemplate; private StatusInfo nameValidationStatus = new StatusInfo(); public TemplateEditionDialog(Shell parent, int templateNumber) { super(parent); this.templateNumber = templateNumber; fInitialTemplateName = templateNumber < 0 ? null : templateNames.get(templateNumber); setHelpAvailable(false); } @Override protected boolean isResizable() { return true; } @Override protected Control createDialogArea(Composite parent) { getShell().setText( templateNumber >= 0 ? JavaUIMessages.GenerateToStringDialog_templateEdition_WindowTitle : JavaUIMessages.GenerateToStringDialog_templateEdition_NewWindowTitle); Composite composite = (Composite) super.createDialogArea(parent); GridLayout layout = (GridLayout) composite.getLayout(); layout.numColumns = 2; layout.horizontalSpacing = 8; Label label = new Label(composite, SWT.LEFT); label.setText(JavaUIMessages.GenerateToStringDialog_template_name); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); templateName = new Text(composite, SWT.BORDER | SWT.SINGLE); templateName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); label = new Label(composite, SWT.LEFT); label.setText(JavaUIMessages.GenerateToStringDialog_template_content); label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); template = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); gridData.heightHint = 80; gridData.widthHint = 480; template.setLayoutData(gridData); new ContentAssistCommandAdapter(template, new TextContentAdapter(), new ToStringTemplateProposalProvider(), null, new char[] { '$' }, true) .setPropagateKeys(false); if (templateNumber >= 0) { templateName.setText(fInitialTemplateName); template.setText(templates.get(templateNumber)); } else { templateName.setText(createNewTemplateName()); template.setText(ToStringTemplateParser.DEFAULT_TEMPLATE); } templateName.setSelection(0, templateName.getText().length()); templateName.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { validate(templateName.getText()); } }); //Ctrl+Enter should execute the default button, workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=145959 template.addTraverseListener(new TraverseListener() { public void keyTraversed(TraverseEvent e) { if (e.detail == SWT.TRAVERSE_RETURN && (e.stateMask & SWT.MODIFIER_MASK) != 0) { buttonPressed(((Integer) getShell().getDefaultButton().getData()).intValue()); } } }); return composite; } private void validate(String newName) { if (newName.length() == 0) { nameValidationStatus.setError( JavaUIMessages.GenerateToStringDialog_templateEdition_TemplateNameEmptyErrorMessage); } else if (!newName.equals(fInitialTemplateName) && templateNames.contains(newName)) { nameValidationStatus.setError( JavaUIMessages.GenerateToStringDialog_templateEdition_TemplateNameDuplicateErrorMessage); } else { nameValidationStatus.setOK(); } updateStatus(nameValidationStatus); } private String createNewTemplateName() { if (!templateNames.contains(JavaUIMessages.GenerateToStringDialog_newTemplateName)) return JavaUIMessages.GenerateToStringDialog_newTemplateName; int copyCount = 2; String newName; do { newName = Messages.format(JavaUIMessages.GenerateToStringDialog_newTemplateNameArg, new Integer(copyCount)); copyCount++; } while (templateNames.contains(newName)); return newName; } @Override public boolean close() { resultTemplateName = templateName.getText(); resultTemplate = fixLineBreaks(template.getText()); return super.close(); } public String getTemplateName() { return resultTemplateName; } public String getTemplate() { return resultTemplate; } private String fixLineBreaks(String input) { String systemLineDelimiter = Text.DELIMITER; final String javaLineDelimiter = "\n"; //$NON-NLS-1$ if (!systemLineDelimiter.equals(javaLineDelimiter)) { StringBuffer outputBuffer = new StringBuffer(input); int pos = outputBuffer.indexOf(systemLineDelimiter); while (pos >= 0) { outputBuffer.delete(pos, pos + systemLineDelimiter.length()); outputBuffer.insert(pos, javaLineDelimiter); pos = outputBuffer.indexOf(systemLineDelimiter, pos + javaLineDelimiter.length()); } return outputBuffer.toString(); } return input; } } private class ToStringTemplateProposalProvider implements IContentProposalProvider { private class Proposal implements IContentProposal { final private String proposal; private int position; public Proposal(String proposal) { this.proposal = proposal; this.position = proposal.length(); } public String getContent() { int overlap = stringOverlap(latestContents.substring(0, latestPosition), proposal); position = proposal.length() - overlap; return proposal.substring(overlap); } public int getCursorPosition() { return position; } public String getDescription() { return parser.getVariableDescriptions().get(proposal); } public String getLabel() { return proposal; } } private String latestContents; private int latestPosition; public IContentProposal[] getProposals(String contents, int position) { List<Proposal> primaryProposals = new ArrayList<Proposal>(); List<Proposal> secondaryProposals = new ArrayList<Proposal>(); String[] proposalStrings = parser.getVariables(); String contentToCursor = contents.substring(0, position); for (int i = 0; i < proposalStrings.length; i++) { if (stringOverlap(contentToCursor, proposalStrings[i]) > 0) primaryProposals.add(new Proposal(proposalStrings[i])); else secondaryProposals.add(new Proposal(proposalStrings[i])); } this.latestContents = contents; this.latestPosition = position; primaryProposals.addAll(secondaryProposals); return primaryProposals.toArray(new IContentProposal[0]); } /** * Checks if the end of the first string is equal to the beginning of of the second * string. * * @param s1 first String * @param s2 second String * @return length of overlapping segment (0 if strings don't overlap) */ private int stringOverlap(String s1, String s2) { int l1 = s1.length(); for (int l = 1; l <= Math.min(s1.length(), s2.length()); l++) { boolean ok = true; for (int i = 0; i < l; i++) { if (s1.charAt(l1 - l + i) != s2.charAt(i)) { ok = false; break; } } if (ok) return l; } return 0; } } private final int ADD_BUTTON = IDialogConstants.CLIENT_ID + 1; private final int REMOVE_BUTTON = IDialogConstants.CLIENT_ID + 2; private final int APPLY_BUTTON = IDialogConstants.CLIENT_ID + 3; private final int EDIT_BUTTON = IDialogConstants.CLIENT_ID + 4; private Text templateTextControl; private org.eclipse.swt.widgets.List templateNameControl; private ToStringTemplateParser parser; private List<String> templateNames; private List<String> templates; private int selectedTemplateNumber; private boolean somethingChanged = false; private StatusInfo validationStatus = new StatusInfo(); protected ToStringTemplatesDialog(Shell parentShell, ToStringTemplateParser parser) { super(parentShell); this.parser = parser; this.setShellStyle(this.getShellStyle() | SWT.RESIZE); this.create(); PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), IJavaHelpContextIds.GENERATE_TOSTRING_MANAGE_TEMPLATES_DIALOG); } @Override protected Control createDialogArea(Composite parent) { getShell().setText(JavaUIMessages.GenerateToStringDialog_templatesManagerTitle); Composite composite = (Composite) super.createDialogArea(parent); Label label = new Label(composite, SWT.LEFT); label.setText(JavaUIMessages.GenerateToStringDialog_templatesManagerTemplatesList); Composite templatesComposite = new Composite(composite, SWT.NONE); templatesComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout gl = new GridLayout(2, false); gl.marginWidth = gl.marginHeight = 0; templatesComposite.setLayout(gl); templateNameControl = new org.eclipse.swt.widgets.List(templatesComposite, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL); templateNameControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite rightComposite = new Composite(templatesComposite, SWT.NONE); gl = new GridLayout(); gl.marginWidth = gl.marginHeight = 0; rightComposite.setLayout(gl); rightComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); createButton(rightComposite, ADD_BUTTON, JavaUIMessages.GenerateToStringDialog_templatesManagerNewButton, false); createButton(rightComposite, REMOVE_BUTTON, JavaUIMessages.GenerateToStringDialog_templatesManagerRemoveButton, false); createButton(rightComposite, EDIT_BUTTON, JavaUIMessages.GenerateToStringDialog_teplatesManagerEditButton, false); ((GridLayout) rightComposite.getLayout()).numColumns = 1; label = new Label(composite, SWT.LEFT); label.setText(JavaUIMessages.GenerateToStringDialog_templatesManagerPreview); templateTextControl = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); gd.heightHint = 80; gd.widthHint = 450; templateTextControl.setLayoutData(gd); templateNames = new ArrayList<String>(Arrays.asList(getTemplateNames())); templates = new ArrayList<String>(Arrays.asList(getTemplates(getDialogSettings()))); selectedTemplateNumber = getGenerationSettings().stringFormatTemplateNumber; refreshControls(); templateNameControl.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { onEdit(); } public void widgetSelected(SelectionEvent e) { if (templateNameControl.getSelectionIndex() >= 0) { selectedTemplateNumber = templateNameControl.getSelectionIndex(); templateTextControl.setText(templates.get(selectedTemplateNumber)); } } }); applyDialogFont(composite); return composite; } @Override protected void createButtonsForButtonBar(Composite parent) { super.createButtonsForButtonBar(parent); createButton(parent, APPLY_BUTTON, JavaUIMessages.GenerateToStringDialog_templateManagerApplyButton, false).setEnabled(false); } private void applyChanges() { getDialogSettings().put(ToStringGenerationSettings.SETTINGS_TEMPLATE_NAMES, templateNames.toArray(new String[0])); getDialogSettings().put(ToStringGenerationSettings.SETTINGS_TEMPLATES, templates.toArray(new String[0])); getGenerationSettings().stringFormatTemplateNumber = Math.max(selectedTemplateNumber, 0); somethingChanged = false; getButton(APPLY_BUTTON).setEnabled(false); } @Override protected void buttonPressed(int buttonId) { switch (buttonId) { case APPLY_BUTTON: applyChanges(); break; case IDialogConstants.OK_ID: applyChanges(); close(); break; case IDialogConstants.CANCEL_ID: close(); break; case ADD_BUTTON: TemplateEditionDialog dialog = new TemplateEditionDialog(getShell(), -1); dialog.open(); if (dialog.getReturnCode() == IDialogConstants.OK_ID) { templateNames.add(dialog.getTemplateName()); templates.add(dialog.getTemplate()); selectedTemplateNumber = templateNames.size() - 1; somethingChanged = true; refreshControls(); } break; case REMOVE_BUTTON: if (templateNames.size() > 0) { templateNames.remove(selectedTemplateNumber); templates.remove(selectedTemplateNumber); } if (selectedTemplateNumber >= templateNames.size()) selectedTemplateNumber = templateNames.size() - 1; somethingChanged = true; refreshControls(); break; case EDIT_BUTTON: onEdit(); } } private void onEdit() { TemplateEditionDialog dialog; dialog = new TemplateEditionDialog(getShell(), selectedTemplateNumber); dialog.open(); if (dialog.getReturnCode() == IDialogConstants.OK_ID) { templateNames.set(selectedTemplateNumber, dialog.getTemplateName()); templates.set(selectedTemplateNumber, dialog.getTemplate()); somethingChanged = true; refreshControls(); } } public void refreshControls() { templateNameControl.setItems(templateNames.toArray(new String[0])); if (templateNames.size() > 0) { templateNameControl.select(selectedTemplateNumber); templateTextControl.setText(templates.get(selectedTemplateNumber)); } else { templateTextControl.setText(""); //$NON-NLS-1$ } revalidate(); if (getButton(APPLY_BUTTON) != null) getButton(APPLY_BUTTON) .setEnabled(somethingChanged && getButton(IDialogConstants.OK_ID).getEnabled()); if (getButton(REMOVE_BUTTON) != null) getButton(REMOVE_BUTTON).setEnabled(templateNames.size() > 0); if (getButton(EDIT_BUTTON) != null) getButton(EDIT_BUTTON).setEnabled(templateNames.size() > 0); } private void revalidate() { if (templateNames.size() > 0) validationStatus.setOK(); else validationStatus .setError(JavaUIMessages.GenerateToStringDialog_templateManagerNoTemplateErrorMessage); updateStatus(validationStatus); } } private static class CustomBuilderValidator implements ISelectionStatusValidator { private final IJavaProject fJavaProject; private IType fLastValidBuilderType; private List<String> fLastValidAppendMethodSuggestions; private List<String> fLastValidResultMethodSuggestions; public CustomBuilderValidator(IJavaProject javaProject) { fJavaProject = javaProject; } public IStatus validateBuilderType(IType type) { if (fLastValidBuilderType != null && fLastValidBuilderType.equals(type)) { return new StatusInfo(); } try { IMethod[] methods = type.getMethods(); boolean foundConstructor = false; for (int i = 0; i < methods.length; i++) { if (methods[i].isConstructor() && Flags.isPublic(methods[i].getFlags())) { String[] parameterTypes = methods[i].getParameterTypes(); if (parameterTypes.length == 1 && "java.lang.Object" //$NON-NLS-1$ .equals(JavaModelUtil.getResolvedTypeName(parameterTypes[0], type))) { foundConstructor = true; break; } } } if (!foundConstructor) return new StatusInfo(IStatus.ERROR, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_noConstructorError); List<String> appendMethodSuggestions = getAppendMethodSuggestions(type); if (appendMethodSuggestions.isEmpty()) return new StatusInfo(IStatus.ERROR, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_noAppendMethodError); List<String> resultMethodSuggestions = getResultMethodSuggestions(type); if (resultMethodSuggestions.isEmpty()) return new StatusInfo(IStatus.ERROR, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_noResultMethodError); fLastValidBuilderType = type; fLastValidAppendMethodSuggestions = appendMethodSuggestions; fLastValidResultMethodSuggestions = resultMethodSuggestions; return new StatusInfo(); } catch (JavaModelException e1) { return new StatusInfo(IStatus.WARNING, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_typeValidationError); } } public IStatus validate(Object[] selection) { return validateBuilderType(((IType) selection[0])); } public IStatus revalidateAll(CustomBuilderSettings builderSettings) { try { if (builderSettings.className.length() == 0) { return new StatusInfo(IStatus.ERROR, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_noBuilderClassError); } IType type = findType(builderSettings.className); if (type == null || !type.exists()) { return new StatusInfo(IStatus.ERROR, MessageFormat.format( JavaUIMessages.GenerateToStringDialog_customBuilderConfig_invalidClassError, new Object[] { builderSettings.className })); } IStatus typeValidation = validateBuilderType(type); if (!typeValidation.isOK()) return typeValidation; if (!getAppendMethodSuggestions(type).contains(builderSettings.appendMethod)) return new StatusInfo(IStatus.ERROR, MessageFormat.format( JavaUIMessages.GenerateToStringDialog_customBuilderConfig_invalidAppendMethodError, new Object[] { builderSettings.appendMethod })); if (!getResultMethodSuggestions(type).contains(builderSettings.resultMethod)) return new StatusInfo(IStatus.ERROR, MessageFormat.format( JavaUIMessages.GenerateToStringDialog_customBuilderConfig_invalidResultMethodError, new Object[] { builderSettings.resultMethod })); if (!isValidJavaIdentifier(builderSettings.variableName)) return new StatusInfo(IStatus.ERROR, MessageFormat.format( JavaUIMessages.GenerateToStringDialog_customBuilderConfig_invalidVariableNameError, new Object[] { builderSettings.variableName })); } catch (JavaModelException e) { return new StatusInfo(IStatus.WARNING, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_dataValidationError); } return new StatusInfo(); } public IType findType(String builderClassName) throws JavaModelException { if (fLastValidBuilderType != null && builderClassName.equals(fLastValidBuilderType.getFullyQualifiedParameterizedName())) { return fLastValidBuilderType; } return fJavaProject.findType(builderClassName, (IProgressMonitor) null); } public List<String> getAppendMethodSuggestions(final IType type) throws JavaModelException { if (fLastValidBuilderType != null && fLastValidBuilderType.equals(type)) { return fLastValidAppendMethodSuggestions; } return getMethodSuggestions(type, new MethodChecker() { public boolean isMethodOK(IMethod method) throws JavaModelException { if (!Flags.isPublic(method.getFlags()) || method.isConstructor()) return false; /* To be an append method, it must take exactly one * Object parameter, and optionally one String parameter. */ String[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length == 0 || parameterTypes.length > 2) { return false; } int countObjects = 0, countStrings = 0; for (int i = 0; i < parameterTypes.length; i++) { String resolvedParameterTypeName = JavaModelUtil.getResolvedTypeName(parameterTypes[i], type); if ("java.lang.Object".equals(resolvedParameterTypeName))//$NON-NLS-1$ countObjects++; if ("java.lang.String".equals(resolvedParameterTypeName))//$NON-NLS-1$ countStrings++; } return countObjects == 1 && countObjects + countStrings == parameterTypes.length; } }); } public List<String> getResultMethodSuggestions(final IType type) throws JavaModelException { if (fLastValidBuilderType != null && fLastValidBuilderType.equals(type)) { return fLastValidResultMethodSuggestions; } return getMethodSuggestions(type, new MethodChecker() { public boolean isMethodOK(IMethod method) throws JavaModelException { return Flags.isPublic(method.getFlags()) && method.getParameterTypes().length == 0 && "java.lang.String" //$NON-NLS-1$ .equals(JavaModelUtil.getResolvedTypeName(method.getReturnType(), type)); } }); } private interface MethodChecker { boolean isMethodOK(IMethod method) throws JavaModelException; } private List<String> getMethodSuggestions(IType type, MethodChecker checker) throws JavaModelException { ArrayList<String> result = new ArrayList<String>(); IType[] classes = type.newSupertypeHierarchy(null).getAllClasses(); for (int i = 0; i < classes.length; i++) { IMethod[] methods = classes[i].getMethods(); for (int j = 0; j < methods.length; j++) { if (checker.isMethodOK(methods[j])) { String name = methods[j].getElementName(); if (!result.contains(name)) result.add(name); } } } return result; } private boolean isValidJavaIdentifier(String identifier) { return JavaConventionsUtil.validateIdentifier(identifier, fJavaProject).isOK(); } } private class CustomBuilderConfigurationDialog extends StatusDialog { private final int APPLY_BUTTON = IDialogConstants.CLIENT_ID + 1; /** * Extension for class selection dialog - validates selected type */ private final TypeSelectionExtension fExtension = new TypeSelectionExtension() { @Override public ISelectionStatusValidator getSelectionValidator() { return getValidator(); } }; /** * Listener for text fields - updates combos and validates entered data */ private final ModifyListener modifyListener = new ModifyListener() { public void modifyText(ModifyEvent e) { if (e.widget == fBuilderClassName) { fBuilderSettings.className = fBuilderClassName.getText(); updateCombos(); } else if (e.widget == fBuilderVariableName) fBuilderSettings.variableName = fBuilderVariableName.getText(); IStatus status = getValidator().revalidateAll(fBuilderSettings); updateStatus(status); enableApplyButton(); } }; private final CustomBuilderValidator fValidator = new CustomBuilderValidator(getType().getJavaProject()); private Text fBuilderClassName; private Text fBuilderVariableName; private Combo fAppendMethodName; private Combo fResultMethodName; private Button fChainInvocations; private ToStringGenerationSettings.CustomBuilderSettings fBuilderSettings; private boolean somethingChanged = false; public CustomBuilderConfigurationDialog(Shell parent) { super(parent); this.setShellStyle(this.getShellStyle() | SWT.RESIZE); fBuilderSettings = getGenerationSettings().getCustomBuilderSettings(); } public CustomBuilderValidator getValidator() { return fValidator; } @Override protected Control createDialogArea(Composite parent) { getShell().setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_windowTitle); Composite composite = (Composite) super.createDialogArea(parent); ((GridLayout) composite.getLayout()).numColumns = 3; LayoutUtil.setWidthHint(composite, convertWidthInCharsToPixels(100)); Label label = new Label(composite, SWT.LEFT); label.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_builderClassField); fBuilderClassName = createTextField(composite, 1, fBuilderSettings.className); Button button = new Button(composite, SWT.NONE); button.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_browseButton); setButtonLayoutData(button); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { browseForBuilderClass(); } }); label = new Label(composite, SWT.LEFT); label.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_varNameField); fBuilderVariableName = createTextField(composite, 2, fBuilderSettings.variableName); label = new Label(composite, SWT.LEFT); label.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_appendMethodField); fAppendMethodName = new Combo(composite, SWT.READ_ONLY); fAppendMethodName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); label = new Label(composite, SWT.LEFT); label.setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_resultMethodField); fResultMethodName = new Combo(composite, SWT.READ_ONLY); fResultMethodName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); updateCombos(); ModifyListener comboListener = new ModifyListener() { public void modifyText(ModifyEvent e) { Combo c = (Combo) e.widget; if (c.getText().length() > 0) { if (c == fAppendMethodName) fBuilderSettings.appendMethod = c.getText(); if (c == fResultMethodName) fBuilderSettings.resultMethod = c.getText(); } updateStatus(fValidator.revalidateAll(fBuilderSettings)); enableApplyButton(); } }; fAppendMethodName.addModifyListener(comboListener); fResultMethodName.addModifyListener(comboListener); if (!select(fAppendMethodName, fBuilderSettings.appendMethod)) { fAppendMethodName.select(0); } if (!select(fResultMethodName, fBuilderSettings.resultMethod)) { fResultMethodName.select(0); } fChainInvocations = new Button(composite, SWT.CHECK); fChainInvocations .setText(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_chainedCallsCheckbox); fChainInvocations.setSelection(fBuilderSettings.chainCalls); fChainInvocations.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); fChainInvocations.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { fBuilderSettings.chainCalls = fChainInvocations.getSelection(); enableApplyButton(); } }); PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), IJavaHelpContextIds.GENERATE_TOSTRING_CONFIGURE_CUSTOM_BUILDER_DIALOG); return composite; } @Override public void create() { super.create(); IStatus status = getValidator().revalidateAll(fBuilderSettings); updateStatus(status); } @Override protected void createButtonsForButtonBar(Composite parent) { super.createButtonsForButtonBar(parent); createButton(parent, APPLY_BUTTON, JavaUIMessages.GenerateToStringDialog_customBuilderConfig_applyButton, false).setEnabled(false); } private void enableApplyButton() { somethingChanged = true; getButton(APPLY_BUTTON).setEnabled(!getStatus().matches(IStatus.ERROR)); } @Override protected void updateButtonsEnableState(IStatus status) { super.updateButtonsEnableState(status); getButton(APPLY_BUTTON).setEnabled(!status.matches(IStatus.ERROR) && somethingChanged); } @Override protected void buttonPressed(int buttonId) { switch (buttonId) { case APPLY_BUTTON: getButton(APPLY_BUTTON).setEnabled(false); somethingChanged = false; //$FALL-THROUGH$ case OK: applyChanges(); } super.buttonPressed(buttonId); } private boolean select(Combo combo, String item) { int index = Arrays.asList(combo.getItems()).indexOf(item); if (index >= 0) { combo.select(index); return true; } return false; } private void updateCombos() { final String[] empty = new String[0]; try { IType type = fValidator.findType(fBuilderSettings.className); if (type == null) { fAppendMethodName.setItems(empty); fResultMethodName.setItems(empty); } else { fAppendMethodName.setItems(fValidator.getAppendMethodSuggestions(type).toArray(empty)); select(fAppendMethodName, fBuilderSettings.appendMethod); fResultMethodName.setItems(fValidator.getResultMethodSuggestions(type).toArray(empty)); select(fResultMethodName, fBuilderSettings.resultMethod); } } catch (JavaModelException e1) { fAppendMethodName.setItems(empty); fResultMethodName.setItems(empty); } } private void applyChanges() { fBuilderSettings.appendMethod = fAppendMethodName.getText(); fBuilderSettings.resultMethod = fResultMethodName.getText(); getGenerationSettings().writeCustomBuilderSettings(fBuilderSettings); } private Text createTextField(Composite composite, int gridHSpan, String text) { Text result = new Text(composite, SWT.BORDER); result.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, gridHSpan, 1)); result.setText(text); result.addModifyListener(modifyListener); TextFieldNavigationHandler.install(result); return result; } private void browseForBuilderClass() { try { IJavaSearchScope scope = SearchEngine .createJavaSearchScope(new IJavaElement[] { getType().getJavaProject() }); SelectionDialog dialog = JavaUI.createTypeDialog(getShell(), PlatformUI.getWorkbench().getProgressService(), scope, IJavaElementSearchConstants.CONSIDER_CLASSES, false, "*ToString", fExtension); //$NON-NLS-1$ dialog.setTitle( JavaUIMessages.GenerateToStringDialog_customBuilderConfig_classSelection_windowTitle); dialog.setMessage(JavaUIMessages.GenerateToStringDialog_customBuilderConfig_classSelection_message); dialog.open(); if (dialog.getReturnCode() == OK) { IType type = (IType) dialog.getResult()[0]; fBuilderClassName.setText(type.getFullyQualifiedParameterizedName()); List<String> suggestions = fValidator.getAppendMethodSuggestions(type); if (!suggestions.contains(fAppendMethodName.getText())) fAppendMethodName.setText(suggestions.get(0)); suggestions = fValidator.getResultMethodSuggestions(type); if (!suggestions.contains(fResultMethodName.getText())) fResultMethodName.setText(suggestions.get(0)); } } catch (JavaModelException e) { JavaPlugin.log(e); } } } private ToStringGenerationSettings fGenerationSettings; private static final int DOWN_BUTTON = IDialogConstants.CLIENT_ID + 2; private static final int UP_BUTTON = IDialogConstants.CLIENT_ID + 1; private static final int SORT_BUTTON = IDialogConstants.CLIENT_ID + 3; protected Button[] fButtonControls; boolean[] fButtonsEnabled; private static final int DOWN_INDEX = 1; private static final int UP_INDEX = 0; public ToStringGenerationSettings getGenerationSettings() { return fGenerationSettings; } public static String[] getTemplates(IDialogSettings dialogSettings) { String[] result = dialogSettings.getArray(ToStringGenerationSettings.SETTINGS_TEMPLATES); if (result != null && result.length > 0) return result; return new String[] { ToStringTemplateParser.DEFAULT_TEMPLATE }; } public String[] getTemplateNames() { String[] result = getDialogSettings().getArray(ToStringGenerationSettings.SETTINGS_TEMPLATE_NAMES); if (result != null && result.length > 0) return result; return new String[] { JavaUIMessages.GenerateToStringDialog_defaultTemplateName }; } public int getSelectedTemplate() { try { int result = getDialogSettings().getInt(ToStringGenerationSettings.SETTINGS_SELECTED_TEMPLATE); if (result < 0) return 0; return result; } catch (NumberFormatException e) { return 0; } } public void setSelectedTemplate(int templateNumber) { getDialogSettings().put(ToStringGenerationSettings.SETTINGS_SELECTED_TEMPLATE, templateNumber); } public GenerateToStringDialog(Shell shell, CompilationUnitEditor editor, IType type, IVariableBinding[] fields, IVariableBinding[] inheritedFields, IVariableBinding[] selectedFields, IMethodBinding[] methods, IMethodBinding[] inheritededMethods) throws JavaModelException { super(shell, new BindingLabelProvider(), new GenerateToStringContentProvider(fields, inheritedFields, methods, inheritededMethods), editor, type, false); setEmptyListMessage(JavaUIMessages.GenerateHashCodeEqualsDialog_no_entries); List<Object> selected = new ArrayList<Object>(Arrays.asList(selectedFields)); if (selectedFields.length == fields.length && selectedFields.length > 0) selected.add(getContentProvider().getParent(selectedFields[0])); setInitialElementSelections(selected); setTitle(JavaUIMessages.GenerateToStringDialog_dialog_title); setMessage(JavaUIMessages.GenerateToStringDialog_select_fields_to_include); setValidator(new GenerateToStringValidator(fields.length + inheritedFields.length, methods.length + inheritededMethods.length)); setSize(60, 18); setInput(new Object()); fGenerationSettings = new ToStringGenerationSettings(getDialogSettings()); } /** * {@inheritDoc} */ @Override public boolean close() { fGenerationSettings.writeDialogSettings(); fGenerationSettings.stringFormatTemplate = getTemplates( getDialogSettings())[fGenerationSettings.stringFormatTemplateNumber]; fGenerationSettings.createComments = getGenerateComment(); return super.close(); } @Override public Object[] getResult() { Object[] oldResult = super.getResult(); List<Object> newResult = new ArrayList<Object>(); for (int i = 0; i < oldResult.length; i++) { if (!(oldResult[i] instanceof String)) { newResult.add(oldResult[i]); } } return newResult.toArray(); } @Override protected void configureShell(Shell shell) { super.configureShell(shell); PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IJavaHelpContextIds.GENERATE_TOSTRING_SELECTION_DIALOG); } @Override protected CheckboxTreeViewer createTreeViewer(Composite parent) { CheckboxTreeViewer treeViewer = super.createTreeViewer(parent); treeViewer.setLabelProvider(new GenerateToStringLabelProvider()); //expandAll because setSubtreeChecked() used in CheckStateListener below assumes that elements have been expanded treeViewer.expandAll(); //but actually we only need one branch expanded treeViewer.collapseAll(); treeViewer.expandToLevel(GenerateToStringContentProvider.fieldsNode, 1); treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) getTreeViewer().getSelection(); Object selected = selection.size() > 0 ? selection.toList().get(0) : null; GenerateToStringContentProvider cp = (GenerateToStringContentProvider) getContentProvider(); fButtonControls[UP_INDEX].setEnabled(cp.canMoveUp(selected)); fButtonControls[DOWN_INDEX].setEnabled(cp.canMoveDown(selected)); } }); treeViewer.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent event) { getTreeViewer().setSubtreeChecked(event.getElement(), event.getChecked()); getTreeViewer().setGrayed(event.getElement(), false); Object parentElement = ((ITreeContentProvider) (getTreeViewer().getContentProvider())) .getParent(event.getElement()); if (parentElement != null) { Object[] siblings = ((ITreeContentProvider) (getTreeViewer().getContentProvider())) .getChildren(parentElement); int count = 0; for (int i = 0; i < siblings.length; i++) { if (getTreeViewer().getChecked(siblings[i])) count++; } if (count == 0) getTreeViewer().setGrayChecked(parentElement, false); else if (count == siblings.length) { getTreeViewer().setChecked(parentElement, true); getTreeViewer().setGrayed(parentElement, false); } else getTreeViewer().setGrayChecked(parentElement, true); } updateOKStatus(); } }); return treeViewer; } @Override protected Composite createSelectionButtons(Composite composite) { Composite buttonComposite = super.createSelectionButtons(composite); GridLayout layout = new GridLayout(); buttonComposite.setLayout(layout); createUpDownButtons(buttonComposite); createButton(buttonComposite, SORT_BUTTON, JavaUIMessages.GenerateToStringDialog_sort_button, false); layout.marginHeight = 0; layout.marginWidth = 0; layout.numColumns = 1; return buttonComposite; } @Override protected void buttonPressed(int buttonId) { super.buttonPressed(buttonId); switch (buttonId) { case UP_BUTTON: { GenerateToStringContentProvider contentProvider = (GenerateToStringContentProvider) getTreeViewer() .getContentProvider(); List<?> selection = ((IStructuredSelection) getTreeViewer().getSelection()).toList(); if (selection.size() > 0) contentProvider.up(selection.get(0), getTreeViewer()); updateOKStatus(); break; } case DOWN_BUTTON: { GenerateToStringContentProvider contentProvider = (GenerateToStringContentProvider) getTreeViewer() .getContentProvider(); List<?> selection = ((IStructuredSelection) getTreeViewer().getSelection()).toList(); if (selection.size() > 0) contentProvider.down(selection.get(0), getTreeViewer()); updateOKStatus(); break; } case SORT_BUTTON: { GenerateToStringContentProvider contentProvider = (GenerateToStringContentProvider) getTreeViewer() .getContentProvider(); contentProvider.sort(); getTreeViewer().refresh(); updateOKStatus(); break; } } } protected void createUpDownButtons(Composite buttonComposite) { int numButtons = 2; // up, down fButtonControls = new Button[numButtons]; fButtonsEnabled = new boolean[numButtons]; fButtonControls[UP_INDEX] = createButton(buttonComposite, UP_BUTTON, JavaUIMessages.GenerateToStringDialog_up_button, false); fButtonControls[DOWN_INDEX] = createButton(buttonComposite, DOWN_BUTTON, JavaUIMessages.GenerateToStringDialog_down_button, false); boolean defaultState = false; fButtonControls[UP_INDEX].setEnabled(defaultState); fButtonControls[DOWN_INDEX].setEnabled(defaultState); fButtonsEnabled[UP_INDEX] = defaultState; fButtonsEnabled[DOWN_INDEX] = defaultState; } private Label formatLabel; private Combo formatCombo; private Button skipNullsButton; private Button styleButton; @Override protected Composite createCommentSelection(Composite parentComposite) { Composite composite = super.createCommentSelection(parentComposite); Group group = new Group(parentComposite, SWT.NONE); group.setText(JavaUIMessages.GenerateToStringDialog_generated_code_group); GridLayout groupLayout = new GridLayout(); group.setLayout(groupLayout); group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); Composite composite2 = new Composite(group, SWT.NONE); GridLayout layout = new GridLayout(3, false); layout.marginWidth = 0; layout.marginHeight = 0; composite2.setLayout(layout); composite2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); formatLabel = new Label(composite2, SWT.NONE); formatLabel.setText(JavaUIMessages.GenerateToStringDialog_string_format_combo); GridData gridData = new GridData(SWT.FILL, SWT.CENTER, false, false); formatLabel.setLayoutData(gridData); formatCombo = new Combo(composite2, SWT.READ_ONLY); formatCombo.setItems(getTemplateNames()); formatCombo.select(fGenerationSettings.stringFormatTemplateNumber); formatCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); SWTUtil.setDefaultVisibleItemCount(formatCombo); formatCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { fGenerationSettings.stringFormatTemplateNumber = ((Combo) e.widget).getSelectionIndex(); } }); final Button formatButton = new Button(composite2, SWT.NONE); formatButton.setText(JavaUIMessages.GenerateToStringDialog_manage_templates_button); setButtonLayoutData(formatButton); formatButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { manageTemplatesButtonSelected(); } }); final Label styleLabel = new Label(composite2, SWT.NONE); styleLabel.setText(JavaUIMessages.GenerateToStringDialog_code_style_combo); gridData = new GridData(SWT.FILL, SWT.CENTER, false, false); styleLabel.setLayoutData(gridData); final Combo styleCombo = new Combo(composite2, SWT.READ_ONLY); styleCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); styleCombo.setItems(GenerateToStringOperation.getStyleNames()); styleCombo.select(Math.min(fGenerationSettings.toStringStyle, styleCombo.getItemCount() - 1)); SWTUtil.setDefaultVisibleItemCount(styleCombo); styleCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { changeToStringStyle(((Combo) e.widget).getSelectionIndex()); } }); styleButton = new Button(composite2, SWT.NONE); styleButton.setText(JavaUIMessages.GenerateToStringDialog_codeStyleConfigureButton); setButtonLayoutData(styleButton); styleButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { configureStyleButtonSelected(); } }); skipNullsButton = new Button(group, SWT.CHECK); skipNullsButton.setText(JavaUIMessages.GenerateToStringDialog_skip_null_button); skipNullsButton.setSelection(fGenerationSettings.skipNulls); skipNullsButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { fGenerationSettings.skipNulls = ((Button) event.widget).getSelection(); } }); final Button arrayButton = new Button(group, SWT.CHECK); arrayButton.setText(JavaUIMessages.GenerateToStringDialog_ignore_default_button); arrayButton.setSelection(fGenerationSettings.customArrayToString); arrayButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { fGenerationSettings.customArrayToString = ((Button) e.widget).getSelection(); } }); Composite limitRow = new Composite(group, SWT.NONE); RowLayout rowLayout = new RowLayout(); rowLayout.center = true; rowLayout.marginLeft = rowLayout.marginRight = rowLayout.marginTop = rowLayout.marginBottom = 0; limitRow.setLayout(rowLayout); final Button limitButton = new Button(limitRow, SWT.CHECK); limitButton.setText(JavaUIMessages.GenerateToStringDialog_limit_elements_button); limitButton.setSelection(fGenerationSettings.limitElements); limitButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { fGenerationSettings.limitElements = ((Button) e.widget).getSelection(); } }); final Spinner limitSpinner = new Spinner(limitRow, SWT.BORDER); limitSpinner.setMinimum(0); limitSpinner.setSelection(fGenerationSettings.limitValue); limitSpinner.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { fGenerationSettings.limitValue = ((Spinner) e.widget).getSelection(); } }); //invoked to change initial enable state of controls changeToStringStyle(styleCombo.getSelectionIndex()); return composite; } private void manageTemplatesButtonSelected() { ToStringTemplatesDialog dialog = new ToStringTemplatesDialog(getShell(), GenerateToStringOperation.createTemplateParser(fGenerationSettings.toStringStyle)); dialog.open(); formatCombo.setItems(getTemplateNames()); formatCombo .select(Math.min(fGenerationSettings.stringFormatTemplateNumber, formatCombo.getItemCount() - 1)); } private void configureStyleButtonSelected() { CustomBuilderConfigurationDialog dialog = new CustomBuilderConfigurationDialog(getShell()); dialog.open(); updateOKStatus(); } private void changeToStringStyle(int style) { fGenerationSettings.toStringStyle = style; skipNullsButton.setEnabled(style != GenerateToStringOperation.STRING_FORMAT); boolean enableFormat = (style != GenerateToStringOperation.CUSTOM_BUILDER); formatLabel.setEnabled(enableFormat); formatCombo.setEnabled(enableFormat); styleButton.setEnabled(style == GenerateToStringOperation.CUSTOM_BUILDER); updateOKStatus(); } }