Java tutorial
/* This file is part of Green. * * Copyright (C) 2005 The Research Foundation of State University of New York * All Rights Under Copyright Reserved, The Research Foundation of S.U.N.Y. * * Green is free software, licensed under the terms of the Eclipse * Public License, version 1.0. The license is available at * http://www.eclipse.org/legal/epl-v10.html */ package edu.buffalo.cse.green.dialogs; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jdt.ui.wizards.NewElementWizardPage; import org.eclipse.jdt.ui.wizards.NewTypeWizardPage; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard; import edu.buffalo.cse.green.GreenException; import edu.buffalo.cse.green.PlugIn; import edu.buffalo.cse.green.editor.model.CompartmentModel; import edu.buffalo.cse.green.editor.model.MemberModel; import edu.buffalo.cse.green.editor.model.RootModel; import edu.buffalo.cse.green.editor.model.filters.MemberVisibility; import static edu.buffalo.cse.green.preferences.VariableAffix.*; import edu.buffalo.cse.green.preferences.VariableAffix; /** * Opens a dialog box that prompts the user for a new element that will be * displayed in the diagram. * * @author bcmartin */ public abstract class NewElementWizard extends GreenWizard implements INewWizard { private IWorkbench _workbench; private IStructuredSelection _selection; protected NewTypeWizardPage _fPage; private static final String DEFAULT_PACKAGE_ERROR = "Cannot use default package to create type in editor"; private MemberModel<CompartmentModel, RootModel, IType> _model; public NewElementWizard() { setNeedsProgressMonitor(true); } /** * @param model - The model automatically generated by the * <code>CreateCommand</code>. */ public void setModel(MemberModel<CompartmentModel, RootModel, IType> model) { _model = model; } /** * @return The model created by this dialog. */ public MemberModel<CompartmentModel, RootModel, IType> getModel() { return _model; } /** * Subclasses should override to perform the actions of the wizard. This * method is run in the wizard container's context as a workspace runnable. * * @param monitor - The progress monitor to use. * @throws InterruptedException * @throws CoreException */ protected void finishPage(IProgressMonitor monitor) throws InterruptedException, CoreException { if (_fPage != null && _fPage.getPackageFragment().isDefaultPackage()) { GreenException.illegalOperation(DEFAULT_PACKAGE_ERROR); } } /** * @return True if the wizard can be run on a forked thread, false * otherwise. */ protected abstract boolean canRunForked(); /** * @see edu.buffalo.cse.green.dialogs.GreenWizard#doFinish() */ public boolean doFinish() { final IWorkspaceRunnable op = new IWorkspaceRunnable() { /** * @see org.eclipse.core.resources.IWorkspaceRunnable#run(org.eclipse.core.runtime.IProgressMonitor) */ public void run(IProgressMonitor monitor) throws CoreException, OperationCanceledException { try { finishPage(monitor); } catch (InterruptedException e) { throw new OperationCanceledException(e.getMessage()); } } }; try { getContainer().run(canRunForked(), true, new IRunnableWithProgress() { /** * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor) */ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { op.run(monitor); } catch (CoreException e) { e.printStackTrace(); } } }); } catch (Exception e) { handleFinishException(e); return false; } return true; } /** * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection) */ public void init(IWorkbench workbench, IStructuredSelection currentSelection) { _workbench = workbench; _selection = currentSelection; } /** * @return The selection. */ public IStructuredSelection getSelection() { return _selection; } /** * @return The workbench. */ public IWorkbench getWorkbench() { return _workbench; } /** * Selects and reveals the given resource in the workbench. * * @param newResource - The resource. */ protected void selectAndReveal(IResource newResource) { BasicNewResourceWizard.selectAndReveal(newResource, _workbench.getActiveWorkbenchWindow()); } } /** * This is the parent class of the wizards used to create fields and methods * using Green's editor. It creates the controls common to both wizards and * provides common functionality. * * @author bcmartin */ abstract class NewMemberSignatureWizardPage extends NewElementWizardPage { private VisibilityComposite _visibility; private Button _checkboxAbstract; private Button _checkboxFinal; private Button _checkboxStatic; private Button _typeByte; private Button _typeShort; private Button _typeInt; private Button _typeLong; private Button _typeFloat; private Button _typeDouble; private Button _typeBoolean; private Button _typeChar; private Button _typeVoid; private Button _browseTypeButton; private Text _name; private boolean _isInterface; private Text _typeNameText; public NewMemberSignatureWizardPage(String name) { super(name); } // /** // * Sets the basic layout for the page. // * // * @param parent - The container of this space. // */ // protected void createBlankSpace(Composite parent) { // Label dummyLabel = new Label(parent, SWT.SHADOW_NONE); // dummyLabel.setLayoutData(new GridData()); // } /** * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(Composite parent) { initializeDialogUnits(parent); Composite group = new Composite(parent, SWT.NONE); int columns = 4; GridLayout layout = new GridLayout(); layout.numColumns = columns; group.setLayout(layout); // pick & choose the wanted UI components createNameControls(group, columns); createModifierControls(group, columns); populateTypeGroup(group, columns); setControl(group); Dialog.applyDialogFont(group); PlugIn.getWorkbenchHelp().setHelp(group, JavaUI.ID_PLUGIN + "." + "new_class_wizard_page_context"); _typeNameText.setText("String"); if (allowVoidType()) { _typeVoid.setSelection(true); } } /** * @return The user specified data type for the pending variable. */ public String getTypeName() { if (_typeBoolean.getSelection()) return "boolean"; if (_typeByte.getSelection()) return "byte"; if (_typeChar.getSelection()) return "char"; if (_typeDouble.getSelection()) return "double"; if (_typeFloat.getSelection()) return "float"; if (_typeInt.getSelection()) return "int"; if (_typeLong.getSelection()) return "long"; if (_typeShort.getSelection()) return "short"; if (allowVoidType() && _typeVoid.getSelection()) return "void"; String typeName = _typeNameText.getText(); if (typeName.startsWith("java.lang.")) { return typeName.substring(typeName.lastIndexOf(".") + 1); } return _typeNameText.getText(); } /** * @return The modifiers for the pending variable. */ public List<String> getModifiers() { List<String> flags = new ArrayList<String>(); String visibility = _visibility.getValue().getCodeText(); if (_checkboxAbstract != null && _checkboxAbstract.getSelection()) flags.add("abstract"); if (_checkboxFinal != null && _checkboxFinal.getSelection()) flags.add("final"); if (_checkboxStatic != null && _checkboxStatic.getSelection()) flags.add("static"); if (visibility != null) flags.add(0, visibility); return flags; } /** * @param parent - The parent of the type group. * @param columns - The number of columns to create. */ private void populateTypeGroup(Composite parent, int columns) { Label typeLabel = new Label(parent, SWT.SHADOW_NONE); typeLabel.setText("&Return Type:"); typeLabel.setLayoutData(new GridData()); Composite typeSubGroup = new Composite(parent, SWT.SHADOW_NONE); GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); data.horizontalSpan = columns - 2; typeSubGroup.setLayoutData(data); int subGroupColumns = 5; typeSubGroup.setLayout(new GridLayout(subGroupColumns, true)); // create type buttons if (allowVoidType()) { _typeVoid = new Button(typeSubGroup, SWT.RADIO); _typeVoid.setText("void"); _typeVoid.setLayoutData(new GridData()); } _typeByte = new Button(typeSubGroup, SWT.RADIO); _typeShort = new Button(typeSubGroup, SWT.RADIO); _typeInt = new Button(typeSubGroup, SWT.RADIO); _typeLong = new Button(typeSubGroup, SWT.RADIO); _typeFloat = new Button(typeSubGroup, SWT.RADIO); _typeDouble = new Button(typeSubGroup, SWT.RADIO); _typeBoolean = new Button(typeSubGroup, SWT.RADIO); _typeChar = new Button(typeSubGroup, SWT.RADIO); _typeByte.setText("byte"); _typeByte.setLayoutData(new GridData()); _typeShort.setText("short"); _typeShort.setLayoutData(new GridData()); _typeInt.setText("int"); _typeInt.setLayoutData(new GridData()); _typeLong.setText("&long"); _typeLong.setLayoutData(new GridData()); _typeFloat.setText("float"); _typeFloat.setLayoutData(new GridData()); _typeDouble.setText("double"); _typeDouble.setLayoutData(new GridData()); _typeBoolean.setText("boolean"); _typeBoolean.setLayoutData(new GridData()); _typeChar.setText("char"); _typeChar.setLayoutData(new GridData()); _typeNameText = new Text(parent, SWT.HORIZONTAL | SWT.LEFT | SWT.BORDER | SWT.SINGLE); data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); data.horizontalSpan = columns - 1; _typeNameText.setLayoutData(data); _typeNameText.setText("Object"); _typeNameText.setEnabled(false); _browseTypeButton = new Button(parent, SWT.PUSH | SWT.CENTER); _browseTypeButton.setText("&Browse ..."); _browseTypeButton.setLayoutData(new GridData()); _browseTypeButton.addSelectionListener(new SelectionListener() { /** * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent e) { List<IType> types = new ChooseTypeDialog(false).open(); if (!types.isEmpty()) { String selectedName = types.get(0).getFullyQualifiedName(); _typeNameText.setText(selectedName); _typeBoolean.setSelection(false); _typeByte.setSelection(false); _typeChar.setSelection(false); _typeDouble.setSelection(false); _typeFloat.setSelection(false); _typeInt.setSelection(false); _typeLong.setSelection(false); _typeShort.setSelection(false); if (allowVoidType()) _typeVoid.setSelection(false); } } /** * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetDefaultSelected(SelectionEvent e) { } }); } /** * Creates the controls for the modifier section of the page. * * @param parent - The parent of the modifier controls group. * @param columns - The number of columns to create. */ private void createModifierControls(Composite parent, int columns) { final NewElementWizardSettings settings = getSettings(); Label modifiersLabel = new Label(parent, SWT.SHADOW_NONE | SWT.LEFT); modifiersLabel.setText("&Modifiers:"); modifiersLabel.setLayoutData(new GridData()); _visibility = new VisibilityComposite(parent, 0, false); _visibility.addListener(new IVisibilityChangedListener() { public void visibilityChanged(MemberVisibility value) { if (value.equals(MemberVisibility.PRIVATE)) { if (settings.isAbstractAvailable()) { _checkboxAbstract.setSelection(false); } } } }); GridData data = new GridData(); data.horizontalSpan = 3; _visibility.setLayoutData(data); if (settings.isAbstractAvailable()) { _checkboxAbstract = new Button(_visibility, SWT.CHECK); _checkboxAbstract.setText("abstract"); _checkboxAbstract.setEnabled(settings.isAbstractEnabled()); _checkboxAbstract.setSelection(settings.isAbstractSelected()); _checkboxAbstract.addSelectionListener(new SelectionListener() { /** * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent e) { if (settings.isFinalAvailable()) { _checkboxFinal.setSelection(false); if (getVisibilityContainer().getValue().equals(MemberVisibility.PRIVATE)) { getVisibilityContainer().setPrivateSelected(false); getVisibilityContainer().setProtectedSelected(true); } } } /** * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetDefaultSelected(SelectionEvent e) { } }); } if (settings.isFinalAvailable()) { _checkboxFinal = new Button(_visibility, SWT.CHECK); _checkboxFinal.setText("final"); _checkboxFinal.setEnabled(settings.isFinalEnabled()); _checkboxFinal.setSelection(settings.isFinalSelected()); _checkboxFinal.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { if (settings.isAbstractAvailable()) { _checkboxAbstract.setSelection(false); } } public void widgetDefaultSelected(SelectionEvent e) { } }); } if (settings.isStaticAvailable()) { _checkboxStatic = new Button(_visibility, SWT.CHECK); _checkboxStatic.setText("static"); _checkboxStatic.setEnabled(settings.isStaticEnabled()); _checkboxStatic.setSelection(settings.isStaticSelected()); } } /** * @return The <code>Composite</code> that holds the visibility buttons. */ protected VisibilityComposite getVisibilityContainer() { return _visibility; } /** * Creates the controls for the name section of the page. * * @param composite - The parent of the modifier controls group. * @param columns - The number of columns to create. */ private void createNameControls(Composite composite, int columns) { Label nameLabel = new Label(composite, SWT.HORIZONTAL | SWT.LEFT | SWT.SHADOW_NONE); nameLabel.setText("&Name"); GridData data = new GridData(); nameLabel.setLayoutData(data); _name = new Text(composite, SWT.HORIZONTAL | SWT.LEFT | SWT.BORDER | SWT.SINGLE); data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); data.horizontalSpan = columns - 1; _name.setLayoutData(data); if (isField()) _name.setText(VariableAffix.getAffixString(FieldPrefix)); else _name.setText(""); _name.setSelection(0, _name.getText().length()); final WizardPage page = this; _name.addKeyListener(new KeyListener() { /** * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent) */ public void keyPressed(KeyEvent e) { } /** * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) */ public void keyReleased(KeyEvent e) { Pattern p = Pattern.compile("[_abcdefghijklmnopqrstuvwxyz]\\w*"); Matcher m = p.matcher(_name.getText()); if (!m.matches()) { page.setErrorMessage("Invalid name"); } else { page.setErrorMessage(null); } } }); page.setErrorMessage("Invalid name"); } /** * @see org.eclipse.jface.wizard.IWizardPage#getName() */ public String getName() { return _name.getText(); } /** * Sets whether or not we are creating the element in an interface. * * @param isInterface - The value to use. */ protected void setInterface(boolean isInterface) { _isInterface = isInterface; } /** * @return Provides settings used to fill out the dialog. */ protected abstract NewElementWizardSettings getSettings(); /** * @return true if void is a valid data type, false otherwise. */ protected abstract boolean allowVoidType(); protected abstract boolean isField(); /** * @return true if this element wizard is being used to add an element to an * interface, false otherwise. */ protected boolean isInterface() { return _isInterface; } }