| // ViewExample1.java |
| package org.eclipse.stem.sample.adaption; |
| |
| /******************************************************************************* |
| * Copyright (c) 2006 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.ILabelProviderListener; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredContentProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ListViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.stem.core.graph.Graph; |
| import org.eclipse.stem.core.graph.Node; |
| import org.eclipse.stem.core.scenario.Scenario; |
| import org.eclipse.stem.definitions.adapters.spatial.geo.LatLong; |
| import org.eclipse.stem.definitions.adapters.spatial.geo.LatLongProvider; |
| import org.eclipse.stem.definitions.adapters.spatial.geo.LatLongProviderAdapterFactory; |
| import org.eclipse.stem.definitions.adapters.spatial.geo.LatLong.Segment; |
| import org.eclipse.stem.jobs.simulation.ISimulation; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.ui.ISelectionListener; |
| import org.eclipse.ui.ISelectionService; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.part.ViewPart; |
| |
| /** |
| * This class is an example of how to run GUI code in Eclipse and monitor the |
| * "selected" simulation, and how to extract the canonical graph from the |
| * selected simulation and then extract data from it. |
| * <p> |
| * It creats an Eclipse "View" called "View Example1" that simply "dumps" the |
| * latitude and longitude data extracted from the canonical graph to the view's |
| * window. The example is simple, but it helps to understand how a JFace |
| * "Viewer" (not the same as an Eclipse "View") works with content and label |
| * providers. |
| * <p> |
| * There are three classes defined in this example. The first is the parent |
| * class that is a <code>ViewPart</code> and implements what is seen in the |
| * view's window in Eclipse. It contains a JFace <code>ListViewer</code> which |
| * basically maintains a list of Objects and creates a display that prints a |
| * descriptive text string for each one. The method |
| * <code>createPartControl</code> is the code that initializes the SWT |
| * graphics for the display of the view. It is passed an SWT |
| * <code>Composite</code> instance called <code>parent</code> that is used |
| * to "contain" the SWT/JFace elements of the view's that make up the display in |
| * the view. The method does three things, it first creates the |
| * <code>ListViewer</code> instance, giving the parent as an argument to the |
| * constructer (this makes it part of the display), it then creates and passes |
| * to the <code>ListViewer</code> the "Content" and "Label" providers it |
| * needs. The Content and Label providers are the other two classes in this |
| * example. |
| * <p> |
| * The content provider class is {@link ViewExample1ContentProvider}, while not |
| * complex, it may not be obvious what's it's doing. It's job is to maintain the |
| * contents of the <code>ListViewer</code>'s internal list of things to |
| * display. It performs the "Controler" job in an "MVC" architecture. In our |
| * example, the content provider is an {@link ISelectionListener} which means it |
| * has a <code>selectionChanged</code> method. The idea behind the method is |
| * that it is called whenever the user "selects" something in the Eclipse |
| * interface. This doesn't happen automatically, an instance of the class must |
| * be registered with the Eclipse "selection service" that serves as a central |
| * dispatcher for selections. This registration is done in the |
| * <code>createPartControl</code> method of the parent class. When something |
| * is selected and the method is called, it must filter out the selections and |
| * ignore those that are not instances of {@link ISimulation}. When it does |
| * find a simulation instance, it removes the current contents of the list |
| * maintained by the <code>ListViewer</code> and adds the newly selected |
| * instances. It then tells the viewer to redraw itself. |
| * <p> |
| * The label provider class is {@link ViewExample1LabelProvider} and is the |
| * easiest to understand, its is used by the <code>ListViewer</code> to |
| * generate a text string for any of the <code>Objects</code> (i.e., |
| * <code>ISimulation</code> instances) it contains. The method |
| * {@link ViewExample1LabelProvider#getText(Object)} does this and in this |
| * example does the work to extract the latitude and longitude data from the |
| * canonical graph used in the simulation. Then it just returns that data as a |
| * (long) string to be displayed. |
| * |
| * To see the example in action, you need to: |
| * <ol> |
| * <li> Run STEM</li> |
| * <li> Open the "View Example 1" view. |
| * "Window->Show View->Other->STEM->View Example 1"</li> |
| * <li> Open the "Active Simulations" view. |
| * "Window->Show View->Active Simulations"</li>. |
| * |
| * <li> Go to the "Scenarios" view. It shows the STEM Scenarios that are plugged |
| * into STEM. </li> |
| * <li> Expand "Test->Disease Models->Standard" and you'll see disease |
| * modeling scenarios that are plugged into STEM. </li> |
| * <li> Double-click on a scenario in the list (e.g., "SEIR 1 x 1") it will |
| * begin simulation and an entry will appear in the "Active Simulations" view. |
| * </li> |
| * <li> Single click on the entry in the Active Simulations view. This will |
| * select that simulation and the latitude/longitude data for that scenario will |
| * appear in the View Example 1 view as a single (long) string. </li> |
| * </ol> |
| * If you double-click on another plugged-in Scenario so that two entries are |
| * displayed in the Active Simulations view and the you select both, you'll see |
| * two entries in the View Example 1 view, one for each of the selected |
| * simulations. |
| * |
| */ |
| public class ViewExample1 extends ViewPart { |
| |
| /** |
| * The identifier of the View Example1 View. Nobody uses this right now, but |
| * it would be useful if we wanted to programatically add this view to a |
| * perspective. |
| */ |
| public static final String ID_VIEW_EXAMPLE1_VIEW = "org.eclipse.stem.sample.adapters.viewexample1"; |
| |
| /** |
| * This is the ListViewer that creates the display that will show up in the |
| * view's window. It contains a list of Objects, which in this example's |
| * case will be instances of ISimulation. |
| */ |
| protected ListViewer lv = null; |
| |
| /** |
| * This method is called when the view is created and it has the |
| * responsibility for doing all of the initialization. It creates the |
| * ListViewer and instances of the ContentProvider and LabelProvider for the |
| * viewer. It also gets a reference to the selection service and registers |
| * the content provider so it will be notified when something is selected. |
| * |
| * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) |
| */ |
| @Override |
| public void createPartControl(Composite parent) { |
| // Create the content provider |
| ViewExample1ContentProvider contentProvider = new ViewExample1ContentProvider(); |
| // Create the ListViewer |
| lv = new ListViewer(parent); |
| |
| // Let the ListViewer know who its content and label providers are |
| lv.setContentProvider(contentProvider); |
| lv.setLabelProvider(new ViewExample1LabelProvider()); |
| |
| // This call tells the viewer's content provider where it should get the |
| // source of its content. In this case it is the selection service. |
| lv.setInput(getSite().getWorkbenchWindow().getSelectionService()); |
| |
| // We also want to be able to have a user select a simluation from our |
| // view and have that be seen by others. So we register the ListViewer |
| // instance as the view's selection provider. When you click on the view |
| // in the interface it finds the underlying Object (i.e., ISimulation) |
| // you selected and passes it to the selection service. |
| getSite().setSelectionProvider(lv); |
| |
| } // createPartControl |
| |
| /** |
| * This is required by the interface, but we're not using it. |
| * |
| * @see org.eclipse.ui.part.WorkbenchPart#setFocus() |
| */ |
| @Override |
| public void setFocus() { |
| // Nothing |
| } // setFocus |
| |
| /** |
| * This class is the content provider for the view. It is also a selection |
| * listener and uses the selection service as the source of its input. It |
| * looks for selected ISimulation instances and updates the list in the |
| * view's ListViewer instance with the current selection. |
| */ |
| public class ViewExample1ContentProvider implements |
| IStructuredContentProvider, ISelectionListener { |
| |
| // We remember the ListViewer that we're providing content for because |
| // we need to manipulate its list in the method selectionChanged. |
| private ListViewer viewer = null; |
| |
| // These are the simulations we added to the ListViewer, we remember |
| // these so we can remove them when a different set of simulations is |
| // selected. |
| private List<ISimulation> selectedSimulations = null; |
| |
| /** |
| * This is used by the ListViewer to get the initial list of ISimulation |
| * instances. |
| * |
| * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) |
| */ |
| public Object[] getElements(@SuppressWarnings("unused") |
| Object inputElement) { |
| Object[] retValue = new Object[] {}; |
| |
| // Anything yet? |
| if (selectedSimulations != null) { |
| // Yes |
| retValue = selectedSimulations.toArray(); |
| } |
| return retValue; |
| } // getElements |
| |
| /** |
| * This is called when the view is closed, we could remove ourselves as |
| * a selection service listener, but this is really for cleaning up SWT |
| * things. The method inputChanged will be called before dispose when |
| * the view is closed, we remove ourselves from the selection service |
| * there. |
| * |
| * @see org.eclipse.jface.viewers.IContentProvider#dispose() |
| */ |
| public void dispose() { |
| // Nothing to do |
| } // dispose |
| |
| /** |
| * @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) { |
| // We remember the ListViewer we're providing content for because |
| // we'll have to change the list of things it contains in the |
| // selectionChanged method. |
| this.viewer = (ListViewer) viewer; |
| |
| // Were we previously getting input from a different service? |
| if (oldInput != null) { |
| // Yes |
| // Not any more. |
| final ISelectionService oldSS = (ISelectionService) oldInput; |
| oldSS.removePostSelectionListener(this); |
| } |
| |
| // Is there some new input we should register with? |
| if (newInput != null) { |
| // Yes |
| // Register us with the new service. Since there should only |
| // really be one selection service in Eclipse, this would only |
| // happen once, however, the code can handle a change if needed. |
| final ISelectionService ss = (ISelectionService) newInput; |
| ss.addPostSelectionListener(this); |
| } |
| |
| } // inputChanged |
| |
| /** |
| * This method is called whenever ANYTHING is selected in the Eclipse |
| * workbench. It's job is to filter out selections of ISimulation |
| * instances and update the list in the ListViewer. |
| * |
| * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, |
| * org.eclipse.jface.viewers.ISelection) |
| */ |
| public void selectionChanged(final IWorkbenchPart part, final ISelection selection) { |
| |
| // Is this selection changed event coming from our view? |
| if (part != ViewExample1.this) { |
| // No |
| // This will hold the new simulations that have been selected |
| final List<ISimulation> temp = new ArrayList<ISimulation>(); |
| |
| // Is it a structured selection? |
| if (selection instanceof IStructuredSelection) { |
| // Yes |
| final List list = ((IStructuredSelection) selection) |
| .toList(); |
| |
| // Go through everything in the list of things that were |
| // selected and pick out the ones that are ISimulations. |
| for (final Iterator selectionIter = list.iterator(); selectionIter |
| .hasNext();) { |
| final Object obj = selectionIter.next(); |
| if (obj instanceof ISimulation) { |
| temp.add((ISimulation) obj); |
| } |
| } // for each selected item |
| } // if structured selection |
| |
| // Did we find any new simulations that were selected? |
| if (temp.size() > 0) { |
| // Yes |
| // Tell the ListViewer not to redraw while we're changing |
| // its list. |
| viewer.getList().setRedraw(false); |
| try { |
| // Do we have any old selections we should remove? |
| if (selectedSimulations != null) { |
| // Yes |
| viewer.remove(selectedSimulations.toArray()); |
| } |
| // Add the new selections to the ListViewer's list. It |
| // will use the label provider to get a text string for |
| // each one. |
| viewer.add(temp.toArray()); |
| |
| // Remember what we added this time so we can remove it |
| // next selection. |
| selectedSimulations = temp; |
| } // try |
| finally { |
| // The ListViewer should update itself now. |
| viewer.getList().setRedraw(true); |
| } |
| } // if any new simulations selected |
| } // if selection changed event coming from our view? |
| } // selectionChanged |
| |
| } // ViewExample1ContentProvider |
| |
| /** |
| * This class is the label provider for the view. It is used by the |
| * ListViewer to convert ISimulation instances to text strings. |
| */ |
| public class ViewExample1LabelProvider implements ILabelProvider { |
| |
| /** |
| * This is called by the ListViewer for each Object in its list to |
| * generate a text string that represents that Object. This |
| * implementation digs into the simulation to get the scenario and then |
| * from that it obtains the canonical graph. It then goes through the |
| * nodes of the graph and using a LatLongProviderAdapterFactory creates |
| * a LatLongProvider for each node that can return the latitude and |
| * longitude data of the node. That data is just turned into a string |
| * and returned as the textual representation of the simulation. |
| * |
| * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) |
| */ |
| public String getText(Object element) { |
| final StringBuilder sb = new StringBuilder(); |
| |
| // Extract the scenario and then the canonical graph |
| final ISimulation simulation = (ISimulation) element; |
| final Scenario scenario = simulation.getScenario(); |
| final Graph canonicalGraph = scenario.getCanonicalGraph(); |
| |
| // Get the nodes from the graph and iterate through them. Note that |
| // the getNodes call returns a Map instance where the keys are the |
| // URI's of the Node instances. We get the values of the map to |
| // interate through the nodes. |
| for (final Iterator nodeIter = canonicalGraph.getNodes().values() |
| .iterator(); nodeIter.hasNext();) { |
| final Node node = (Node) nodeIter.next(); |
| |
| // We'd like to have access to lat/long data of the node if |
| // there is any, to do that we use a factory to create an |
| // adapter that knows about the inner details of nodes (it |
| // really knows about all Identifiables) and implements the |
| // LatLongProvider interface. |
| final LatLongProvider latLongProvider = (LatLongProvider) LatLongProviderAdapterFactory.INSTANCE |
| .adapt(node, LatLongProvider.class); |
| |
| // The node may or may not have lat/long data associated with |
| // it, if it doesn't the list that's returned will be empty. |
| final LatLong latLong = latLongProvider.getLatLong(); |
| |
| // Now we just go through each segment and create a string. |
| for (Segment segment : latLong.getSegments()) { |
| sb.append(Example1.createStringOfLatLongData(segment)); |
| sb.append("///"); |
| } // for |
| } // for |
| |
| // Now if we didn't find any lat/long data, we just return a simple |
| // response. This will appear in the view instead of the data. |
| String retValue = sb.toString(); |
| retValue = retValue.length() == 0 ? "No Lat/Long Data" : retValue; |
| |
| return retValue; |
| } // getText |
| |
| /** |
| * We don't have any images associated with simulations, but if we did |
| * we'd return them here. Returning null just tells the caller that |
| * there are no images. |
| * |
| * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) |
| */ |
| public Image getImage(@SuppressWarnings("unused") |
| Object element) { |
| return null; |
| } // getImage |
| |
| /** |
| * Required by the interface, but not used by us. |
| * |
| * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener) |
| */ |
| public void addListener(@SuppressWarnings("unused") |
| ILabelProviderListener listener) { |
| // nothing |
| } |
| |
| /** |
| * Required by the interface, but not used by us. |
| * |
| * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() |
| */ |
| public void dispose() { |
| // nothing |
| } |
| |
| /** |
| * Required by the interface, but not used by us. |
| * |
| * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, |
| * java.lang.String) |
| */ |
| public boolean isLabelProperty(@SuppressWarnings("unused") |
| Object element, @SuppressWarnings("unused") |
| String property) { |
| return false; |
| } |
| |
| /** |
| * Required by the interface, but not used by us. |
| * |
| * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener) |
| */ |
| public void removeListener(@SuppressWarnings("unused") |
| ILabelProviderListener listener) { |
| // nothing |
| } |
| } // ViewExample1LabelProvider |
| |
| } // ViewExample1 |