/* * Copyright (c) 2011, 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.sun.max.ins.view; import java.util.*; import javax.swing.*; import javax.swing.event.*; import com.sun.max.ins.*; import com.sun.max.ins.gui.*; import com.sun.max.ins.view.InspectionViews.ViewKind; import com.sun.max.tele.*; /** * Abstract manager for a kind of view that can occur in multiple * instances. */ public abstract class AbstractMultiViewManager<View_Kind extends InspectorView> extends AbstractInspectionHolder implements MultiViewManager, InspectionViewFactory<View_Kind>, InspectionListener { private final ViewKind viewKind; private final String shortName; private final String longName; private final ArrayList<View_Kind> views = new ArrayList<View_Kind>(); private final InspectorAction deactivateAllAction; protected AbstractMultiViewManager(Inspection inspection, ViewKind viewKind, String shortName, String longName) { super(inspection); this.viewKind = viewKind; this.shortName = shortName; this.longName = longName; this.deactivateAllAction = new DeactivateAllAction(shortName); inspection().addInspectionListener(this); refresh(); } public final ViewKind viewKind() { return viewKind; } public final String shortName() { return shortName; } public final String longName() { return longName; } public final boolean isSingleton() { return false; } /** * {@inheritDoc} * <p> * Multiple view kinds are assumed by default to be supported. * Concrete view manager types should override if this * isn't always so. */ public boolean isSupported() { return true; } /** * {@inheritDoc} * <p> * Multiple view kinds are assumed by default to be enabled * if they are supported. * Concrete view manager types should override if this * isn't always so. */ public boolean isEnabled() { return isSupported(); } public final boolean isActive() { return views.size() > 0; } public final List<View_Kind> activeViews() { return views; } public final JMenu viewMenu() { final JMenu menu = new JMenu("View " + shortName); menu.addMenuListener(new MenuListener() { public void menuCanceled(MenuEvent e) { } public void menuDeselected(MenuEvent e) { } public void menuSelected(MenuEvent e) { menu.removeAll(); final List<View_Kind> views = activeViews(); if (views.size() > 0) { for (InspectorAction makeViewAction : makeViewActions()) { menu.add(makeViewAction); } menu.addSeparator(); menu.add(deactivateAllAction); for (InspectorAction closeViewAction : closeViewActions()) { menu.add(closeViewAction); } menu.addSeparator(); for (InspectorView view : views) { menu.add(view.getShowViewAction()); } } else { for (InspectorAction makeViewAction : makeViewActions()) { menu.add(makeViewAction); } } } }); return menu; } public final void deactivateAllUnpinnedViews() { for (InspectorView view : new ArrayList<View_Kind>(views)) { if (!view.isPinned()) { view.dispose(); } } refresh(); } public final InspectorAction deactivateAllAction(InspectorView exception) { if (exception == null) { return deactivateAllAction; } return new DeactivateAllExceptAction(shortName, exception); } /** * Allows concrete subclasses to register the creation of a new view. */ protected final void notifyAddingView(View_Kind view) { assert views.add(view); view.addViewEventListener(new ViewEventListener() { @Override public void viewClosing(InspectorView view) { assert views.remove(view); refresh(); } }); refresh(); } /** * Gets a list of interactive (context-independent) actions that * can make a new view. These will be added to the view menu * for this kind. * * @return actions that can create a new view */ protected List<InspectorAction> makeViewActions() { return Collections.emptyList(); } /** * Gets a list of interactive (context-independent) actions that * can close existing views. These will be added to the view menu * for this kind. * * @return actions that can close existing views */ protected List<InspectorAction> closeViewActions() { return Collections.emptyList(); } public void vmStateChanged(boolean force) { } public void breakpointStateChanged() { } public void breakpointToBeDeleted(MaxBreakpoint breakpoint, String reason) { } public void watchpointSetChanged() { } public void viewConfigurationChanged() { } public void vmProcessTerminated() { } public void inspectionEnding() { } /** * Update any internal state on occasion of view activation/deactivation. */ private void refresh() { deactivateAllAction.refresh(true); } private final class DeactivateAllAction extends InspectorAction { public DeactivateAllAction(String title) { super(inspection(), "Close unpinned " + title + " views"); } @Override protected void procedure() { deactivateAllUnpinnedViews(); } @Override public void refresh(boolean force) { setEnabled(isActive()); } } private final class DeactivateAllExceptAction extends InspectorAction { private final InspectorView exceptInspector; public DeactivateAllExceptAction(String title, InspectorView exceptInspector) { super(inspection(), "Close other " + title + " views"); this.exceptInspector = exceptInspector; } @Override protected void procedure() { for (InspectorView view : new ArrayList<View_Kind>(views)) { if (!view.equals(exceptInspector)) { view.dispose(); } } AbstractMultiViewManager.this.refresh(); } @Override public void refresh(boolean force) { setEnabled(isActive()); } } }