001: /*
002: * <copyright>
003: *
004: * Copyright 2000-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.tools.csmart.ui.util;
028:
029: import org.cougaar.tools.csmart.ui.viewer.CSMART;
030: import org.cougaar.util.log.Logger;
031:
032: import javax.swing.*;
033: import java.io.IOException;
034: import java.io.ObjectInputStream;
035: import java.util.Enumeration;
036: import java.util.Hashtable;
037: import java.util.Observable;
038:
039: /**
040: * Ensure that window names are unique within the CSMARTUL application.
041: * Notify observers (generally, just the CSMARTUL application) when a window
042: * is created or destroyed, so that it
043: * can maintain a list of window menu items.
044: * Do not create this object directly. Use Util.getNamedFrame() to
045: * obtain the single NamedFrame object for the CSMARTUL application.
046: * @see Util#getNamedFrame
047: */
048:
049: public class NamedFrame extends Observable {
050: public static final String AGENT = "Agents";
051: public static final String COMMUNITY = "Community";
052: public static final String EVENTS = "Events";
053: public static final String PLAN = "Plan";
054: public static final String SOCIETY = "Society";
055: public static final String THREAD = "Thread";
056: public static final String HAPPINESS = "Happiness";
057: public static final String ALLOC_FAILURE = "Allocations";
058: public static final String INV_LEVEL = "Inventory";
059: public static final String METRICS = "Metrics";
060: // public static final String TOPOLOGY = "Topology";
061: public static final String XML = "XML";
062:
063: private static transient Hashtable titleToFrame = new Hashtable();
064: private static String titles[] = { COMMUNITY, AGENT, SOCIETY, PLAN,
065: EVENTS, THREAD, HAPPINESS, ALLOC_FAILURE, INV_LEVEL,
066: METRICS, XML
067: // METRICS,
068: // TOPOLOGY
069: };
070: private static int index[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // used for common titles
071:
072: // If CSMART dies do not store the info on what windows are open
073: private static transient NamedFrame singleton = null;
074:
075: private transient Logger log;
076:
077: public static synchronized NamedFrame getNamedFrame() {
078: if (singleton == null) {
079: singleton = new NamedFrame();
080: }
081: return singleton;
082: }
083:
084: /**
085: * Disallow new. Must use singleton instance via getNamedFrame
086: **/
087: private NamedFrame() {
088: createLogger();
089: }
090:
091: private void createLogger() {
092: log = CSMART.createLogger(this .getClass().getName());
093: }
094:
095: /**
096: * Add a frame with the specified title and notify observers.
097: * The titles are either "common" titles as specified by the
098: * Strings in this class, or they are the names of files from
099: * which the graphs were read.
100: * Returns a title which is unique (by appending a number if necessary).
101: * @param title frame title
102: * @param frame the frame
103: * @return title of the frame
104: */
105: public String addFrame(String title, JFrame frame) {
106: if (frame == null)
107: return null;
108: if (title == null)
109: title = "Unknown Frame";
110:
111: // number commonly used titles
112: for (int i = 0; i < titles.length; i++) {
113: if (title.equals(titles[i])) {
114: title = titles[i] + " " + index[i]++;
115: break;
116: }
117: }
118: String baseTitle = title;
119: int otherIndex = 1;
120: while (titleToFrame.get(title) != null)
121: title = baseTitle + " " + otherIndex++;
122: titleToFrame.put(title, frame);
123: setChanged();
124: // notify observers with title and frame
125: notifyObservers(new Event(frame, title, Event.ADDED, null));
126: frame.setTitle(title);
127: return title;
128: }
129:
130: public JFrame getFrame(String title) {
131: return (JFrame) titleToFrame.get(title);
132: }
133:
134: public JFrame getToolFrame(String toolTitle) {
135: Enumeration titles = titleToFrame.keys();
136: while (titles.hasMoreElements()) {
137: String title = (String) titles.nextElement();
138: if (title.startsWith(toolTitle))
139: return (JFrame) titleToFrame.get(title);
140: }
141: return null;
142: }
143:
144: public JFrame getToolFrame(String toolTitle, String societyName) {
145: String newTitle = toolTitle + ": " + societyName;
146: Enumeration titles = titleToFrame.keys();
147: while (titles.hasMoreElements()) {
148: String title = (String) titles.nextElement();
149: if (title.startsWith(toolTitle)) {
150: JFrame frame = (JFrame) titleToFrame.get(title);
151: if (title.equals(newTitle))
152: return frame;
153: else {
154: // rename frame by removing and adding
155: titleToFrame.remove(title);
156: titleToFrame.put(newTitle, frame);
157: frame.setTitle(newTitle);
158: setChanged();
159: notifyObservers(new Event(frame, newTitle,
160: Event.CHANGED, title));
161: return frame;
162: }
163: }
164: }
165: return null;
166: }
167:
168: /**
169: * Remove a frame and notify observers.
170: * @param frame the frame to remove
171: */
172: public void removeFrame(JFrame frame) {
173: // String s = removeTitleColon(frame.getTitle());
174: String s = frame.getTitle();
175: if (log.isDebugEnabled()) {
176: log.debug("Removing frame " + s);
177: }
178:
179: if (titleToFrame.remove(s) == null) {
180: if (log.isInfoEnabled()) {
181: log.info("Couldnt find frame " + s);
182: }
183: // Nothing changed so dont tell people it did
184: } else {
185: setChanged();
186: notifyObservers(new Event(frame, s, Event.REMOVED, null));
187: }
188: }
189:
190: // public static String removeTitleColon(String title) {
191: // int colon = title.indexOf(':');
192: // if (colon >= 0) title = title.substring(0, colon).trim();
193: // return title;
194: // }
195:
196: public static class Event {
197: // types of events
198: public static int ADDED = 0;
199: public static int REMOVED = 1;
200: public static int CHANGED = 2;
201:
202: public JFrame frame;
203: public String title;
204: public int eventType;
205: public String prevTitle;
206:
207: public Event(JFrame frame, String title, int eventType,
208: String prevTitle) {
209: this .frame = frame;
210: this .title = title;
211: this .eventType = eventType;
212: this .prevTitle = prevTitle;
213: }
214: }
215:
216: private void readObject(ObjectInputStream ois) throws IOException,
217: ClassNotFoundException {
218: ois.defaultReadObject();
219: createLogger();
220: titleToFrame = new Hashtable();
221: }
222:
223: }
|