Java tutorial
/******************************************************************************* * Copyright (c) 2013 Luigi Sgro. 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: * Luigi Sgro - initial API and implementation ******************************************************************************/ package com.quantcomponents.ui.marketdata; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.DecoratingLabelProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ILabelDecorator; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.model.BaseWorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.ui.part.ViewPart; import com.quantcomponents.core.utils.LangUtils; import com.quantcomponents.marketdata.IRealTimeMarketDataManager; import com.quantcomponents.ui.core.IMonitorableContainer; import com.quantcomponents.ui.core.IMonitorableContainerListener; import com.quantcomponents.ui.core.TaskMonitorAdapter; public class MarketDataManagersView extends ViewPart { public static final String VIEW_ID = "com.quantcomponent.ui.marketdata.marketDataManagers"; private IMonitorableContainer<MarketDataManagerPresentationWrapper> marketDataManagerContainer; private MarketDataManagerPresentationWrapper selectedMarketDataManager; private final List<StockDatabasePresentationWrapper> multipleStockDatabaseSelection = new ArrayList<StockDatabasePresentationWrapper>(); private Composite parent; private TreeViewer dataManagerTree; private final MarketDataViewAdapterFactory adapterFactory = new MarketDataViewAdapterFactory(); private final Action addStockDatabaseAction = new Action("Add Stock Database...") { @Override public void run() { if (selectedMarketDataManager != null) { WizardDialog dialog = new WizardDialog(parent.getShell(), new NewHistoricalData(selectedMarketDataManager)); dialog.open(); } } }; private final Action removeStockDatabaseAction = new Action("Remove") { @Override public void run() { if (selectedMarketDataManager != null && multipleStockDatabaseSelection.size() > 0) { if (MessageDialog.openConfirm(parent.getShell(), "Confirmation", "Delete " + multipleStockDatabaseSelection.size() + " stock database(s)?")) { for (StockDatabasePresentationWrapper selectedStockDatabase : multipleStockDatabaseSelection) { try { selectedMarketDataManager.removeStockDatabase(selectedStockDatabase); } catch (Exception e) { MessageDialog.openError(parent.getShell(), "Error", "Stock database deletion failed: " + LangUtils.exceptionMessage(e)); return; } } refreshTree(); multipleStockDatabaseSelection.clear(); } } } }; private final Action openViewAction = new Action("Open view") { @Override public void run() { if (selectedMarketDataManager != null && multipleStockDatabaseSelection.size() > 0) { for (StockDatabasePresentationWrapper selectedStockDatabase : multipleStockDatabaseSelection) { try { getSite().getPage().showView(StockDatabaseChartView.MULTI_STOCK_DB_VIEW_ID, selectedStockDatabase.getPrettyName(), IWorkbenchPage.VIEW_VISIBLE); } catch (Exception e) { MessageDialog.openError(parent.getShell(), "Error", "A problem occurred while opening view for: " + selectedStockDatabase.getPrettyName() + "[" + LangUtils.exceptionMessage(e) + "]"); } } } } }; private final Action refreshAction = new Action("Refresh") { @Override public void run() { refreshTree(); } }; private final Action startAutoUpdateAction = new Action("Start auto-update") { @Override public void run() { if (selectedMarketDataManager != null && multipleStockDatabaseSelection.size() > 0) { try { for (final StockDatabasePresentationWrapper selectedStockDatabase : multipleStockDatabaseSelection) { ProgressMonitorDialog dialog = new ProgressMonitorDialog(parent.getShell()); dialog.setCancelable(true); dialog.run(true, true, new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { IRealTimeMarketDataManager realTimeMarketDataManager = (IRealTimeMarketDataManager) selectedMarketDataManager; realTimeMarketDataManager.startRealtimeUpdate(selectedStockDatabase, true, new TaskMonitorAdapter(monitor, "Retrieving historical data")); } catch (Exception e) { MessageDialog.openError(parent.getShell(), "Error", "Error while retrieving historical data: " + LangUtils.exceptionMessage(e)); } } }); IBaseLabelProvider labelDecorator = PlatformUI.getWorkbench().getDecoratorManager() .getBaseLabelProvider(AutoUpdateIconDecorator.DECORATOR_ID); if (labelDecorator != null) { // it is enabled AutoUpdateIconDecorator autoUpdateIconDecorator = (AutoUpdateIconDecorator) labelDecorator; autoUpdateIconDecorator.fireLabelProviderChanged(selectedStockDatabase); } } } catch (InvocationTargetException e) { MessageDialog.openError(parent.getShell(), "Error", "A problem occurred while starting auto-update: " + LangUtils.exceptionMessage(e)); } catch (InterruptedException e) { MessageDialog.openError(parent.getShell(), "Error", "Task interrupted while starting auto-update: " + LangUtils.exceptionMessage(e)); } catch (ClassCastException e) { MessageDialog.openError(parent.getShell(), "Error", "Market data source does not support real-time update"); } } } }; private final Action stopAutoUpdateAction = new Action("Stop auto-update") { @Override public void run() { if (selectedMarketDataManager != null && multipleStockDatabaseSelection.size() > 0) { for (StockDatabasePresentationWrapper selectedStockDatabase : multipleStockDatabaseSelection) { try { IRealTimeMarketDataManager realTimeMarketDataManager = (IRealTimeMarketDataManager) selectedMarketDataManager; realTimeMarketDataManager.stopRealtimeUpdate(selectedStockDatabase); } catch (ClassCastException e) { MessageDialog.openError(parent.getShell(), "Error", "Market data source does not support real-time update"); } catch (Exception e) { MessageDialog.openError(parent.getShell(), "Error", "A problem occurred while stopping auto-update: " + LangUtils.exceptionMessage(e)); } IBaseLabelProvider labelDecorator = PlatformUI.getWorkbench().getDecoratorManager() .getBaseLabelProvider(AutoUpdateIconDecorator.DECORATOR_ID); if (labelDecorator != null) { // it is enabled AutoUpdateIconDecorator autoUpdateIconDecorator = (AutoUpdateIconDecorator) labelDecorator; autoUpdateIconDecorator.fireLabelProviderChanged(selectedStockDatabase); } } } } }; private final IMonitorableContainerListener<MarketDataManagerPresentationWrapper> marketDataManagerContainerListener = new IMonitorableContainerListener<MarketDataManagerPresentationWrapper>() { @Override public void onElementAdded(MarketDataManagerPresentationWrapper manager) { manager.addListener(stockDatabaseContainerListener); refreshTree(); for (StockDatabasePresentationWrapper stockDatabase : manager.getElements()) { showChart(stockDatabase); } } @Override public void onElementRemoved(MarketDataManagerPresentationWrapper manager) { manager.removeListener(stockDatabaseContainerListener); refreshTree(); for (StockDatabasePresentationWrapper stockDatabase : manager.getElements()) { hideChart(stockDatabase); } } @Override public void onElementModified(MarketDataManagerPresentationWrapper element) { } }; private final IMonitorableContainerListener<StockDatabasePresentationWrapper> stockDatabaseContainerListener = new IMonitorableContainerListener<StockDatabasePresentationWrapper>() { @Override public void onElementAdded(StockDatabasePresentationWrapper element) { refreshTree(); showChart(element); } @Override public void onElementRemoved(StockDatabasePresentationWrapper element) { refreshTree(); hideChart(element); } @Override public void onElementModified(StockDatabasePresentationWrapper element) { } }; public void init(IViewSite site) throws PartInitException { super.init(site); marketDataManagerContainer = MarketDataPlugin.getDefault().getMarketDataManagerContainer(); } @Override public void createPartControl(Composite parent) { this.parent = parent; dataManagerTree = new TreeViewer(parent); dataManagerTree.setContentProvider(new BaseWorkbenchContentProvider() { @SuppressWarnings("unchecked") @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { super.inputChanged(viewer, oldInput, newInput); if (oldInput != null) { ((IMonitorableContainer<MarketDataManagerPresentationWrapper>) oldInput) .removeListener(marketDataManagerContainerListener); } if (newInput != null) { IMonitorableContainer<MarketDataManagerPresentationWrapper> container = (IMonitorableContainer<MarketDataManagerPresentationWrapper>) newInput; container.addListener(marketDataManagerContainerListener); for (MarketDataManagerPresentationWrapper manager : container.getElements()) { marketDataManagerContainerListener.onElementAdded(manager); } } } }); ILabelDecorator decorator = PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator(); dataManagerTree.setLabelProvider(new DecoratingLabelProvider(new WorkbenchLabelProvider(), decorator)); Platform.getAdapterManager().registerAdapters(adapterFactory, IMarketDataManagerContainer.class); Platform.getAdapterManager().registerAdapters(adapterFactory, MarketDataManagerPresentationWrapper.class); Platform.getAdapterManager().registerAdapters(adapterFactory, StockDatabasePresentationWrapper.class); dataManagerTree.setInput(marketDataManagerContainer); dataManagerTree.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { multipleStockDatabaseSelection.clear(); ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection = (IStructuredSelection) selection; Object o = structuredSelection.getFirstElement(); if (o instanceof MarketDataManagerPresentationWrapper) { selectedMarketDataManager = (MarketDataManagerPresentationWrapper) o; openViewAction.setEnabled(false); addStockDatabaseAction.setEnabled(true); removeStockDatabaseAction.setEnabled(false); if (selectedMarketDataManager instanceof RealTimeMarketDataManagerPresentationWrapper) { startAutoUpdateAction.setEnabled(false); stopAutoUpdateAction.setEnabled(false); } } else if (o instanceof StockDatabasePresentationWrapper) { openViewAction.setEnabled(true); addStockDatabaseAction.setEnabled(true); removeStockDatabaseAction.setEnabled(true); if (selectedMarketDataManager instanceof RealTimeMarketDataManagerPresentationWrapper) { startAutoUpdateAction.setEnabled(true); stopAutoUpdateAction.setEnabled(true); } if (structuredSelection.size() > 0) { Iterator<?> iterator = structuredSelection.iterator(); while (iterator.hasNext()) { Object sel = iterator.next(); if (sel instanceof StockDatabasePresentationWrapper) { StockDatabasePresentationWrapper stockDatabaseWrapper = (StockDatabasePresentationWrapper) sel; selectedMarketDataManager = stockDatabaseWrapper.getParent(); multipleStockDatabaseSelection.add(stockDatabaseWrapper); } } } } else { openViewAction.setEnabled(false); addStockDatabaseAction.setEnabled(false); removeStockDatabaseAction.setEnabled(false); startAutoUpdateAction.setEnabled(false); stopAutoUpdateAction.setEnabled(false); } } } }); dataManagerTree.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection = (IStructuredSelection) selection; Object o = structuredSelection.getFirstElement(); if (o instanceof StockDatabasePresentationWrapper) { StockDatabasePresentationWrapper selectedStockDatabase = (StockDatabasePresentationWrapper) o; try { getSite().getPage().showView(StockDatabaseChartView.MULTI_STOCK_DB_VIEW_ID, selectedStockDatabase.getPrettyName(), IWorkbenchPage.VIEW_VISIBLE); } catch (PartInitException e) { MessageDialog.openError(MarketDataManagersView.this.parent.getShell(), "Error", "A problem occurred while opening view for: " + selectedStockDatabase.getPrettyName() + "[" + LangUtils.exceptionMessage(e) + "]"); } } } } }); getSite().setSelectionProvider(dataManagerTree); hookGlobalActions(); createContextMenu(); } private void createContextMenu() { // Create menu manager. MenuManager menuMgr = new MenuManager(); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager mgr) { fillContextMenu(mgr); } }); // Create menu. Menu menu = menuMgr.createContextMenu(dataManagerTree.getControl()); dataManagerTree.getControl().setMenu(menu); // Register menu for extension. getSite().registerContextMenu(menuMgr, dataManagerTree); } private void fillContextMenu(IMenuManager menuMgr) { if (multipleStockDatabaseSelection.size() > 0) { menuMgr.add(openViewAction); menuMgr.add(removeStockDatabaseAction); } if (selectedMarketDataManager != null) { menuMgr.add(addStockDatabaseAction); menuMgr.add(refreshAction); if (selectedMarketDataManager instanceof RealTimeMarketDataManagerPresentationWrapper) { menuMgr.add(startAutoUpdateAction); menuMgr.add(stopAutoUpdateAction); } } menuMgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); } private void hookGlobalActions() { IActionBars bars = getViewSite().getActionBars(); bars.setGlobalActionHandler(ActionFactory.DELETE.getId(), removeStockDatabaseAction); } @Override public void setFocus() { } @Override public void dispose() { Platform.getAdapterManager().unregisterAdapters(adapterFactory); super.dispose(); } private void hideChart(StockDatabasePresentationWrapper stockDatabase) { IViewReference chartViewRef = getViewSite().getPage() .findViewReference(StockDatabaseChartView.MULTI_STOCK_DB_VIEW_ID, stockDatabase.getPrettyName()); if (chartViewRef != null) { getViewSite().getPage().hideView(chartViewRef); } } private void showChart(StockDatabasePresentationWrapper stockDatabase) { String secondaryId = stockDatabase.getPrettyName(); IViewReference chartViewRef = getViewSite().getPage() .findViewReference(StockDatabaseChartView.MULTI_STOCK_DB_VIEW_ID, secondaryId); if (chartViewRef != null) { StockDatabaseChartView view = (StockDatabaseChartView) chartViewRef.getView(false); if (view != null) { view.setupFromSecondaryId(secondaryId); } } } private void refreshTree() { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { @Override public void run() { dataManagerTree.refresh(); } }); } }