| /******************************************************************************* |
| * Copyright (c) 2000, 2004 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 |
| *******************************************************************************/ |
| package org.eclipse.ui.views.framelist; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.commands.common.EventManager; |
| import org.eclipse.jface.util.Assert; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| |
| /** |
| * Supports a web-browser style of navigation by maintaining a list |
| * of frames. Each frame holds a snapshot of a view at some point |
| * in time. |
| * <p> |
| * The frame list obtains a snapshot of the current frame from a frame source |
| * on creation, and whenever switching to a different frame. |
| * </p> |
| * <p> |
| * A property change notification is sent whenever the current page changes. |
| * </p> |
| */ |
| public class FrameList extends EventManager { |
| |
| /** Property name constant for the current frame. */ |
| public static final String P_CURRENT_FRAME = "currentFrame"; //$NON-NLS-1$ |
| |
| private IFrameSource source; |
| |
| private List frames; |
| |
| private int current; |
| |
| /** |
| * Creates a new frame list with the given source. |
| * |
| * @param source the frame source |
| */ |
| public FrameList(IFrameSource source) { |
| this.source = source; |
| Frame frame = source.getFrame(IFrameSource.CURRENT_FRAME, 0); |
| frame.setParent(this); |
| frame.setIndex(0); |
| frames = new ArrayList(); |
| frames.add(frame); |
| current = 0; |
| } |
| |
| /** |
| * Adds a property change listener. |
| * Has no effect if an identical listener is already registered. |
| * |
| * @param listener a property change listener |
| */ |
| public void addPropertyChangeListener(IPropertyChangeListener listener) { |
| addListenerObject(listener); |
| } |
| |
| /** |
| * Moves the frame pointer back by one. |
| * Has no effect if there is no frame before the current one. |
| * Fires a <code>P_CURRENT_FRAME</code> property change event. |
| */ |
| public void back() { |
| if (current > 0) { |
| setCurrent(current - 1); |
| } |
| } |
| |
| /** |
| * Notifies any property change listeners that a property has changed. |
| * Only listeners registered at the time this method is called are notified. |
| * |
| * @param event the property change event |
| * |
| * @see IPropertyChangeListener#propertyChange |
| */ |
| protected void firePropertyChange(PropertyChangeEvent event) { |
| Object[] listeners = getListeners(); |
| for (int i = 0; i < listeners.length; ++i) { |
| ((IPropertyChangeListener) listeners[i]).propertyChange(event); |
| } |
| } |
| |
| /** |
| * Moves the frame pointer forward by one. |
| * Has no effect if there is no frame after the current one. |
| * Fires a <code>P_CURRENT_FRAME</code> property change event. |
| */ |
| public void forward() { |
| if (current < frames.size() - 1) { |
| setCurrent(current + 1); |
| } |
| } |
| |
| /** |
| * Returns the current frame. |
| * Returns <code>null</code> if there is no current frame. |
| * |
| * @return the current frame, or <code>null</code> |
| */ |
| public Frame getCurrentFrame() { |
| return getFrame(current); |
| } |
| |
| /** |
| * Returns the index of the current frame. |
| * |
| * @return the index of the current frame |
| */ |
| public int getCurrentIndex() { |
| return current; |
| } |
| |
| /** |
| * Returns the frame at the given index, or <code>null</code> |
| * if the index is ≤ 0 or ≥ <code>size()</code>. |
| * |
| * @param index the index of the requested frame |
| * @return the frame at the given index or <code>null</code> |
| */ |
| public Frame getFrame(int index) { |
| if (index < 0 || index >= frames.size()) |
| return null; |
| return (Frame) frames.get(index); |
| } |
| |
| /** |
| * Returns the frame source. |
| */ |
| public IFrameSource getSource() { |
| return source; |
| } |
| |
| /** |
| * Adds the given frame after the current frame, |
| * and advances the pointer to the new frame. |
| * Before doing so, updates the current frame, and removes any frames following the current frame. |
| * Fires a <code>P_CURRENT_FRAME</code> property change event. |
| * |
| * @param frame the frame to add |
| */ |
| public void gotoFrame(Frame frame) { |
| for (int i = frames.size(); --i > current;) { |
| frames.remove(i); |
| } |
| frame.setParent(this); |
| int index = frames.size(); |
| frame.setIndex(index); |
| frames.add(frame); |
| setCurrent(index); |
| } |
| |
| /** |
| * Removes a property change listener. |
| * Has no effect if an identical listener is not registered. |
| * |
| * @param listener a property change listener |
| */ |
| public void removePropertyChangeListener(IPropertyChangeListener listener) { |
| removeListenerObject(listener); |
| } |
| |
| /** |
| * Sets the current frame to the one with the given index. |
| * Updates the old current frame, and fires a <code>P_CURRENT_FRAME</code> property change event |
| * if the current frame changes. |
| * |
| * @param newCurrent the index of the frame |
| */ |
| void setCurrent(int newCurrent) { |
| Assert.isTrue(newCurrent >= 0 && newCurrent < frames.size()); |
| int oldCurrent = this.current; |
| if (oldCurrent != newCurrent) { |
| updateCurrentFrame(); |
| this.current = newCurrent; |
| firePropertyChange(new PropertyChangeEvent(this, P_CURRENT_FRAME, |
| getFrame(oldCurrent), getFrame(newCurrent))); |
| } |
| } |
| |
| /** |
| * Sets the current frame to the frame with the given index. |
| * Fires a <code>P_CURRENT_FRAME</code> property change event |
| * if the current frame changes. |
| */ |
| public void setCurrentIndex(int index) { |
| if (index != -1 && index != current) |
| setCurrent(index); |
| } |
| |
| /** |
| * Returns the number of frames in the frame list. |
| */ |
| public int size() { |
| return frames.size(); |
| } |
| |
| /** |
| * Replaces the current frame in this list with the current frame |
| * from the frame source. No event is fired. |
| */ |
| public void updateCurrentFrame() { |
| Assert.isTrue(current >= 0); |
| Frame frame = source.getFrame(IFrameSource.CURRENT_FRAME, |
| IFrameSource.FULL_CONTEXT); |
| frame.setParent(this); |
| frame.setIndex(current); |
| frames.set(current, frame); |
| } |
| } |