Java tutorial
/******************************************************************************* *Copyright (c) 2008 The Bioclipse Team 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: * Ola Spjuth - initial API and implementation *******************************************************************************/ package net.bioclipse.qsar.ui.editors; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.List; import net.bioclipse.cdk.business.Activator; import net.bioclipse.cdk.business.ICDKManager; import net.bioclipse.qsar.DescriptorType; import net.bioclipse.qsar.DescriptorlistType; import net.bioclipse.qsar.ParameterType; import net.bioclipse.qsar.QsarFactory; import net.bioclipse.qsar.QsarPackage; import net.bioclipse.qsar.QsarType; import net.bioclipse.qsar.business.IQsarManager; import net.bioclipse.qsar.descriptor.model.Descriptor; import net.bioclipse.qsar.descriptor.model.DescriptorImpl; import net.bioclipse.qsar.descriptor.model.DescriptorModel; import org.apache.log4j.Logger; import org.eclipse.core.databinding.observable.Realm; import org.eclipse.core.databinding.observable.map.IObservableMap; import org.eclipse.core.databinding.observable.set.IObservableSet; import org.eclipse.core.resources.IProject; import org.eclipse.emf.common.ui.viewer.IViewerProvider; import org.eclipse.emf.databinding.edit.EMFEditObservables; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.edit.command.SetCommand; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.domain.IEditingDomainProvider; import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; import org.eclipse.jface.dialogs.IPageChangedListener; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.PageChangedEvent; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnPixelData; import org.eclipse.jface.viewers.ComboBoxCellEditor; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; 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.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.forms.IFormColors; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.editor.FormPage; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.forms.widgets.Section; public class DescriptorsPage extends FormPage implements IEditingDomainProvider, IViewerProvider, IPageChangedListener { private TreeViewer descViewer; private Tree descTree; private TableViewer rightViewer; private Table rightTable; private static final Logger logger = Logger.getLogger(MoleculesPage.class); ICDKManager cdk; DecimalFormat formatter; private EditingDomain editingDomain; /** * This list of Descriptors in the qsar model. Also used as input to * rightViewer, containing the selected descrriptors */ // private DescriptorlistType descriptorList; IQsarManager qsar; private OnlyWithImplFilter onlyWithImplFilter = new OnlyWithImplFilter(); // private EList<DescriptorimplType> providerList; // private QsarType qsarModel; private TableViewer paramsViewer; private Table paramsTable; // private List<DescriptorInstance> selectedDescriptors; public DescriptorsPage(FormEditor editor, EditingDomain editingDomain) { super(editor, "qsar.descriptors", "Descriptors"); this.editingDomain = editingDomain; //Get Managers via OSGI qsar = net.bioclipse.qsar.init.Activator.getDefault().getQsarManager(); cdk = Activator.getDefault().getJavaCDKManager(); //We need to ensure that '.' is always decimal separator in all locales DecimalFormatSymbols sym = new DecimalFormatSymbols(); sym.setDecimalSeparator('.'); formatter = new DecimalFormat("0.00", sym); editor.addPageChangedListener(this); } /** * Add content to form */ @Override protected void createFormContent(IManagedForm managedForm) { ScrolledForm form = managedForm.getForm(); FormToolkit toolkit = managedForm.getToolkit(); form.setText("Descriptors for QSAR analysis"); toolkit.decorateFormHeading(form.getForm()); IProject project = ((QsarEditor) getEditor()).getActiveProject(); ToolbarHelper.setupToolbar(form, project); // setupToolbar(form); // form.setBackgroundImage(FormArticlePlugin.getDefault().getImage(FormArticlePlugin.IMG_FORM_BG)); GridLayout layout = new GridLayout(); layout.numColumns = 2; form.getBody().setLayout(layout); createDescriptorSection(form, toolkit); createRightSection(form, toolkit); descViewer.setInput(new PendingObject()); descViewer.refresh(); //Populate descriptorViewer from qsar model descViewer.getTree().getDisplay().asyncExec(new Runnable() { public void run() { DescriptorModel descModel = qsar.getModel(); //Set descriptor model as input object to viewer descViewer.setInput(descModel); } }); //Populate selected descriptors from the read qsar model populateRightViewerFromModel(); //Post selections to Eclipse via our intermediate selectionprovider descViewer.getTree().setFocus(); } private void populateRightViewerFromModel() { // The content provider is responsible to handle add and // remove notification for the Person#address EList ObservableListContentProvider provider = new ObservableListContentProvider(); rightViewer.setContentProvider(provider); // The label provider in turn handles the addresses // The EStructuralFeature[] defines which fields get shown // in the TableViewer columns IObservableSet knownElements = provider.getKnownElements(); IObservableMap[] observeMaps = EMFEditObservables.observeMaps(editingDomain, knownElements, new EStructuralFeature[] { QsarPackage.Literals.DESCRIPTOR_TYPE__ONTOLOGYID }); ObservableMapLabelProvider labelProvider = new ObservableQSARLabelProvider(observeMaps); rightViewer.setLabelProvider(labelProvider); DescriptorlistType descriptorList = getDescriptorListFromModel(); // Person#addresses is the Viewer's input rightViewer.setInput(EMFEditObservables.observeList(Realm.getDefault(), editingDomain, descriptorList, QsarPackage.Literals.DESCRIPTORLIST_TYPE__DESCRIPTORS)); } private DescriptorlistType getDescriptorListFromModel() { //Get descriptorList from qsar model, init if empty (should not be) QsarType qsarModel = ((QsarEditor) getEditor()).getQsarModel(); DescriptorlistType descriptorList = qsarModel.getDescriptorlist(); if (descriptorList == null) { descriptorList = QsarFactory.eINSTANCE.createDescriptorlistType(); qsarModel.setDescriptorlist(descriptorList); } return descriptorList; } /** * Create the left part of the page for displaying molecules * @param form * @param toolkit */ private void createDescriptorSection(final ScrolledForm form, FormToolkit toolkit) { Section descSection = toolkit.createSection(form.getBody(), Section.TWISTIE | Section.DESCRIPTION); descSection.setActiveToggleColor(toolkit.getHyperlinkGroup().getActiveForeground()); descSection.setToggleColor(toolkit.getColors().getColor(IFormColors.SEPARATOR)); toolkit.createCompositeSeparator(descSection); Composite client = toolkit.createComposite(descSection, SWT.WRAP); GridLayout layout = new GridLayout(); layout.numColumns = 2; client.setLayout(layout); final Button btnOnlyImpl = toolkit.createButton(client, "Display only with implementation", SWT.CHECK); btnOnlyImpl.setSelection(true); btnOnlyImpl.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (btnOnlyImpl.getSelection() == true) { descViewer.addFilter(onlyWithImplFilter); } else if (btnOnlyImpl.getSelection() == false) { descViewer.removeFilter(onlyWithImplFilter); } } }); GridData gdBTN = new GridData(GridData.FILL_HORIZONTAL); gdBTN.horizontalSpan = 2; btnOnlyImpl.setLayoutData(gdBTN); descViewer = new TreeViewer(client, SWT.BORDER | SWT.MULTI); descTree = descViewer.getTree(); toolkit.adapt(descTree, true, true); GridData gd = new GridData(GridData.FILL_BOTH); gd.widthHint = 250; descTree.setLayoutData(gd); descTree.setHeaderVisible(true); // molTable.setLinesVisible(true); toolkit.adapt(descTree, true, true); //Add providers columns TableLayout tableLayout = new TableLayout(); descTree.setLayout(tableLayout); TreeViewerColumn firstCol = new TreeViewerColumn(descViewer, SWT.NONE); firstCol.getColumn().setText(""); tableLayout.addColumnData(new ColumnPixelData(200)); TreeViewerColumn providersCol = new TreeViewerColumn(descViewer, SWT.NONE); providersCol.getColumn().setText("Provider(s)"); tableLayout.addColumnData(new ColumnPixelData(100)); descViewer.setContentProvider(new DescriptorContentProvider()); descViewer.setLabelProvider(new DescriptorLabelProvider()); descViewer.setUseHashlookup(true); //Sort by name descViewer.setSorter(new ViewerSorter()); //Default is to only show with impl (checkbox is selected!) descViewer.addFilter(onlyWithImplFilter); //If focus gained, make this viewer provide selections descViewer.getTree().addFocusListener(new FocusListener() { public void focusGained(FocusEvent e) { rightViewer.setSelection(null); } public void focusLost(FocusEvent e) { } }); descTree.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { //Delete key if (e.keyCode == SWT.DEL) { deleteSelectedDescriptors(); } //Space key, toggle selection if (e.keyCode == 32) { // IStructuredSelection msel=(IStructuredSelection) descViewer.getSelection(); //TODO: implement } } public void keyReleased(KeyEvent e) { } }); //Create composite centered vertically and add buttons to it Composite comp = toolkit.createComposite(client, SWT.WRAP); comp.setLayout(new GridLayout()); GridData gd2 = new GridData(GridData.VERTICAL_ALIGN_CENTER); comp.setLayoutData(gd2); Button btnAdd = toolkit.createButton(comp, " >> ", SWT.PUSH); btnAdd.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { addSelectedDescriptors(); } }); GridData gda2 = new GridData(GridData.VERTICAL_ALIGN_CENTER); gda2.widthHint = 60; btnAdd.setLayoutData(gda2); Button btnDel = toolkit.createButton(comp, " << ", SWT.PUSH); btnDel.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { deleteSelectedDescriptors(); } }); GridData gd21 = new GridData(GridData.VERTICAL_ALIGN_CENTER); gd21.widthHint = 60; btnDel.setLayoutData(gd21); //Wrap up section toolkit.paintBordersFor(client); descSection.setText("Avaliable descriptors"); descSection.setDescription("Descriptors available for QSAR analysis"); descSection.setClient(client); descSection.setExpanded(true); descSection.addExpansionListener(new ExpansionAdapter() { public void expansionStateChanged(ExpansionEvent e) { form.reflow(false); } }); GridData gd122 = new GridData(GridData.FILL_BOTH); descSection.setLayoutData(gd122); } /** * Handle the case when users press the ADD button next to moleculeviewer */ protected void addSelectedDescriptors() { List<String> errorList = new ArrayList<String>(); IStructuredSelection ssel = (IStructuredSelection) descViewer.getSelection(); for (Object obj : ssel.toList()) { if (obj instanceof Descriptor) { Descriptor desc = (Descriptor) obj; //Find out impl // DescriptorImpl impl2 = qsar.getDescriptorByID(desc.getId()); DescriptorImpl impl = qsar.getPreferredImpl(desc.getId()); if (impl != null) { QsarType qsarModel = ((QsarEditor) getEditor()).getQsarModel(); qsar.addDescriptorToModel(qsarModel, editingDomain, desc, impl); } else { errorList.add("No implementation available for descriptor: " + desc); } } } if (errorList.size() > 0) { String errormsgs = "The following errors occured:\n\n"; for (String str : errorList) { errormsgs = errormsgs + str + "\n"; } } // rightViewer.setInput(descriptorList.eContents().toArray()); } /** * Handle the case when users press the Remove button next to moleculeviewer * or presses the delete button on something */ protected void deleteSelectedDescriptors() { IStructuredSelection ssel = (IStructuredSelection) rightViewer.getSelection(); QsarType qsarModel = ((QsarEditor) getEditor()).getQsarModel(); qsar.removeDescriptorsFromModel(qsarModel, editingDomain, ssel.toList()); } private void showMessage(String message) { MessageDialog.openInformation(getSite().getShell(), "Information", message); } private void createRightSection(final ScrolledForm form, FormToolkit toolkit) { Section preSection = toolkit.createSection(form.getBody(), Section.TWISTIE | Section.DESCRIPTION); preSection.setActiveToggleColor(toolkit.getHyperlinkGroup().getActiveForeground()); preSection.setToggleColor(toolkit.getColors().getColor(IFormColors.SEPARATOR)); toolkit.createCompositeSeparator(preSection); Composite client = toolkit.createComposite(preSection, SWT.WRAP); GridLayout layout = new GridLayout(); layout.numColumns = 1; client.setLayout(layout); //Right viewer //================= rightViewer = new TableViewer(client, SWT.BORDER | SWT.MULTI); rightTable = rightViewer.getTable(); toolkit.adapt(rightTable, true, true); GridData gd6 = new GridData(GridData.FILL_BOTH); gd6.widthHint = 100; rightTable.setLayoutData(gd6); //If focus gained, make this viewer provide selections rightTable.addFocusListener(new FocusListener() { public void focusGained(FocusEvent e) { descViewer.setSelection(null); } public void focusLost(FocusEvent e) { } }); rightTable.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { //Delete key if (e.keyCode == SWT.DEL) { deleteSelectedDescriptors(); } } public void keyReleased(KeyEvent e) { } }); //Post changes to parameters viewer rightViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { //For now, don't care about multiple selections DescriptorType desc = (DescriptorType) ((IStructuredSelection) event.getSelection()) .getFirstElement(); if (desc != null) { paramsViewer.setInput(desc.getParameter().toArray()); } else { paramsViewer.setInput(new Object[0]); } } }); Label lblParams = toolkit.createLabel(client, "Descriptor parameters"); lblParams.setEnabled(true); //Parameters viewer //================= paramsViewer = new TableViewer(client, SWT.BORDER | SWT.MULTI); paramsTable = paramsViewer.getTable(); toolkit.adapt(paramsTable, true, true); GridData gd7 = new GridData(GridData.FILL_BOTH); gd7.heightHint = 40; gd7.minimumHeight = 150; paramsTable.setLayoutData(gd7); paramsTable.setHeaderVisible(true); paramsTable.setLinesVisible(true); //Add providers columns TableLayout tableLayout = new TableLayout(); paramsTable.setLayout(tableLayout); TableViewerColumn keyCol = new TableViewerColumn(paramsViewer, SWT.H_SCROLL | SWT.V_SCROLL); keyCol.getColumn().setText("Key"); tableLayout.addColumnData(new ColumnPixelData(150)); keyCol.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { ParameterType param = (ParameterType) element; return param.getKey(); } }); TableViewerColumn valueCol = new TableViewerColumn(paramsViewer, SWT.NONE); valueCol.getColumn().setText("Value"); tableLayout.addColumnData(new ColumnPixelData(150)); valueCol.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { ParameterType param = (ParameterType) element; return param.getValue(); } }); valueCol.setEditingSupport(new EditingSupport(paramsViewer) { // private TextCellEditor cellEditor; @Override protected boolean canEdit(Object element) { return true; } @Override protected CellEditor getCellEditor(Object element) { ParameterType param = (ParameterType) element; if ((param.getValue().equals("true")) || (param.getValue().equals("false"))) { String[] values = new String[] { "true", "false" }; ComboBoxCellEditor cbo = new ComboBoxCellEditor(paramsTable, values); return cbo; } return new TextCellEditor(paramsTable); } @Override protected Object getValue(Object element) { ParameterType param = (ParameterType) element; //For combo boolean if (param.getValue().equals("true")) { return new Integer(0); } else if (param.getValue().equals("false")) { return new Integer(1); } else return param.getValue(); } @Override protected void setValue(Object element, Object value) { ParameterType param = (ParameterType) element; //Integers if (value instanceof Integer) { Integer i = (Integer) value; if (i == 0) { if (param.getValue().equals("false")) { SetCommand cmd = new SetCommand(editingDomain, param, QsarPackage.Literals.PARAMETER_TYPE__VALUE, "true"); editingDomain.getCommandStack().execute(cmd); paramsViewer.refresh(); } } if (i == 1) { if (param.getValue().equals("true")) { SetCommand cmd = new SetCommand(editingDomain, param, QsarPackage.Literals.PARAMETER_TYPE__VALUE, "false"); editingDomain.getCommandStack().execute(cmd); paramsViewer.refresh(); } } } //String values if (value instanceof String) { String strval = (String) value; if (!(strval.equals(param.getValue()))) { SetCommand cmd = new SetCommand(editingDomain, param, QsarPackage.Literals.PARAMETER_TYPE__VALUE, strval); editingDomain.getCommandStack().execute(cmd); paramsViewer.refresh(); rightViewer.refresh(); } } } }); paramsViewer.setContentProvider(new ArrayContentProvider()); //Wrap up section toolkit.paintBordersFor(client); preSection.setText("Selected descriptors"); preSection.setDescription("Add descriptors here for calculation"); preSection.setClient(client); preSection.setExpanded(true); preSection.addExpansionListener(new ExpansionAdapter() { public void expansionStateChanged(ExpansionEvent e) { form.reflow(false); } }); GridData gd = new GridData(GridData.FILL_BOTH); preSection.setLayoutData(gd); //Post selections to Eclipse //getSite().setSelectionProvider(queryViewer); } public void activatePage() { } public class Stopwatch { private long start; private long stop; public void start() { start = System.currentTimeMillis(); // start timing } public void stop() { stop = System.currentTimeMillis(); // stop timing } public long elapsedTimeMillis() { return stop - start; } //return number of seconds public String toString() { return "" + Long.toString(elapsedTimeMillis() / 1000); // print execution time } } public EditingDomain getEditingDomain() { return editingDomain; } public Viewer getViewer() { return rightViewer; } public void pageChanged(PageChangedEvent event) { if (event.getSelectedPage() != this) return; if (rightViewer != null) { populateRightViewerFromModel(); } activatePage(); } }