changeset 4500:ef80d24510fd

Clean up next/prev actions. Remove ContextAction class.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 05 Feb 2012 02:03:30 +0100
parents 5ddea75b496a
children d6f55cb223f4
files src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java src/share/tools/IdealGraphVisualizer/Editor/src/com/oracle/graal/visualizer/editor/EditorTopComponent.java src/share/tools/IdealGraphVisualizer/Editor/src/com/oracle/graal/visualizer/editor/actions/NextDiagramAction.java src/share/tools/IdealGraphVisualizer/Editor/src/com/oracle/graal/visualizer/editor/actions/PrevDiagramAction.java src/share/tools/IdealGraphVisualizer/OutlineView/src/com/oracle/graal/visualizer/outline/OutlineTopComponent.java src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/SnapshotTopComponent.java src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/actions/NextSnapshotAction.java src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/actions/PrevSnapshotAction.java src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/images/next_snapshot.png src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/images/prev_snapshot.png src/share/tools/IdealGraphVisualizer/Util/src/com/oracle/graal/visualizer/util/LookupUtils.java src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ContextAction.java src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/next_diagram.png src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/prev_diagram.png
diffstat 16 files changed, 227 insertions(+), 464 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Sun Feb 05 00:52:10 2012 +0100
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Sun Feb 05 02:03:30 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,18 +23,10 @@
  */
 package com.sun.hotspot.igv.data;
 
-/**
- * Class representing a generic changed event.
- * @author Thomas Wuerthinger
- * @param <T>
- */
 public class ChangedEvent<T> extends Event<ChangedListener<T>> {
 
     private T object;
 
-    /**
-     * Creates a new event with the specific object as the one for which the event gets fired.
-     */
     public ChangedEvent(T object) {
         this.object = object;
     }
@@ -43,4 +35,11 @@
     protected void fire(ChangedListener<T> l) {
         l.changed(object);
     }
+
+    public void changeObject(T newObject) {
+        if (object != newObject) {
+            this.object = newObject;
+            fire();
+        }
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java	Sun Feb 05 00:52:10 2012 +0100
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java	Sun Feb 05 02:03:30 2012 +0100
@@ -45,6 +45,11 @@
         listener.add(l);
     }
 
+    public void addListenerAndFire(L l) {
+        addListener(l);
+        fire(l);
+    }
+
     /**
      * Remove listener
      * @param l
--- a/src/share/tools/IdealGraphVisualizer/Editor/src/com/oracle/graal/visualizer/editor/EditorTopComponent.java	Sun Feb 05 00:52:10 2012 +0100
+++ b/src/share/tools/IdealGraphVisualizer/Editor/src/com/oracle/graal/visualizer/editor/EditorTopComponent.java	Sun Feb 05 02:03:30 2012 +0100
@@ -23,14 +23,8 @@
  */
 package com.oracle.graal.visualizer.editor;
 
-import com.oracle.graal.visualizer.editor.actions.NextDiagramAction;
-import com.oracle.graal.visualizer.editor.actions.PrevDiagramAction;
 import com.sun.hotspot.igv.data.*;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
-import com.sun.hotspot.igv.filter.FilterChain;
-import com.sun.hotspot.igv.filter.FilterChainProvider;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.services.DiagramProvider;
 import com.sun.hotspot.igv.util.LookupHistory;
 import com.sun.hotspot.igv.util.RangeSlider;
@@ -47,11 +41,9 @@
 import org.openide.actions.UndoAction;
 import org.openide.awt.Toolbar;
 import org.openide.awt.ToolbarPool;
-import org.openide.awt.UndoRedo;
 import org.openide.filesystems.FileUtil;
 import org.openide.util.ContextAwareAction;
 import org.openide.util.Lookup;
-import org.openide.util.Lookup.Provider;
 import org.openide.util.NbBundle;
 import org.openide.util.Utilities;
 import org.openide.util.actions.Presenter;
@@ -144,9 +136,6 @@
 
         rangeSliderModel.getChangedEvent().addListener(rangeSliderListener);
 
-        toolBar.add(PrevDiagramAction.get(PrevDiagramAction.class));
-        toolBar.add(NextDiagramAction.get(NextDiagramAction.class));
-
         toolBar.addSeparator();
         toolBar.add(UndoAction.get(UndoAction.class));
         toolBar.add(RedoAction.get(RedoAction.class));
--- a/src/share/tools/IdealGraphVisualizer/Editor/src/com/oracle/graal/visualizer/editor/actions/NextDiagramAction.java	Sun Feb 05 00:52:10 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.oracle.graal.visualizer.editor.actions;
-
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.util.ContextAction;
-import com.oracle.graal.visualizer.editor.DiagramViewModel;
-import com.sun.hotspot.igv.util.RangeSliderModel;
-import javax.swing.Action;
-import javax.swing.ImageIcon;
-import org.openide.awt.ActionID;
-import org.openide.awt.ActionReference;
-import org.openide.awt.ActionRegistration;
-import org.openide.util.*;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-@ActionID(id = "com.oracle.graal.visualizer.editor.actions.NextDiagramAction", category = "View")
-@ActionRegistration(displayName = "Next snapshot")
-@ActionReference(path = "Menu/View", position = 150)
-public final class NextDiagramAction extends ContextAction<RangeSliderModel> implements ChangedListener<RangeSliderModel> {
-
-    private RangeSliderModel model;
-
-    public NextDiagramAction() {
-        this(Utilities.actionsGlobalContext());
-    }
-
-    public NextDiagramAction(Lookup lookup) {
-        putValue(Action.SHORT_DESCRIPTION, "Show next graph of current group");
-        putValue(Action.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage("com/sun/hotspot/igv/view/images/next_diagram.png")));
-    }
-
-    @Override
-    public String getName() {
-        return "Next snapshot";
-    }
-
-    @Override
-    public HelpCtx getHelpCtx() {
-        return HelpCtx.DEFAULT_HELP;
-    }
-
-    @Override
-    public Class<RangeSliderModel> contextClass() {
-        return RangeSliderModel.class;
-    }
-
-    @Override
-    public void performAction(RangeSliderModel model) {
-        int fp = model.getFirstPosition();
-        int sp = model.getSecondPosition();
-        if (sp != model.getPositions().size() - 1) {
-            int nfp = fp + 1;
-            int nsp = sp + 1;
-            model.setPositions(nfp, nsp);
-        }
-    }
-
-    @Override
-    public void update(RangeSliderModel model) {
-        super.update(model);
-
-        if (this.model != model) {
-            if (this.model != null) {
-                this.model.getChangedEvent().removeListener(this);
-            }
-
-            this.model = model;
-            if (this.model != null) {
-                this.model.getChangedEvent().addListener(this);
-            }
-        }
-    }
-
-    @Override
-    public boolean isEnabled(RangeSliderModel model) {
-        return model.getSecondPosition() != model.getPositions().size() - 1;
-    }
-
-    @Override
-    public Action createContextAwareInstance(Lookup arg0) {
-        return new NextDiagramAction(arg0);
-    }
-
-    @Override
-    public void changed(RangeSliderModel source) {
-        update(source);
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Editor/src/com/oracle/graal/visualizer/editor/actions/PrevDiagramAction.java	Sun Feb 05 00:52:10 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.oracle.graal.visualizer.editor.actions;
-
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.util.ContextAction;
-import com.oracle.graal.visualizer.editor.DiagramViewModel;
-import com.sun.hotspot.igv.util.RangeSliderModel;
-import javax.swing.Action;
-import javax.swing.ImageIcon;
-import org.openide.awt.ActionID;
-import org.openide.awt.ActionReference;
-import org.openide.awt.ActionRegistration;
-import org.openide.util.*;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-@ActionID(id = "com.oracle.graal.visualizer.editor.actions.PrevDiagramAction", category = "View")
-@ActionRegistration(displayName = "Previous snapshot")
-@ActionReference(path = "Menu/View", position = 100)
-public final class PrevDiagramAction extends ContextAction<RangeSliderModel> implements ChangedListener<RangeSliderModel> {
-
-    private RangeSliderModel model;
-
-    public PrevDiagramAction() {
-        this(Utilities.actionsGlobalContext());
-    }
-
-    public PrevDiagramAction(Lookup lookup) {
-        putValue(Action.SHORT_DESCRIPTION, "Show previous graph of current group");
-        putValue(Action.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage("com/sun/hotspot/igv/view/images/prev_diagram.png")));
-    }
-
-    @Override
-    public String getName() {
-        return "Previous snapshot";
-    }
-
-    @Override
-    public HelpCtx getHelpCtx() {
-        return HelpCtx.DEFAULT_HELP;
-    }
-
-    @Override
-    public Class<RangeSliderModel> contextClass() {
-        return RangeSliderModel.class;
-    }
-
-    @Override
-    public void performAction(RangeSliderModel model) {
-        int fp = model.getFirstPosition();
-        int sp = model.getSecondPosition();
-        if (fp != 0) {
-            int nfp = fp - 1;
-            int nsp = sp - 1;
-            model.setPositions(nfp, nsp);
-        }
-    }
-
-    @Override
-    public void update(RangeSliderModel model) {
-        super.update(model);
-
-        if (this.model != model) {
-            if (this.model != null) {
-                this.model.getChangedEvent().removeListener(this);
-            }
-
-            this.model = model;
-            if (this.model != null) {
-                this.model.getChangedEvent().addListener(this);
-            }
-        }
-    }
-
-    @Override
-    public boolean isEnabled(RangeSliderModel model) {
-        return model.getFirstPosition() != 0;
-    }
-
-    @Override
-    public Action createContextAwareInstance(Lookup arg0) {
-        return new PrevDiagramAction(arg0);
-    }
-
-    @Override
-    public void changed(RangeSliderModel source) {
-        update(source);
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/OutlineView/src/com/oracle/graal/visualizer/outline/OutlineTopComponent.java	Sun Feb 05 00:52:10 2012 +0100
+++ b/src/share/tools/IdealGraphVisualizer/OutlineView/src/com/oracle/graal/visualizer/outline/OutlineTopComponent.java	Sun Feb 05 02:03:30 2012 +0100
@@ -23,34 +23,27 @@
  */
 package com.oracle.graal.visualizer.outline;
 
-import com.oracle.graal.visualizer.outline.server.Server;
 import com.oracle.graal.visualizer.outline.server.ServerPanel;
+import com.oracle.graal.visualizer.util.LookupUtils;
 import com.sun.hotspot.igv.data.GraphDocument;
 import java.awt.BorderLayout;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 import javax.swing.Action;
 import javax.swing.UIManager;
 import javax.swing.border.Border;
-import org.openide.ErrorManager;
 import org.openide.actions.GarbageCollectAction;
 import org.openide.awt.Toolbar;
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
 import org.openide.explorer.view.BeanTreeView;
 import org.openide.util.ContextAwareAction;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
 import org.openide.util.NbBundle;
 import org.openide.util.lookup.Lookups;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
 
-public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
+public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider {
 
     public static final String GLOBAL_ACTIONS_FOLDER = "Actions/Outline/Global";
     public static final String NODE_ACTIONS_FOLDER = "Actions/Outline/Nodes";
@@ -58,7 +51,6 @@
     public static final String PREFERRED_ID = "OutlineTopComponent";
     private ExplorerManager manager;
     private GraphDocument document;
-    private Server server;
 
     private OutlineTopComponent() {
         initComponents();
@@ -84,26 +76,12 @@
         Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
         toolbar.setBorder(b);
         this.add(toolbar, BorderLayout.NORTH);
-        for (Action a : lookupActions(GLOBAL_ACTIONS_FOLDER)) {
+        for (Action a : LookupUtils.lookupActions(GLOBAL_ACTIONS_FOLDER, getLookup())) {
             toolbar.add(a);
         }
         toolbar.add(GarbageCollectAction.get(GarbageCollectAction.class).getToolbarPresenter());
         toolbar.add(new ServerPanel(getDocument()));
     }
-    
-    private List<Action> lookupActions(String path) {
-        List<Action> actions = new ArrayList<>();
-        for (Action a : Lookups.forPath(path).lookupAll(Action.class)) {
-            Action newAction = a;
-            if (a instanceof ContextAwareAction) {
-                newAction = ((ContextAwareAction) a).createContextAwareInstance(getLookup());
-            }
-            newAction.putValue(Action.SHORT_DESCRIPTION, newAction.getValue(Action.NAME));
-            actions.add(newAction);
-            
-        }
-        return actions;
-    }
 
     public void clear() {
         document.clear();
@@ -118,47 +96,13 @@
         return document;
     }
 
-    /**
-     * Gets default instance. Do not use directly: reserved for *.settings files
-     * only, i.e. deserialization routines; otherwise you could get a
-     * non-deserialized instance. To obtain the singleton instance, use {@link findInstance}.
-     */
-    public static synchronized OutlineTopComponent getDefault() {
-        if (instance == null) {
-            instance = new OutlineTopComponent();
-        }
-        return instance;
-    }
-
-    /**
-     * Obtain the OutlineTopComponent instance. Never call {@link #getDefault}
-     * directly!
-     */
-    public static synchronized OutlineTopComponent findInstance() {
-        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
-        if (win == null) {
-            ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find Outline component. It will not be located properly in the window system.");
-            return getDefault();
-        }
-        if (win instanceof OutlineTopComponent) {
-            return (OutlineTopComponent) win;
-        }
-        ErrorManager.getDefault().log(ErrorManager.WARNING, "There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior.");
-        return getDefault();
+    public static OutlineTopComponent findInstance() {
+        return (OutlineTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
     }
 
     @Override
     public int getPersistenceType() {
-        return TopComponent.PERSISTENCE_ALWAYS;
-    }
-
-    @Override
-    public void componentOpened() {
-        this.requestActive();
-    }
-
-    @Override
-    public void componentClosed() {
+        return TopComponent.PERSISTENCE_NEVER;
     }
 
     @Override
@@ -166,49 +110,6 @@
         return PREFERRED_ID;
     }
 
-    @Override
-    public void requestActive() {
-        super.requestActive();
-        treeView.requestFocus();
-    }
-
-    @Override
-    public boolean requestFocus(boolean temporary) {
-        treeView.requestFocus();
-        return super.requestFocus(temporary);
-    }
-
-    @Override
-    protected boolean requestFocusInWindow(boolean temporary) {
-        treeView.requestFocus();
-        return super.requestFocusInWindow(temporary);
-    }
-
-    @Override
-    public void resultChanged(LookupEvent lookupEvent) {
-    }
-
-    @Override
-    public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {
-        // Not called when user starts application for the first time
-        super.readExternal(objectInput);
-        ((BeanTreeView) this.treeView).setRootVisible(false);
-    }
-
-    @Override
-    public void writeExternal(ObjectOutput objectOutput) throws IOException {
-        super.writeExternal(objectOutput);
-    }
-
-    static final class ResolvableHelper implements Serializable {
-
-        private static final long serialVersionUID = 1L;
-
-        public Object readResolve() {
-            return OutlineTopComponent.getDefault();
-        }
-    }
-
     /**
      * This method is called from within the constructor to initialize the form.
      * WARNING: Do NOT modify this code. The content of this method is always
--- a/src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/SnapshotTopComponent.java	Sun Feb 05 00:52:10 2012 +0100
+++ b/src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/SnapshotTopComponent.java	Sun Feb 05 02:03:30 2012 +0100
@@ -25,25 +25,31 @@
 
 import com.oracle.graal.visualizer.editor.EditorTopComponent;
 import com.oracle.graal.visualizer.util.LookupUtils;
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.util.RangeSlider;
 import com.sun.hotspot.igv.util.RangeSliderModel;
 import java.awt.BorderLayout;
+import javax.swing.JScrollPane;
 import org.openide.awt.ActionID;
 import org.openide.awt.ActionReference;
 import org.openide.util.Lookup.Result;
 import org.openide.util.LookupEvent;
 import org.openide.util.LookupListener;
 import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
 
-@TopComponent.Description(preferredID = "SnapshotTopComponent", persistenceType = TopComponent.PERSISTENCE_NEVER)
+@TopComponent.Description(preferredID = SnapshotTopComponent.PREFERRED_ID, persistenceType = TopComponent.PERSISTENCE_NEVER)
 @TopComponent.Registration(mode = "output", openAtStartup = true)
 @ActionID(category = "Window", id = "com.oracle.graal.visualizer.snapshots.SnapshotTopComponent")
 @ActionReference(path = "Menu/Window")
 @TopComponent.OpenActionRegistration(displayName = "Snapshot", preferredID = "SnapshotTopComponent")
 public final class SnapshotTopComponent extends TopComponent {
+    public static final String PREFERRED_ID = "SnapshotTopComponent";
 
     private final Result<RangeSliderModel> result;
     private final RangeSlider rangeSlider;
+    private final ChangedEvent<RangeSliderModel> rangeSliderChangedEvent = new ChangedEvent<RangeSliderModel>(null);
     private final LookupListener lookupListener = new LookupListener() {
 
         @Override
@@ -51,6 +57,14 @@
             update();
         }
     };
+    
+    private final ChangedListener<RangeSliderModel> rangeSliderChangedListener = new ChangedListener<RangeSliderModel>(){
+
+        @Override
+        public void changed(RangeSliderModel source) {
+            rangeSliderChangedEvent.fire();
+        }
+    };
 
     public SnapshotTopComponent() {
         initComponents();
@@ -61,17 +75,34 @@
         result.addLookupListener(lookupListener);
         this.rangeSlider = new RangeSlider(null);
         this.setLayout(new BorderLayout());
-        this.add(rangeSlider, BorderLayout.CENTER);
+        this.add(new JScrollPane(rangeSlider), BorderLayout.CENTER);
+        LookupUtils.lookupActions("Actions/View");
         update();
-
     }
 
     private void update() {
+        RangeSliderModel newModel;
         if (result.allInstances().size() > 0) {
-            rangeSlider.setModel(result.allInstances().iterator().next());
+            newModel = result.allInstances().iterator().next();
         } else {
-            rangeSlider.setModel(null);
+            newModel = null;
+        }
+        if (rangeSlider.getModel() != null) {
+            rangeSlider.getModel().getChangedEvent().removeListener(rangeSliderChangedListener);
         }
+        rangeSlider.setModel(newModel);
+        rangeSliderChangedEvent.changeObject(newModel);
+        if (newModel != null) {
+            newModel.getChangedEvent().addListener(rangeSliderChangedListener);
+        }
+    }
+
+    public ChangedEvent<RangeSliderModel> getRangeSliderChangedEvent() {
+        return rangeSliderChangedEvent;
+    }
+
+    public static SnapshotTopComponent findInstance() {
+        return (SnapshotTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
     }
 
     /**
@@ -94,4 +125,5 @@
     }// </editor-fold>//GEN-END:initComponents
     // Variables declaration - do not modify//GEN-BEGIN:variables
     // End of variables declaration//GEN-END:variables
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/actions/NextSnapshotAction.java	Sun Feb 05 02:03:30 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.oracle.graal.visualizer.snapshots.actions;
+
+import com.oracle.graal.visualizer.snapshots.SnapshotTopComponent;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.util.RangeSliderModel;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.editor.actions.NextSnapshotAction", category = "View")
+@ActionRegistration(displayName = "Next snapshot", iconBase = "com/oracle/graal/visualizer/snapshots/images/next_snapshot.png")
+@ActionReference(path = "Menu/View", position = 150)
+public final class NextSnapshotAction extends AbstractAction{
+
+    private RangeSliderModel model;
+
+    public NextSnapshotAction() {
+        SnapshotTopComponent.findInstance().getRangeSliderChangedEvent().addListenerAndFire(changeListener);
+    }
+    private final ChangedListener<RangeSliderModel> changeListener = new ChangedListener<RangeSliderModel>() {
+
+        @Override
+        public void changed(RangeSliderModel source) {
+            model = source;
+            setEnabled(model != null && model.getSecondPosition() != model.getPositions().size() - 1);
+        }
+    };
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (model != null) {
+            int fp = model.getFirstPosition();
+            int sp = model.getSecondPosition();
+            if (sp != model.getPositions().size() - 1) {
+                int nfp = fp + 1;
+                int nsp = sp + 1;
+                model.setPositions(nfp, nsp);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/actions/PrevSnapshotAction.java	Sun Feb 05 02:03:30 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.oracle.graal.visualizer.snapshots.actions;
+
+import com.oracle.graal.visualizer.snapshots.SnapshotTopComponent;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.util.RangeSliderModel;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.editor.actions.PrevSnapshotAction", category = "View")
+@ActionRegistration(displayName = "Previous snapshot", iconBase = "com/oracle/graal/visualizer/snapshots/images/prev_snapshot.png")
+@ActionReference(path = "Menu/View", position = 100)
+public final class PrevSnapshotAction extends AbstractAction {
+
+    private RangeSliderModel model;
+
+    public PrevSnapshotAction() {
+        SnapshotTopComponent.findInstance().getRangeSliderChangedEvent().addListenerAndFire(changeListener);
+    }
+    private final ChangedListener<RangeSliderModel> changeListener = new ChangedListener<RangeSliderModel>() {
+
+        @Override
+        public void changed(RangeSliderModel source) {
+            model = source;
+            setEnabled(model != null && model.getFirstPosition() != 0);
+        }
+    };
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (model != null) {
+            int fp = model.getFirstPosition();
+            int sp = model.getSecondPosition();
+            if (fp != 0) {
+                int nfp = fp - 1;
+                int nsp = sp - 1;
+                model.setPositions(nfp, nsp);
+            }
+        }
+    }
+}
Binary file src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/images/next_snapshot.png has changed
Binary file src/share/tools/IdealGraphVisualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/images/prev_snapshot.png has changed
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/oracle/graal/visualizer/util/LookupUtils.java	Sun Feb 05 00:52:10 2012 +0100
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/oracle/graal/visualizer/util/LookupUtils.java	Sun Feb 05 02:03:30 2012 +0100
@@ -26,6 +26,10 @@
 
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.Action;
+import org.openide.util.ContextAwareAction;
 import org.openide.util.Lookup;
 import org.openide.util.Lookup.Provider;
 import org.openide.util.lookup.Lookups;
@@ -48,6 +52,24 @@
         return topComponentLookupImpl.lookup;
     }
     
+    public static Iterable<Action> lookupActions(String path) {
+        return lookupActions(path, null);
+    }
+
+    public static Iterable<Action> lookupActions(String path, Lookup context) {
+        List<Action> actions = new ArrayList<>();
+        for (Action a : Lookups.forPath(path).lookupAll(Action.class)) {
+            Action newAction = a;
+            if (a instanceof ContextAwareAction && context != null) {
+                newAction = ((ContextAwareAction) a).createContextAwareInstance(context);
+            }
+            newAction.putValue(Action.SHORT_DESCRIPTION, newAction.getValue(Action.NAME));
+            actions.add(newAction);
+            
+        }
+        return actions;
+    }
+    
     private static class TopComponentLookup implements PropertyChangeListener {
         private final Class<?> clazz;
         private final Lookup lookup;
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ContextAction.java	Sun Feb 05 00:52:10 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.util;
-
-import java.awt.EventQueue;
-import org.openide.util.*;
-import org.openide.util.actions.CallableSystemAction;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public abstract class ContextAction<T> extends CallableSystemAction implements LookupListener, ContextAwareAction {
-
-    private Lookup context = null;
-    private Lookup.Result<T> result = null;
-
-    public ContextAction() {
-        this(Utilities.actionsGlobalContext());
-    }
-
-    public ContextAction(Lookup context) {
-        init(context);
-    }
-
-    private void init(Lookup context) {
-        this.context = context;
-        result = context.lookupResult(contextClass());
-        result.addLookupListener(this);
-        resultChanged(null);
-    }
-
-    @Override
-    public void resultChanged(LookupEvent e) {
-        if (result.allItems().size() != 0) {
-            update(result.allInstances().iterator().next());
-        } else {
-            update(null);
-        }
-    }
-
-    @Override
-    public void performAction() {
-        final T t = result.allInstances().iterator().next();
-
-        // Ensure it's AWT event thread
-        EventQueue.invokeLater(new Runnable() {
-
-            @Override
-            public void run() {
-                performAction(t);
-            }
-        });
-    }
-
-    public void update(T t) {
-        if (t == null) {
-            setEnabled(false);
-        } else {
-            setEnabled(isEnabled(t));
-        }
-    }
-
-    public boolean isEnabled(T context) {
-        return true;
-    }
-
-    public abstract Class<T> contextClass();
-
-    public abstract void performAction(T context);
-}
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java	Sun Feb 05 00:52:10 2012 +0100
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java	Sun Feb 05 02:03:30 2012 +0100
@@ -63,23 +63,21 @@
 
     @Override
     public Dimension getPreferredSize() {
-        Dimension d = super.getPreferredSize();
-        Graphics g = this.getGraphics();
-
-        int maxWidth = 0;
-        List<String> list = getPaintingModel().getPositions();
-        for (int i = 0; i < list.size(); i++) {
-
-            String curS = list.get(i);
-            if (curS != null && curS.length() > 0) {
-                FontMetrics metrics = g.getFontMetrics();
-                Rectangle bounds = metrics.getStringBounds(curS, g).getBounds();
-                maxWidth = Math.max(maxWidth, (int) bounds.getWidth());
+        if (getPaintingModel() != null) {
+            Graphics g = this.getGraphics();
+            int maxWidth = 0;
+            List<String> list = getPaintingModel().getPositions();
+            for (int i = 0; i < list.size(); i++) {
+                String curS = list.get(i);
+                if (curS != null && curS.length() > 0) {
+                    FontMetrics metrics = g.getFontMetrics();
+                    Rectangle bounds = metrics.getStringBounds(curS, g).getBounds();
+                    maxWidth = Math.max(maxWidth, (int) bounds.getWidth());
+                }
             }
+            return new Dimension(maxWidth + ITEM_WIDTH, ITEM_HEIGHT * list.size());
         }
-        d.width = maxWidth + ITEM_WIDTH;
-        d.height = ITEM_HEIGHT * list.size();
-        return d;
+        return super.getPreferredSize();
     }
     private ChangedListener<RangeSliderModel> modelChangedListener = new ChangedListener<RangeSliderModel>() {
 
@@ -244,6 +242,10 @@
         }
     };
 
+    public RangeSliderModel getModel() {
+        return model;
+    }
+
     public void setModel(RangeSliderModel newModel) {
         if (newModel != this.model) {
             if (this.model != null) {
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/next_diagram.png has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/prev_diagram.png has changed