Java tutorial
/** * Copyright (c) 2005-2006 Aptana, Inc. * * 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. If redistributing this code, * this entire header must remain intact. */ package org.eclipse.eclipsemonkey.ui.views; import java.util.List; import java.util.Vector; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.browser.LocationEvent; import org.eclipse.swt.browser.LocationListener; import org.eclipse.swt.browser.ProgressEvent; import org.eclipse.swt.browser.ProgressListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IMemento; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.plugin.AbstractUIPlugin; /** * @author Paul Colton (Aptana, Inc.) * */ public abstract class BrowserView extends ViewPart { private String partId; //$NON-NLS-1$ private Browser browser; private String url; // TODO: Add to plugin strings for localization /** * Browser_homeButton_tooltip */ public static String Browser_homeButton_tooltip = Messages.BrowserView_Home; /** * Browser_forwardButton_tooltip */ public static String Browser_forwardButton_tooltip = Messages.BrowserView_NavigateToNextTopic; /** * Browser_backwardButton_tooltip */ public static String Browser_backwardButton_tooltip = Messages.BrowserView_NavigateToPreviousTopic; /** * Browser_invalidConfig */ public static String Browser_invalidConfig = Messages.BrowserView_InvalidConfiguration; /** * urlListener */ protected BrowserIntroPartLocationListener urlListener = new BrowserIntroPartLocationListener(this); /** * history */ protected History history = new History(); // Global actions /** * backAction */ protected Action backAction = new Action() { { setToolTipText(BrowserView.Browser_backwardButton_tooltip); setImageDescriptor(BrowserView.getImageDescriptor("icons/backward_nav_on.gif")); //$NON-NLS-1$ setDisabledImageDescriptor(BrowserView.getImageDescriptor("icons/backward_nav_off.gif")); //$NON-NLS-1$ } @Override public void run() { navigateBackward(); } }; /** * forwardAction */ protected Action forwardAction = new Action() { { setToolTipText(BrowserView.Browser_forwardButton_tooltip); setImageDescriptor(BrowserView.getImageDescriptor("icons/forward_nav_on.gif")); //$NON-NLS-1$ setDisabledImageDescriptor(BrowserView.getImageDescriptor("icons/forward_nav_off.gif")); //$NON-NLS-1$ } @Override public void run() { navigateForward(); } }; /** * Returns the startup URL (to display when this control initially loads * * @return String */ public abstract String getStartUrl(); /** * homeAction */ protected Action homeAction = new Action() { { setToolTipText(BrowserView.Browser_homeButton_tooltip); //$NON-NLS-1$ setImageDescriptor(BrowserView.getImageDescriptor("icons/home_nav_on.gif")); //$NON-NLS-1$ setDisabledImageDescriptor(BrowserView.getImageDescriptor("icons/home_nav_off.gif")); //$NON-NLS-1$ } @Override public void run() { navigateHome(); } }; /** * The constructor. */ public BrowserView() { url = getStartUrl(); partId = getPartId(); } /** * Returns the "part ID" which is used in the contexts.xml file * * @return String */ public abstract String getPartId(); /** * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento) */ @Override public void init(IViewSite site, IMemento memento) throws PartInitException { super.init(site, memento); if (memento != null) { url = memento.getString(partId); sendMessage(url); } } /** * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento) */ @Override public void saveState(IMemento memento) { if (url != null) { memento.putString(partId, url); } } /** * This is a callback that will allow us to create the viewer and initialize it. * * @param parent */ @Override public void createPartControl(Composite parent) { browser = new Browser(parent, SWT.NONE); if (this.url != null) { browser.setUrl(this.url); } PlatformUI.getWorkbench().getHelpSystem().setHelp(browser, "com.aptana.ide.js.ui." + partId); //$NON-NLS-1$ // add a location listener on the browser so we can intercept // LocationEvents. Responsible for intercepting URLs and updating UI // with history. browser.addLocationListener(urlListener); // add a location listener that will clear a flag at the end of any // navigation to a page. This is used in conjunction with the location // listener to filter out redundant navigations due to frames. browser.addProgressListener(new ProgressListener() { @Override public void changed(ProgressEvent event) { // no-op } @Override public void completed(ProgressEvent event) { urlListener.flagEndOfNavigation(); urlListener.flagEndOfFrameNavigation(); urlListener.flagRemovedTempUrl(); updateNavigationActionsState(); } }); addToolBarActions(); } /******************************************************************************************************************* * Pulled from BrowserIntroPartImplementation ******************************************************************************************************************/ protected void addToolBarActions() { IActionBars actionBars = getViewSite().getActionBars(); IToolBarManager toolBarManager = actionBars.getToolBarManager(); actionBars.setGlobalActionHandler(ActionFactory.FORWARD.getId(), forwardAction); actionBars.setGlobalActionHandler(ActionFactory.BACK.getId(), backAction); toolBarManager.add(homeAction); toolBarManager.add(backAction); toolBarManager.add(forwardAction); toolBarManager.update(true); actionBars.updateActionBars(); updateNavigationActionsState(); } /** * Return a reference to the browser * * @return Browser */ public Browser getBrowser() { return browser; } /** * Passing the focus request to the viewer's control. */ @Override public void setFocus() { browser.setFocus(); } /** * @param url */ public void sendMessage(String url) { if (url != null) { this.url = url; if (browser != null) { browser.setUrl(url); } } } /** * updateNavigationActionsState */ protected void updateNavigationActionsState() { // in static html intro, use browser history. forwardAction.setEnabled(browser.isForwardEnabled()); backAction.setEnabled(browser.isBackEnabled()); } /** * navigateBackward * * @return boolean */ public boolean navigateBackward() { return browser.back(); } /** * navigateForward * * @return boolean */ public boolean navigateForward() { return browser.forward(); } /** * navigateHome * * @return boolean */ public boolean navigateHome() { String location = url; boolean success = browser.setUrl(location); updateHistory(location); return success; } /** * Updates the UI navigation history with either a real URL. * * @param location */ public void updateHistory(String location) { history.updateHistory(location); updateNavigationActionsState(); } /** * Retrieves the image descriptor associated with resource from the image * descriptor registry. If the image descriptor cannot be retrieved, attempt * to find and load the image descriptor at the location specified in * resource. * * @param imageFilePath * the image descriptor to retrieve * @return The image descriptor assocated with resource or the default * "missing" image descriptor if one could not be found */ private static ImageDescriptor getImageDescriptor(String imageFilePath) { ImageDescriptor imageDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.eclipsemonkey.ui", imageFilePath); if (imageDescriptor == null) { imageDescriptor = ImageDescriptor.getMissingImageDescriptor(); } return imageDescriptor; } /** * A Location Listener that knows how to intercept OOBE action URLs. It also knows how to update UI navigation * history. */ private class BrowserIntroPartLocationListener implements LocationListener { private BrowserView implementation; /** * Takes the implementation as an input. * * @param implementation */ public BrowserIntroPartLocationListener(BrowserView implementation) { this.implementation = implementation; } /** * @see org.eclipse.swt.browser.LocationListener#changed(org.eclipse.swt.browser.LocationEvent) */ @Override public void changed(LocationEvent event) { String url = event.location; if (url == null) { return; } // guard against unnecessary History updates. Browser browser = (Browser) event.getSource(); if (browser.getData("navigation") != null //$NON-NLS-1$ && browser.getData("navigation").equals("true")) //$NON-NLS-1$ //$NON-NLS-2$ { return; } } /** * Intercept any LocationEvents on the browser. If the event location is a valid IntroURL, cancel the event and * execute the intro action that is embedded in the URL * * @param event */ @Override public void changing(LocationEvent event) { String url = event.location; if (url == null) { return; } } // /** // * flagStartOfFrameNavigation // */ // public void flagStartOfFrameNavigation() { // if(implementation.getBrowser().getData("frameNavigation") == null) //$NON-NLS-1$ // { // implementation.getBrowser().setData("frameNavigation", "true"); //$NON-NLS-1$ //$NON-NLS-2$ // } // } /** * flagEndOfFrameNavigation */ public void flagEndOfFrameNavigation() { implementation.getBrowser().setData("frameNavigation", null); //$NON-NLS-1$ } // /** // * flagStartOfNavigation // */ // public void flagStartOfNavigation() { // if(implementation.getBrowser().getData("navigation") == null) //$NON-NLS-1$ // { // implementation.getBrowser().setData("navigation", "true"); //$NON-NLS-1$ //$NON-NLS-2$ // } // } /** * flagEndOfNavigation */ public void flagEndOfNavigation() { implementation.getBrowser().setData("navigation", null); //$NON-NLS-1$ } // /** // * flagStoredTempUrl // */ // public void flagStoredTempUrl() { // if(implementation.getBrowser().getData("tempUrl") == null) //$NON-NLS-1$ // { // implementation.getBrowser().setData("tempUrl", "true"); //$NON-NLS-1$ //$NON-NLS-2$ // } // } /** * flagRemovedTempUrl */ public void flagRemovedTempUrl() { implementation.getBrowser().setData("tempUrl", null); //$NON-NLS-1$ } } /** * All browser history * * @author Ingo Muschenetz */ private class History { // History of Intro Pages and real URL visited by Intro Browser. All // elements are all of type HistoryObject. private Vector<HistoryObject> history = new Vector<HistoryObject>(); private int navigationLocation = 0; /** * Model class for history objects. A history object may be a URL or an Intro page. A URL is a regular URL * navigated to from a fully qualified link. An intro page may be an IFrame page. IFrame pages are not created * for every Help topic navigated in an embedded IFrame. Instead the same IFrame is stored in history as a * different object with the IFrameURL set. This way the model actually creates one page for every embedded Help * Topic target but the navigation history updates the IFrame accordingly. */ class HistoryObject { // String iframeUrl; String url; HistoryObject(Object location) { if (location instanceof String) { this.url = (String) location; } } String getUrl() { return url; } boolean isURL() { return (url != null) ? true : false; } // boolean isIFramePage() { // return (iframeUrl != null) ? true : false; // } } /** * Updates the UI navigation history with either a real URL, or a page ID. * * @param location */ public void updateHistory(String location) { // quick exit. if (!history.isEmpty() && isSameLocation(location)) { // resetting the same location is useless. return; } doUpdateHistory(location); } private void doUpdateHistory(Object location) { // we got here due to an intro URL listener or an SWT Form hyperlink // listener. location may be a URL or an IntroPage. if (navigationLocation == getHistoryEndPosition()) { // we are at the end of the vector, just push. pushToHistory(location); } else { // we already navigated. add item at current location, and clear // rest of history. (Same as browser behavior.) trimHistory(location); } } private boolean isSameLocation(Object location) { HistoryObject currentLocation = getCurrentLocation(); if (location instanceof String && currentLocation.isURL()) { return currentLocation.getUrl().equals(location); } return false; } private void pushToHistory(Object location) { history.add(new HistoryObject(location)); // point the nav location to the end of the vector. navigationLocation = getHistoryEndPosition(); } // /** // * removeLastHistory // */ // public void removeLastHistory() { // history.remove(getHistoryEndPosition()); // // point the nav location to the end of the vector. // navigationLocation = getHistoryEndPosition(); // } private void trimHistory(Object location) { List<HistoryObject> newHistory = history.subList(0, navigationLocation + 1); history = new Vector<HistoryObject>(newHistory); history.add(new HistoryObject(location)); // point the nav location to the end of the vector. navigationLocation = getHistoryEndPosition(); } /** * Return the position of the last element in the navigation history. If vector is empty, return 0. * * @param vector * @return int */ private int getHistoryEndPosition() { if (history.isEmpty()) { return 0; } return history.size() - 1; } // /** // * navigateHistoryBackward // */ // public void navigateHistoryBackward() { // if(badNavigationLocation(navigationLocation - 1)) { // // do nothing. We are at the beginning. // return; // } // --navigationLocation; // } // // /** // * Navigate forward in the history. // */ // public void navigateHistoryForward() { // if(badNavigationLocation(navigationLocation + 1)) { // // do nothing. We are at the beginning. // return; // } // ++navigationLocation; // } // private boolean badNavigationLocation(int navigationLocation) { // if(navigationLocation < 0 || navigationLocation >= history.size()) { // // bad nav location. // return true; // } // return false; // } /** * Returns true if the current location in the navigation history represents a URL. False if the location is an * Intro Page id. * * @return Returns the locationIsURL. */ private HistoryObject getCurrentLocation() { return history.elementAt(navigationLocation); } // /** // * canNavigateForward // * // * @return boolean // */ // public boolean canNavigateForward() { // return navigationLocation != getHistoryEndPosition() ? true : false; // } // // /** // * canNavigateBackward // * // * @return boolean // */ // public boolean canNavigateBackward() { // return navigationLocation == 0 ? false : true; // } // // /** // * currentLocationIsUrl // * // * @return boolean // */ // public boolean currentLocationIsUrl() { // return getCurrentLocation().isURL(); // } // // /** // * getCurrentLocationAsUrl // * // * @return boolean // */ // public String getCurrentLocationAsUrl() { // return getCurrentLocation().getUrl(); // } // // /** // * clear // */ // public void clear() { // history.clear(); // navigationLocation = 0; // } } }