Java tutorial
/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Spindle, an Eclipse Plugin for Tapestry. * * The Initial Developer of the Original Code is * Intelligent Works Incorporated. * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * glongman@intelligentworks.com * * ***** END LICENSE BLOCK ***** */ package com.iw.plugins.spindle.editors; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.pde.core.IEditable; import org.eclipse.pde.core.IModel; import org.eclipse.pde.core.IModelChangedListener; import org.eclipse.pde.internal.ui.editor.PropertiesAction; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; 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.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertySource; import org.eclipse.ui.views.properties.IPropertySourceProvider; import org.eclipse.update.ui.forms.internal.FormWidgetFactory; import com.iw.plugins.spindle.model.BaseTapestryModel; import com.iw.plugins.spindle.model.ITapestryModel; import com.iw.plugins.spindle.spec.IIdentifiable; import com.iw.plugins.spindle.spec.XMLUtil; import com.iw.plugins.spindle.ui.EmptySelection; import com.iw.plugins.spindle.ui.IToolTipProvider; import com.iw.plugins.spindle.ui.TreeViewerWithToolTips; import com.iw.plugins.spindle.ui.descriptors.INeedsModelInitialization; import com.iw.plugins.spindle.util.JavaListSelectionProvider; import com.iw.plugins.spindle.util.StringSorter; public abstract class AbstractPropertySheetEditorSection extends SpindleFormSection implements ISelectionChangedListener, IModelChangedListener, IPropertySource, IPropertySourceProvider { private static DefaultTooltipProvider defaultTooltipProvider = new DefaultTooltipProvider(); protected Button newButton; protected Button inspectButton; protected Button deleteButton; private TreeViewer treeViewer; private FormWidgetFactory factory; protected boolean updateNeeded; protected boolean updateSelection = false; private ITreeContentProvider contentProvider = new ContentProvider(); private ITableLabelProvider labelProvider; private Action newAction; private Action deleteAction; private int boxHeight = -1; protected PropertiesAction pAction; protected boolean hasFocus; private Composite container; protected int DTDVersion; protected List holderArray = new ArrayList(); protected Point oldSize = new Point(0, 0); private boolean useToolTips = false; private IToolTipProvider toolTipProvider = defaultTooltipProvider; /** * Constructor for PropertySection */ public AbstractPropertySheetEditorSection(SpindleFormPage page) { super(page); pAction = new PropertiesAction(page.getEditor()); pAction.setText("Inspect"); pAction.setToolTipText("Edit the selected"); } public AbstractPropertySheetEditorSection(SpindleFormPage page, int boxHeight) { this(page); this.boxHeight = boxHeight; setContentProvider(new ContentProvider()); } public void setContentProvider(ITreeContentProvider provider) { contentProvider = provider; } public void setLabelProvider(ITableLabelProvider provider) { labelProvider = provider; } public void setNewAction(Action action) { newAction = action; } public void setDeleteAction(Action action) { deleteAction = action; } public Control getControl() { return treeViewer.getControl(); } public TreeViewer getViewer() { return treeViewer; } public void update() { if (updateNeeded && canUpdate()) { update((BaseTapestryModel) getFormPage().getModel()); if (holderArray != null && !holderArray.isEmpty()) { layout(); } } updateNeeded = false; } protected abstract void update(BaseTapestryModel model); public void setInput(Object obj) { treeViewer.setInput(obj); } public void initialize(Object input) { BaseTapestryModel model = (BaseTapestryModel) input; boolean isEditable = model.isEditable(); if (newButton != null) { newButton.setEnabled(isEditable); } if (deleteButton != null) { deleteAction.setEnabled(isEditable); } if (inspectButton != null) { inspectButton.setEnabled(isEditable); } if (deleteButton != null) { deleteButton.setEnabled(isEditable); } updateNeeded = true; if (canUpdate()) { update(); } DTDVersion = XMLUtil.getDTDVersion(model.getPublicId()); if (useToolTips) { TreeViewerWithToolTips viewer = (TreeViewerWithToolTips) treeViewer; viewer.setToolTipProvider(toolTipProvider); } model.addModelChangedListener(this); } public Composite createClientContainer(Composite parent, FormWidgetFactory factory) { this.factory = factory; container = factory.createComposite(parent); GridLayout layout = new GridLayout(); layout.numColumns = 2; container.setLayout(layout); Control control = createTree(container, factory); GridData gd = new GridData(GridData.FILL_BOTH); gd.widthHint = 200; if (boxHeight != -1) { gd.heightHint = boxHeight; } control.setLayoutData(gd); Composite buttonContainer = factory.createComposite(container); layout = new GridLayout(); layout.marginHeight = 0; buttonContainer.setLayout(layout); gd = new GridData(GridData.FILL_VERTICAL); buttonContainer.setLayoutData(gd); createButtons(buttonContainer, factory); factory.paintBordersFor(container); return container; } protected void createButtons(Composite buttonContainer, FormWidgetFactory factory) { String temp = newAction == null ? "New" : newAction.getText(); temp = (temp == null || "".equals(temp)) ? "New" : temp; newButton = factory.createButton(buttonContainer, temp, SWT.PUSH); GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); newButton.setLayoutData(gd); newButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleNew(); } }); inspectButton = factory.createButton(buttonContainer, "Inspect", SWT.PUSH); gd = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); inspectButton.setLayoutData(gd); inspectButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleEdit(); } }); if (deleteAction != null) { deleteButton = factory.createButton(buttonContainer, "Delete", SWT.PUSH); gd = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); deleteButton.setLayoutData(gd); deleteButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleDelete(); } }); } } private Tree createTree(Composite container, FormWidgetFactory factory) { Tree tree = factory.createTree(container, SWT.NULL); MenuManager popupMenuManager = new MenuManager(); IMenuListener listener = new IMenuListener() { public void menuAboutToShow(IMenuManager mng) { fillContextMenu(mng); } }; popupMenuManager.setRemoveAllWhenShown(true); popupMenuManager.addMenuListener(listener); Menu menu = popupMenuManager.createContextMenu(tree); tree.setMenu(menu); if (useToolTips) { TreeViewerWithToolTips viewer = new TreeViewerWithToolTips(tree); viewer.setToolTipProvider(toolTipProvider); treeViewer = viewer; } else { treeViewer = new TreeViewer(tree); } treeViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { handleEdit(); } }); treeViewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS); treeViewer.setContentProvider(contentProvider); treeViewer.setLabelProvider(labelProvider); treeViewer.addSelectionChangedListener(this); treeViewer.setSorter(new TreeViewSorter()); treeViewer.getControl().addFocusListener(new FocusListener() { public void focusGained(FocusEvent event) { hasFocus = true; } public void focusLost(FocusEvent event) { hasFocus = false; } }); return tree; } public void setSelection(IStructuredSelection selection) { treeViewer.getControl().setFocus(); treeViewer.setSelection(selection); } protected void selectFirst() { Object[] items = ((ITreeContentProvider) getContentProvider()).getElements(null); if (items != null && items.length >= 1) { ArrayList list = new ArrayList(); list.add(items[0]); setSelection(new JavaListSelectionProvider(list)); } } protected ITreeContentProvider getContentProvider() { return this.contentProvider; } protected Object getSelected() { return ((IStructuredSelection) treeViewer.getSelection()).getFirstElement(); } public ITapestryModel getModel() { return (ITapestryModel) getFormPage().getModel(); } public boolean isModelEditable() { return ((BaseTapestryModel) getModel()).isEditable(); } public void setFocus() { treeViewer.getTree().setFocus(); setPageSelection(); } protected void updateButtons(Object selected) { boolean isEditable = isModelEditable(); newButton.setEnabled(isEditable); if (deleteButton != null) { deleteButton.setEnabled(isEditable && selected != null); } } protected void fillContextMenu(IMenuManager manager) { ISelection selection = getSelection(); final Object object = ((IStructuredSelection) selection).getFirstElement(); boolean isEditable = ((BaseTapestryModel) getFormPage().getModel()).isEditable(); if (isEditable) { manager.add(newAction); if (object != null) { manager.add(new Separator()); manager.add(deleteAction); } } manager.add(new Separator()); pAction.setEnabled(((IModel) getFormPage().getModel()).isEditable()); manager.add(pAction); } protected ISelection getSelection() { return treeViewer.getSelection(); } protected void handleNew() { newAction.run(); } protected void handleEdit() { IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection(); if (!selection.isEmpty()) { Object object = ((IStructuredSelection) selection).getFirstElement(); fireSelectionNotification(object); setPageSelection(); pAction.run(); } } protected void setPageSelection() { getFormPage().setSelection(new StructuredSelection(this)); } protected void clearPageSelection() { getFormPage().setSelection(EmptySelection.Instance); } protected void handleDelete() { if (deleteAction != null) { deleteAction.run(); } } protected void forceDirty() { setDirty(true); updateNeeded = true; IModel model = (IModel) getFormPage().getModel(); if (model instanceof IEditable) { IEditable editable = (IEditable) model; editable.setDirty(true); getFormPage().getEditor().fireSaveNeeded(); } } public void selectionChanged(SelectionChangedEvent event) { Object object = null; if (!event.getSelection().isEmpty()) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { object = ((IStructuredSelection) selection).getFirstElement(); } } fireSelectionNotification(object); if (hasFocus || updateSelection) { setPageSelection(); } updateButtons(object); } protected String findPrevious(String name) { if (name != null) { Object[] items = ((ITreeContentProvider) getContentProvider()).getElements(null); final ArrayList list = new ArrayList(); for (int i = 0; i < items.length; i++) { if (((IIdentifiable) items[i]).getIdentifier().equals(name) && i >= 1) { return ((IIdentifiable) items[i - 1]).getIdentifier(); } } } return null; } protected boolean alreadyHasIdentifer(String name) { Object[] items = ((ITreeContentProvider) getContentProvider()).getElements(null); if (items != null && items.length >= 1) { for (int i = 0; i < items.length; i++) { IIdentifiable holder = (IIdentifiable) items[i]; if (holder.getIdentifier().equals(name)) { return true; } } } return false; } public void setSelection(IIdentifiable identifiable) { setSelection(identifiable.getIdentifier()); } public void setSelection(String name) { Object[] items = ((ITreeContentProvider) getContentProvider()).getElements(null); if (items != null && items.length >= 1) { for (int i = 0; i < items.length; i++) { IIdentifiable holder = (IIdentifiable) items[i]; if (holder.getIdentifier().equals(name)) { ArrayList list = new ArrayList(); list.add(items[i]); setSelection(new JavaListSelectionProvider(list)); break; } } } } public boolean isSelected(Object object) { IStructuredSelection selection = (IStructuredSelection) getViewer().getSelection(); if (selection == null || selection.isEmpty()) { return false; } return object == selection.getFirstElement(); } protected IPropertySource getSelectedPropertySource() { return (IPropertySource) getSelected(); } /** * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue() */ public Object getEditableValue() { IPropertySource selected = getSelectedPropertySource(); if (selected != null) { return selected.getEditableValue(); } return null; } /** * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors() */ public IPropertyDescriptor[] getPropertyDescriptors() { IPropertySource selected = getSelectedPropertySource(); if (selected != null) { IPropertyDescriptor[] descriptors = selected.getPropertyDescriptors(); for (int i = 0; i < descriptors.length; i++) { if (descriptors[i] instanceof INeedsModelInitialization) { ((INeedsModelInitialization) descriptors[i]).initialize(getModel()); } } return descriptors; } return new IPropertyDescriptor[0]; } /** * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(Object) */ public Object getPropertyValue(Object id) { IPropertySource selected = getSelectedPropertySource(); if (selected != null) { return selected.getPropertyValue(id); } return null; } /** * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(Object) */ public boolean isPropertySet(Object id) { IPropertySource selected = getSelectedPropertySource(); if (selected != null) { return selected.isPropertySet(id); } return false; } /** * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(Object) */ public void resetPropertyValue(Object id) { IPropertySource selected = getSelectedPropertySource(); if (selected != null) { selected.resetPropertyValue(id); } } /** * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(Object, Object) */ public void setPropertyValue(Object id, Object value) { final String oldSelected = ((IIdentifiable) getSelected()).getIdentifier(); if (!isModelEditable()) { updateNeeded = true; update(); setSelection(oldSelected); return; } final IPropertySource selected = getSelectedPropertySource(); if (selected != null) { selected.setPropertyValue(id, value); } Display d = Display.getCurrent(); d.asyncExec(new Runnable() { public void run() { updateUI(); // we may have changed the identifier, must ensure that // which was selected is still selected! String newSelected = ((IIdentifiable) selected).getIdentifier(); if (!newSelected.equals(oldSelected) || getSelection() == null) { setSelection(newSelected); } } }); } /** * @see org.eclipse.ui.views.properties.IPropertySourceProvider#getPropertySource(Object) */ public IPropertySource getPropertySource(Object object) { return this; } protected void updateUI() { forceDirty(); updateNeeded = true; update(); } protected class TreeViewSorter extends StringSorter { protected TreeViewSorter() { super(); } public int compare(Viewer viewer, Object e1, Object e2) { ITableLabelProvider provider = (ITableLabelProvider) ((TreeViewer) viewer).getLabelProvider(); return super.compare(viewer, provider.getColumnText(e1, 1), provider.getColumnText(e2, 1)); } } class ContentProvider implements ITreeContentProvider { public Object[] getElements(Object object) { return holderArray.toArray(); } public Object[] getChildren(Object parent) { return new Object[0]; } public Object getParent(Object child) { return null; } public boolean hasChildren(Object parent) { return false; } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } /** * Returns the useToolTips. * @return boolean */ public boolean isUseToolTips() { return useToolTips; } /** * Sets the useToolTips. * @param useToolTips The useToolTips to set */ public void setUseToolTips(boolean useToolTips) { if (treeViewer == null) { this.useToolTips = useToolTips; } } /** * Returns the tooltipProvider. * @return IToolTipProvider */ public IToolTipProvider getToolTipProvider() { if (useToolTips) { return toolTipProvider; } return null; } /** * Sets the tooltipProvider. * @param tooltipProvider The tooltipProvider to set */ public void setToolTipProvider(IToolTipProvider tooltipProvider) { if (useToolTips) { if (treeViewer != null) { ((TreeViewerWithToolTips) treeViewer).setToolTipProvider(tooltipProvider); } else if (tooltipProvider != null) { this.toolTipProvider = tooltipProvider; } } } public static class DefaultTooltipProvider implements IToolTipProvider { /** * @see com.iw.plugins.spindle.ui.IToolTipProvider#getToolTipText(Object) */ public String getToolTipText(Object object) { return "Tooltip provider not supplied!"; } } }