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.configbuilder;
028:
029: import org.cougaar.tools.csmart.core.property.ModifiableComponent;
030: import org.cougaar.tools.csmart.experiment.DBExperiment;
031: import org.cougaar.tools.csmart.experiment.Experiment;
032: import org.cougaar.tools.csmart.recipe.RecipeComponent;
033: import org.cougaar.tools.csmart.society.SocietyComponent;
034: import org.cougaar.tools.csmart.ui.Browser;
035: import org.cougaar.tools.csmart.ui.util.NamedFrame;
036: import org.cougaar.tools.csmart.ui.viewer.CSMART;
037: import org.cougaar.tools.csmart.ui.viewer.GUIUtils;
038: import org.cougaar.util.log.Logger;
039:
040: import javax.swing.*;
041: import java.awt.*;
042: import java.awt.event.ActionEvent;
043: import java.awt.event.ActionListener;
044: import java.awt.event.WindowAdapter;
045: import java.awt.event.WindowEvent;
046: import java.net.URL;
047:
048: /**
049: * User interface that supports building a configurable component.
050: */
051: public class PropertyBuilder extends JFrame implements ActionListener {
052: private PropertyEditorPanel propertyEditor;
053: private ModifiableComponent configComponent;
054: private static final String FILE_MENU = "File";
055: private static final String EXIT_MENU_ITEM = "Exit";
056: private static final String SAVE_DB_MENU_ITEM = "Save To Database";
057:
058: private static final String HELP_MENU = "Help";
059:
060: protected static final String HELP_DOC = "help.html";
061: protected static final String ABOUT_CSMART_ITEM = "About CSMART";
062: protected static final String ABOUT_DOC = "/org/cougaar/tools/csmart/ui/help/about-csmart.html";
063: protected static final String HELP_MENU_ITEM = "Help";
064:
065: private String[] helpMenuItems = { HELP_MENU_ITEM,
066: ABOUT_CSMART_ITEM };
067:
068: private JMenuItem saveMenuItem;
069: private CSMART csmart;
070: private transient Logger log;
071: private Experiment experiment;
072: private ModifiableComponent originalComponent;
073: private boolean componentWasSaved = false;
074:
075: public PropertyBuilder(CSMART csmart, ModifiableComponent mc,
076: ModifiableComponent originalComponent, Experiment experiment) {
077: log = CSMART.createLogger(this .getClass().getName());
078: this .csmart = csmart;
079: this .originalComponent = originalComponent;
080: this .experiment = experiment;
081:
082: // initialize menus and gui panels
083: JMenuBar menuBar = new JMenuBar();
084: getRootPane().setJMenuBar(menuBar);
085: JMenu fileMenu = new JMenu(FILE_MENU);
086:
087: saveMenuItem = new JMenuItem(SAVE_DB_MENU_ITEM);
088: saveMenuItem.addActionListener(this );
089: fileMenu.add(saveMenuItem);
090: fileMenu.addSeparator();
091:
092: JMenuItem exitMenuItem = new JMenuItem(EXIT_MENU_ITEM);
093: exitMenuItem.addActionListener(this );
094: fileMenu.add(exitMenuItem);
095:
096: menuBar.add(fileMenu);
097:
098: JMenu helpMenu = new JMenu(HELP_MENU);
099: for (int i = 0; i < helpMenuItems.length; i++) {
100: JMenuItem mItem = new JMenuItem(helpMenuItems[i]);
101: mItem.addActionListener(this );
102: helpMenu.add(mItem);
103: }
104: menuBar.add(helpMenu);
105:
106: setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
107: addWindowListener(new WindowAdapter() {
108: public void windowClosing(WindowEvent e) {
109: if (!PropertyBuilder.this .getGlassPane().isVisible()) {
110: exit();
111: }
112: }
113: });
114:
115: // setConfigComponent(mc);
116: configComponent = mc;
117: propertyEditor = new PropertyEditorPanel(configComponent, true);
118: getContentPane().setLayout(new BorderLayout());
119: getContentPane().add(propertyEditor, BorderLayout.CENTER);
120:
121: setSize(600, 500);
122: setVisible(true);
123: }
124:
125: // if we modified a component in an experiment,
126: // update the experiment and update the workspace view
127: // and save the component in the database
128: // if we modified a component not in the database,
129: // save the component
130: private void exit() {
131: configComponent.setEditable(true);
132: if (originalComponent != null)
133: originalComponent.setEditable(true);
134: propertyEditor.stopEditing(); // accept any edit in progress
135: propertyEditor.exit();
136: // if component is modified, or was modified and was saved
137: // update it in the experiment
138: if (isModified() || componentWasSaved) {
139: if (experiment != null) {
140: if (configComponent instanceof SocietyComponent) {
141: SocietyComponent society = (SocietyComponent) configComponent;
142: experiment.removeSocietyComponent();
143: experiment.addSocietyComponent(society);
144: CSMART.getOrganizer().replaceComponent(experiment,
145: originalComponent, society);
146: } else if (configComponent instanceof RecipeComponent) {
147: RecipeComponent recipe = (RecipeComponent) configComponent;
148: experiment
149: .removeRecipeComponent((RecipeComponent) originalComponent);
150: experiment.addRecipeComponent(recipe);
151: CSMART.getOrganizer().replaceComponent(experiment,
152: originalComponent, recipe);
153: }
154: }
155: }
156: if (isModified())
157: saveToDatabase();
158: }
159:
160: private boolean isModified() {
161: return ((configComponent instanceof SocietyComponent && ((SocietyComponent) configComponent)
162: .isModified()) || (configComponent instanceof RecipeComponent && ((RecipeComponent) configComponent)
163: .isModified()));
164: }
165:
166: // user selected save from menu
167: private void save() {
168: if (!isModified()) {
169: String[] msg = { "No modifications were made.",
170: "Do you want to save anyway?" };
171: int answer = JOptionPane.showConfirmDialog(this , msg,
172: "No Modifications", JOptionPane.YES_NO_OPTION,
173: JOptionPane.WARNING_MESSAGE);
174: if (answer != JOptionPane.YES_OPTION)
175: return;
176: }
177: componentWasSaved = true;
178: saveToDatabase(); // force save
179: }
180:
181: public void actionPerformed(ActionEvent e) {
182: Object source = e.getSource();
183: String s = ((AbstractButton) source).getActionCommand();
184: if (s.equals(SAVE_DB_MENU_ITEM)) {
185: save();
186: } else if (s.equals(EXIT_MENU_ITEM)) {
187: exit();
188: // notify top-level viewer that user quit the builder
189: NamedFrame.getNamedFrame().removeFrame(this );
190: dispose();
191: } else if (s.equals(HELP_MENU_ITEM)) {
192: URL help = (URL) getClass().getResource(HELP_DOC);
193: if (help != null)
194: Browser.setPage(help);
195: } else if (s.equals(ABOUT_CSMART_ITEM)) {
196: URL about = (URL) getClass().getResource(ABOUT_DOC);
197: if (about != null)
198: Browser.setPage(about);
199: }
200: }
201:
202: /**
203: * Save society and recipes to database.
204: */
205:
206: private void saveToDatabase() {
207: if (configComponent instanceof SocietyComponent) {
208: final PropertyBuilder propertyBuilder = this ;
209: GUIUtils.timeConsumingTaskStart(csmart);
210: GUIUtils.timeConsumingTaskStart(this );
211: try {
212: new Thread("SaveSociety") {
213: public void run() {
214: boolean success = ((SocietyComponent) configComponent)
215: .saveToDatabase();
216: GUIUtils.timeConsumingTaskEnd(csmart);
217: GUIUtils.timeConsumingTaskEnd(propertyBuilder);
218: if (!success
219: && propertyBuilder.log.isWarnEnabled()) {
220: propertyBuilder.log
221: .warn("Failed to save society "
222: + configComponent
223: .getShortName());
224: } else if (propertyBuilder.log.isDebugEnabled()) {
225: propertyBuilder.log.debug("Saved society "
226: + configComponent.getShortName());
227: }
228: }
229: }.start();
230: } catch (RuntimeException re) {
231: if (log.isErrorEnabled()) {
232: log.error("Runtime exception saving society", re);
233: }
234: GUIUtils.timeConsumingTaskEnd(csmart);
235: GUIUtils.timeConsumingTaskEnd(propertyBuilder);
236: }
237: } else if (configComponent instanceof RecipeComponent) {
238: ((RecipeComponent) configComponent).saveToDatabase();
239: }
240: }
241:
242: // public void reinit(ModifiableComponent newModifiableComponent) {
243: // setConfigComponent(newModifiableComponent);
244: // propertyEditor.reinit(configComponent);
245: // }
246:
247: // private void setConfigComponent(ModifiableComponent newConfigComponent) {
248: // configComponent = newConfigComponent;
249: // }
250:
251: }
|