/* * Copyright (c) 2007, 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 com.sun.max.ins.*; import com.sun.max.ins.gui.*; import com.sun.max.ins.view.InspectionViews.ViewKind; /** * Abstract manager for a kind of view that is a singleton which can either be active (the instance * exists and is visible) or not. * <p> * Subclasses must implement {@link SingletonViewManager#activateView()} and set the view in this abstract * class. * @param <View_Kind> a kind of view that is to be managed as a singleton */ public abstract class AbstractSingletonViewManager<View_Kind extends InspectorView> extends AbstractInspectionHolder implements SingletonViewManager { private final ViewKind viewKind; private final String shortName; private final String longName; /** * The active view instance; null when inactive. */ private ArrayList<View_Kind> views = new ArrayList<View_Kind>(1); private final InspectorAction activateViewAction; private final InspectorAction deactivateAllAction; protected AbstractSingletonViewManager(Inspection inspection, ViewKind viewKind, String shortName, String longName) { super(inspection); this.viewKind = viewKind; this.shortName = shortName; this.longName = longName; this.activateViewAction = new ActivateViewAction(shortName); this.deactivateAllAction = new DeactivateAllAction(shortName); } public final ViewKind viewKind() { return viewKind; } public final String shortName() { return shortName; } public final String longName() { return longName; } public final boolean isSingleton() { return true; } /** * {@inheritDoc} * <p> * Singleton 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> * Singleton views 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 View_Kind activateView() { if (views.size() == 0) { final View_Kind view = createView(inspection()); views.add(view); view.addViewEventListener(new ViewEventListener() { @Override public void viewClosing(InspectorView view) { assert views.remove(view); refresh(); } }); refresh(); } return views.get(0); } public final void deactivateView() { assert views.size() == 1; views.get(0).dispose(); } public final InspectorAction activateSingletonViewAction() { return activateViewAction; } public InspectorAction deactivateAllAction(InspectorView exception) { if (exception == null) { return deactivateAllAction; } return new DeactivateAllExceptAction(shortName, exception); } /** * Creates an instance of the concrete view kind. */ protected abstract View_Kind createView(Inspection inspection); /** * Update any internal state on occasion of view activation/deactivation. */ private void refresh() { deactivateAllAction.refresh(true); } /** * Action: makes visible and highlights a singleton view. * <p> * Note that this action is enabled, even when the view is already * activated (visible); in that case it serves to bring the view * forward and highlight it. */ private final class ActivateViewAction extends InspectorAction { public ActivateViewAction(String title) { super(inspection(), "View " + title); refresh(true); } @Override protected void procedure() { activateView().highlight(); } @Override public void refresh(boolean force) { setEnabled(AbstractSingletonViewManager.this.isEnabled()); } } /** * Action: deactivate all views, which in the case of a singleton * means only the one view, if already activated. */ private final class DeactivateAllAction extends InspectorAction { public DeactivateAllAction(String title) { super(inspection(), "Close " + title + " view"); } @Override protected void procedure() { if (isActive()) { deactivateView(); } } @Override public void refresh(boolean force) { setEnabled(isActive()); } } /** * Action: deactivate the singleton view, with one exception, which might * be the singleton view itself. */ private final class DeactivateAllExceptAction extends InspectorAction { private final InspectorView exceptInspector; public DeactivateAllExceptAction(String title, InspectorView exceptInspector) { super(inspection(), "Close " + title + " view"); this.exceptInspector = exceptInspector; } @Override protected void procedure() { if (isActive() && !views.get(0).equals(exceptInspector)) { deactivateView(); } } @Override public void refresh(boolean force) { setEnabled(isActive()); } } }