0001: /*
0002: * <copyright>
0003: *
0004: * Copyright 2000-2004 BBNT Solutions, LLC
0005: * under sponsorship of the Defense Advanced Research Projects
0006: * Agency (DARPA).
0007: *
0008: * You can redistribute this software and/or modify it under the
0009: * terms of the Cougaar Open Source License as published on the
0010: * Cougaar Open Source Website (www.cougaar.org).
0011: *
0012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023: *
0024: * </copyright>
0025: */
0026:
0027: package org.cougaar.tools.csmart.ui.console;
0028:
0029: import org.cougaar.tools.csmart.experiment.Experiment;
0030: import org.cougaar.tools.csmart.experiment.XMLExperiment;
0031: import org.cougaar.tools.csmart.experiment.NodeComponent;
0032: import org.cougaar.tools.csmart.ui.Browser;
0033: import org.cougaar.tools.csmart.ui.experiment.HostConfigurationBuilder;
0034: import org.cougaar.tools.csmart.ui.tree.ConsoleTreeObject;
0035: import org.cougaar.tools.csmart.ui.util.ChooserUtils;
0036: import org.cougaar.tools.csmart.ui.util.NamedFrame;
0037: import org.cougaar.tools.csmart.ui.util.Util;
0038: import org.cougaar.tools.csmart.ui.viewer.CSMART;
0039: import org.cougaar.util.log.Logger;
0040:
0041: import javax.swing.*;
0042: import javax.swing.border.LineBorder;
0043: import javax.swing.event.InternalFrameEvent;
0044: import javax.swing.event.InternalFrameListener;
0045: import javax.swing.event.TreeSelectionEvent;
0046: import javax.swing.event.TreeSelectionListener;
0047: import javax.swing.tree.DefaultMutableTreeNode;
0048: import javax.swing.tree.TreePath;
0049: import java.awt.*;
0050: import java.awt.event.*;
0051: import java.beans.PropertyVetoException;
0052: import java.net.URL;
0053: import java.text.DecimalFormat;
0054: import java.util.ArrayList;
0055: import java.util.Date;
0056: import java.util.Observable;
0057: import java.util.Observer;
0058:
0059: /**
0060: * org.cougaar.tools.csmart.ui.console
0061: *
0062: */
0063: public class CSMARTConsoleView extends JFrame implements Observer {
0064: private HostConfigurationBuilder hostConfiguration = null;
0065: private Component hostConfigComponent = null;
0066: private transient Logger log;
0067: private ConsoleDesktop desktop;
0068: private CSMARTConsoleModel model;
0069: public boolean dontClose = false; // flag for use when running under CSMART
0070:
0071: // gui controls
0072: private ButtonGroup statusButtons;
0073: private JToggleButton attachButton;
0074: private JMenuItem attachMenuItem; // same as attachButton
0075: private JMenuItem addGLSMenuItem; // call addGLSWindow
0076: private JMenuItem findHostMenuItem;
0077: private JMenuItem findNodeMenuItem;
0078: private JMenuItem findAgentMenuItem;
0079: private JToggleButton runButton;
0080: private JToggleButton stopButton;
0081: private JPanel buttonPanel; // contains status buttons
0082: private JPopupMenu nodeMenu; // pop-up menu on node status button
0083: private Legend legend;
0084:
0085: private boolean haveGLS = false;
0086:
0087: private JMenuItem deleteMenuItem;
0088: private JMenuItem displayMenuItem;
0089: private JMenuItem killAllMenuItem;
0090: private JMenuItem refreshMenuItem;
0091: private ConsoleNodeOutputFilter displayFilter = null;
0092: private javax.swing.Timer experimentTimer;
0093: private JLabel experimentTimeLabel;
0094: private static Dimension HGAP10 = new Dimension(10, 1);
0095: private static Dimension HGAP5 = new Dimension(5, 1);
0096: private static Dimension VGAP30 = new Dimension(1, 30);
0097: private long startExperimentTime;
0098: private DecimalFormat myNumberFormat;
0099:
0100: // top level menus and menu items
0101: private static final String FILE_MENU = "File";
0102: private static final String OPEN_MENU_ITEM = "Load Society XML";
0103: private static final String EXIT_MENU_ITEM = "Close";
0104: private static final String VIEW_MENU = "View";
0105: private static final String SET_VIEW_SIZE_MENU_ITEM = "Set View Size...";
0106: private static final String FILTER_MENU_ITEM = "Filter...";
0107: private static final String NOTIFY_MENU = "Notify";
0108: private static final String SET_NOTIFY_MENU_ITEM = "Set Notification...";
0109: private static final String VIEW_NOTIFY_MENU_ITEM = "View Notification";
0110: private static final String REMOVE_NOTIFY_MENU_ITEM = "Remove All Notifications";
0111: private static final String RESET_NOTIFY_MENU_ITEM = "Reset All Notifications";
0112: private static final String FIND_MENU = "Find";
0113: private static final String FIND_HOST_MENU_ITEM = "Find Host...";
0114: private static final String FIND_NODE_MENU_ITEM = "Find Node...";
0115: private static final String FIND_AGENT_MENU_ITEM = "Find Agent...";
0116: private static final String APP_SERVER_MENU = "Application Server";
0117: private static final String VIEW_APP_SERVER_ITEM = "View";
0118: private static final String ADD_APP_SERVER_ITEM = "Add...";
0119: private static final String DELETE_APP_SERVER_ITEM = "Delete...";
0120: private static final String ATTACH_AS_ITEM = "Attach...";
0121: private static final String KILL_ALL_PROCS_ITEM = "Kill Any Nodes";
0122: private static final String REFRESH_APP_SERVER_ITEM = "Refresh";
0123: private static final String SET_POLL_INTERVAL_ITEM = "Set Poll Interval";
0124: private static final String ADD_GLS_ITEM = "Add GLS Client";
0125: private static final String HELP_MENU = "Help";
0126: private static final String ABOUT_CONSOLE_ITEM = "About Experiment Controller";
0127: private static final String ABOUT_CSMART_ITEM = "About CSMART";
0128: private static final String LEGEND_MENU_ITEM = "Node Status Legend";
0129: protected static final String ABOUT_DOC = "/org/cougaar/tools/csmart/ui/help/about-csmart.html";
0130: private static final String HELP_DOC = "help.html";
0131:
0132: // for pop-up menu on node status buttons
0133: private static final String ABOUT_ACTION = "Info";
0134: private static final String RESET_ACTION = "Reset Notification";
0135:
0136: private static final int MSECS_PER_SECOND = 1000;
0137: private static final int MSECS_PER_MINUTE = 60000;
0138: private static final int MSECS_PER_HOUR = 3600000;
0139:
0140: /**
0141: * Create and show console GUI.
0142: */
0143: public CSMARTConsoleView() {
0144: this (null, null);
0145: }
0146:
0147: public CSMARTConsoleView(CSMART csmart) {
0148: this (csmart, null);
0149: }
0150:
0151: /**
0152: * Create and show console GUI.
0153: * @param csmart the CSMART viewer
0154: */
0155: public CSMARTConsoleView(CSMART csmart, Experiment experiment) {
0156: this .model = new CSMARTConsoleModel(experiment, csmart);
0157: createLogger();
0158: initGUI();
0159: }
0160:
0161: private void initGUI() {
0162: String description = "Experiment Controller";
0163:
0164: desktop = new ConsoleDesktop();
0165:
0166: setTitle(description);
0167: getRootPane().setJMenuBar(createMenu());
0168: getContentPane().add(createNodePanel(description));
0169:
0170: model.addObserver(this );
0171: initButtons();
0172: updateASControls();
0173:
0174: experimentTimer = new javax.swing.Timer(1000,
0175: new ActionListener() {
0176: public void actionPerformed(ActionEvent e) {
0177: experimentTimeLabel
0178: .setText(getElapsedTimeLabel(
0179: "Experiment: ",
0180: startExperimentTime));
0181: }
0182: });
0183:
0184: // do nothing on the close; the windowClosing method handles the close
0185: setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
0186: addWindowListener(new WindowAdapter() {
0187: public void windowClosing(WindowEvent e) {
0188: exitMenuItem_actionPerformed(e);
0189: }
0190: });
0191:
0192: pack();
0193: setSize(700, 600);
0194: setVisible(true);
0195: } // end initGUI
0196:
0197: private JPanel createNodePanel(String description) {
0198: // create panel which contains description panel, status button panel, and tabbed panes
0199: JPanel panel = new JPanel(new GridBagLayout());
0200:
0201: // descriptionPanel contains society name, control buttons
0202: JPanel descriptionPanel = createHorizontalPanel(true);
0203: descriptionPanel.add(Box.createRigidArea(VGAP30));
0204: descriptionPanel.add(Box.createRigidArea(HGAP10));
0205: descriptionPanel.add(new JLabel(description));
0206: descriptionPanel.add(Box.createRigidArea(HGAP5));
0207:
0208: attachButton = new JToggleButton("Attach");
0209: attachButton.setToolTipText("Attach to running nodes");
0210: attachButton.addActionListener(new ActionListener() {
0211: public void actionPerformed(ActionEvent e) {
0212: attachStateChanged();
0213: }
0214: });
0215: attachButton.setFocusPainted(false);
0216: descriptionPanel.add(attachButton);
0217: descriptionPanel.add(Box.createRigidArea(HGAP5));
0218: runButton = new JToggleButton("Run");
0219: runButton.setToolTipText("Start running experiment");
0220: runButton.addActionListener(new ActionListener() {
0221: public void actionPerformed(ActionEvent e) {
0222: model.setRunning(true);
0223: }
0224: });
0225: runButton.setFocusPainted(false);
0226: descriptionPanel.add(runButton);
0227: descriptionPanel.add(Box.createRigidArea(HGAP5));
0228:
0229: stopButton = new JToggleButton("Stop");
0230: stopButton.setToolTipText("Halt experiment at end of current");
0231: stopButton.addActionListener(new ActionListener() {
0232: public void actionPerformed(ActionEvent e) {
0233: model.setRunning(false);
0234: }
0235: });
0236: stopButton.setFocusPainted(false);
0237: descriptionPanel.add(stopButton);
0238: descriptionPanel.add(Box.createRigidArea(HGAP5));
0239:
0240: // create progress panel for time labels
0241: // these are referenced elsewhere, so are created even if not displayed
0242: JPanel runProgressPanel = createHorizontalPanel(false);
0243: myNumberFormat = new DecimalFormat("00");
0244: experimentTimeLabel = new JLabel("Experiment: 00:00:00");
0245: JPanel progressPanel = new JPanel(new GridBagLayout());
0246: runProgressPanel.add(experimentTimeLabel);
0247: progressPanel.add(runProgressPanel, new GridBagConstraints(0,
0248: 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
0249: GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
0250: 0, 0));
0251:
0252: descriptionPanel.add(Box.createRigidArea(HGAP10));
0253: descriptionPanel.add(progressPanel);
0254:
0255: descriptionPanel.add(Box.createRigidArea(HGAP10));
0256: // add description panel to top panel
0257: panel.add(descriptionPanel, new GridBagConstraints(0, 0, 1, 1,
0258: 1.0, 0.0, GridBagConstraints.WEST,
0259: GridBagConstraints.HORIZONTAL,
0260: new Insets(0, 10, 2, 10), 0, 0));
0261:
0262: // create status button panel, initially with no buttons
0263: buttonPanel = createHorizontalPanel(true);
0264: buttonPanel.add(Box.createRigidArea(HGAP10));
0265: buttonPanel.add(new JLabel("Node Status"));
0266: buttonPanel.add(Box.createRigidArea(HGAP10));
0267: buttonPanel.add(Box.createRigidArea(VGAP30));
0268: JScrollPane jsp = new JScrollPane(buttonPanel);
0269: // ensure the layout leaves space for the scrollbar
0270: jsp.setMinimumSize(new Dimension(100, 50));
0271: panel.add(jsp, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0,
0272: GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
0273: new Insets(0, 10, 0, 10), 0, 0));
0274:
0275: statusButtons = new ButtonGroup();
0276: nodeMenu = new JPopupMenu();
0277: Action aboutAction = new AbstractAction(ABOUT_ACTION) {
0278: public void actionPerformed(ActionEvent e) {
0279: displayAboutNode();
0280: }
0281: };
0282: nodeMenu.add(aboutAction);
0283: Action resetAction = new AbstractAction(RESET_ACTION) {
0284: public void actionPerformed(ActionEvent e) {
0285: resetNodeStatus();
0286: }
0287: };
0288: Action legendAction = new AbstractAction(LEGEND_MENU_ITEM) {
0289: public void actionPerformed(ActionEvent e) {
0290: legend.setVisible(true);
0291: }
0292: };
0293: nodeMenu.add(resetAction);
0294: nodeMenu.addSeparator();
0295: nodeMenu.add(legendAction);
0296:
0297: // if have experiment,
0298: // create internal frame for host/node/agent configuration
0299: createHostConfiguration();
0300: panel.add(desktop, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0,
0301: GridBagConstraints.WEST, GridBagConstraints.BOTH,
0302: new Insets(0, 0, 0, 0), 0, 0));
0303: return panel;
0304: }
0305:
0306: private void createHostConfiguration() {
0307: Experiment experiment = model.getExperiment();
0308: if (experiment != null) {
0309: if (hostConfigComponent != null) {
0310: desktop.remove(hostConfigComponent);
0311: }
0312: hostConfiguration = new HostConfigurationBuilder(
0313: experiment, null);
0314: hostConfiguration.update(); // display configuration
0315: hostConfiguration
0316: .addHostTreeSelectionListener(myTreeListener);
0317: JInternalFrame jif = new JInternalFrame("Configuration",
0318: true, false, true, true);
0319: jif.getContentPane().add(hostConfiguration);
0320: jif.setSize(660, 400);
0321: jif.setLocation(0, 0);
0322: jif.setVisible(true);
0323: hostConfigComponent = jif;
0324: desktop.add(jif, JLayeredPane.DEFAULT_LAYER);
0325: }
0326: }
0327:
0328: private JMenuBar createMenu() {
0329: // top level menus
0330: JMenu fileMenu = new JMenu(FILE_MENU);
0331: fileMenu.setToolTipText("Console Operations");
0332:
0333: JMenuItem openMenuItem = new JMenuItem(OPEN_MENU_ITEM);
0334: openMenuItem.setToolTipText("Load in an XML Society to run.");
0335: openMenuItem.addActionListener(new ActionListener() {
0336: public void actionPerformed(ActionEvent e) {
0337: openMenuItem_actionPerformed(e);
0338: }
0339: });
0340: fileMenu.add(openMenuItem);
0341:
0342: JMenuItem exitMenuItem = new JMenuItem(EXIT_MENU_ITEM);
0343: exitMenuItem.setToolTipText("Exit this tool.");
0344: exitMenuItem.addActionListener(new ActionListener() {
0345: public void actionPerformed(ActionEvent e) {
0346: exitMenuItem_actionPerformed(e);
0347: }
0348: });
0349: fileMenu.add(exitMenuItem);
0350:
0351: JMenu viewMenu = new JMenu(VIEW_MENU);
0352: JMenuItem viewSizeMenuItem = new JMenuItem(
0353: SET_VIEW_SIZE_MENU_ITEM);
0354: viewSizeMenuItem.addActionListener(new ActionListener() {
0355: public void actionPerformed(ActionEvent e) {
0356: viewSizeMenuItem_actionPerformed();
0357: }
0358: });
0359: viewMenu.add(viewSizeMenuItem);
0360: JMenuItem filterMenuItem = new JMenuItem(FILTER_MENU_ITEM);
0361: filterMenuItem.addActionListener(new ActionListener() {
0362: public void actionPerformed(ActionEvent e) {
0363: filterMenuItem_actionPerformed();
0364: }
0365: });
0366: viewMenu.add(filterMenuItem);
0367:
0368: JMenu findMenu = new JMenu(FIND_MENU);
0369: findHostMenuItem = new JMenuItem(FIND_HOST_MENU_ITEM);
0370: findHostMenuItem.addActionListener(new ActionListener() {
0371: public void actionPerformed(ActionEvent e) {
0372: hostConfiguration.findHost();
0373: }
0374: });
0375: findMenu.add(findHostMenuItem);
0376: findNodeMenuItem = new JMenuItem(FIND_NODE_MENU_ITEM);
0377: findNodeMenuItem.addActionListener(new ActionListener() {
0378: public void actionPerformed(ActionEvent e) {
0379: hostConfiguration.findNode();
0380: }
0381: });
0382: findMenu.add(findNodeMenuItem);
0383: findAgentMenuItem = new JMenuItem(FIND_AGENT_MENU_ITEM);
0384: findAgentMenuItem.addActionListener(new ActionListener() {
0385: public void actionPerformed(ActionEvent e) {
0386: hostConfiguration.findAgent();
0387: }
0388: });
0389: findMenu.add(findAgentMenuItem);
0390: enableFindOptions();
0391:
0392: JMenu notifyMenu = new JMenu(NOTIFY_MENU);
0393: JMenuItem setNotifyMenuItem = new JMenuItem(
0394: SET_NOTIFY_MENU_ITEM);
0395: setNotifyMenuItem.addActionListener(new ActionListener() {
0396: public void actionPerformed(ActionEvent e) {
0397: setNotifyMenuItem_actionPerformed();
0398: }
0399: });
0400: notifyMenu.add(setNotifyMenuItem);
0401: JMenuItem viewNotifyMenuItem = new JMenuItem(
0402: VIEW_NOTIFY_MENU_ITEM);
0403: viewNotifyMenuItem.addActionListener(new ActionListener() {
0404: public void actionPerformed(ActionEvent e) {
0405: viewNotifyMenuItem_actionPerformed();
0406: }
0407: });
0408: notifyMenu.add(viewNotifyMenuItem);
0409: JMenuItem removeNotifyMenuItem = new JMenuItem(
0410: REMOVE_NOTIFY_MENU_ITEM);
0411: removeNotifyMenuItem.addActionListener(new ActionListener() {
0412: public void actionPerformed(ActionEvent e) {
0413: removeNotifyMenuItem_actionPerformed();
0414: }
0415: });
0416: notifyMenu.add(removeNotifyMenuItem);
0417: notifyMenu.addSeparator();
0418: JMenuItem resetNotifyMenuItem = new JMenuItem(
0419: RESET_NOTIFY_MENU_ITEM);
0420: resetNotifyMenuItem.addActionListener(new ActionListener() {
0421: public void actionPerformed(ActionEvent e) {
0422: resetNotifyMenuItem_actionPerformed();
0423: }
0424: });
0425: notifyMenu.add(resetNotifyMenuItem);
0426:
0427: JMenu appServerMenu = new JMenu(APP_SERVER_MENU);
0428: appServerMenu
0429: .setToolTipText("Display, add, and delete list of Application Servers.");
0430:
0431: displayMenuItem = new JMenuItem(VIEW_APP_SERVER_ITEM);
0432: displayMenuItem.addActionListener(new ActionListener() {
0433: public void actionPerformed(ActionEvent e) {
0434: displayAppServers();
0435: }
0436: });
0437: displayMenuItem
0438: .setToolTipText("Display list of Application Servers.");
0439: appServerMenu.add(displayMenuItem);
0440:
0441: JMenuItem addMenuItem = new JMenuItem(ADD_APP_SERVER_ITEM);
0442: addMenuItem.addActionListener(new ActionListener() {
0443: public void actionPerformed(ActionEvent e) {
0444: addAppServer();
0445: }
0446: });
0447: addMenuItem.setToolTipText("Add an Application Server.");
0448: appServerMenu.add(addMenuItem);
0449:
0450: deleteMenuItem = new JMenuItem(DELETE_APP_SERVER_ITEM);
0451: deleteMenuItem.addActionListener(new ActionListener() {
0452: public void actionPerformed(ActionEvent e) {
0453: deleteAppServers();
0454: }
0455: });
0456: deleteMenuItem.setToolTipText("Ignore Application Servers.");
0457: appServerMenu.add(deleteMenuItem);
0458:
0459: attachMenuItem = new JMenuItem(ATTACH_AS_ITEM);
0460: attachMenuItem.addActionListener(new ActionListener() {
0461: public void actionPerformed(ActionEvent e) {
0462: attachStateChanged();
0463: }
0464: });
0465: attachMenuItem
0466: .setToolTipText("Attach to any new Running Nodes.");
0467: appServerMenu.add(attachMenuItem);
0468:
0469: killAllMenuItem = new JMenuItem(KILL_ALL_PROCS_ITEM);
0470: killAllMenuItem.addActionListener(new ActionListener() {
0471: public void actionPerformed(ActionEvent e) {
0472: killAll_actionPerformed();
0473: }
0474: });
0475: killAllMenuItem
0476: .setToolTipText("Kill Any Nodes on known App Servers.");
0477: appServerMenu.add(killAllMenuItem);
0478:
0479: refreshMenuItem = new JMenuItem(REFRESH_APP_SERVER_ITEM);
0480: refreshMenuItem.addActionListener(new ActionListener() {
0481: public void actionPerformed(ActionEvent e) {
0482: refreshAppServers();
0483: }
0484: });
0485: refreshMenuItem
0486: .setToolTipText("Refresh list of Application Servers");
0487: appServerMenu.add(refreshMenuItem);
0488:
0489: JMenuItem pollIntervalMenuItem = new JMenuItem(
0490: SET_POLL_INTERVAL_ITEM);
0491: pollIntervalMenuItem.addActionListener(new ActionListener() {
0492: public void actionPerformed(ActionEvent e) {
0493: // Put up a dialog with the current interval.
0494: // If the user changes the interval, cancel the current timer
0495: // and create a new one
0496: int interval = getNewASPollInterval();
0497: if (interval != 0)
0498: model.resetASPoller(interval);
0499: }
0500: });
0501: pollIntervalMenuItem
0502: .setToolTipText("Change Delay Between Checking for New Application Servers");
0503: appServerMenu.add(pollIntervalMenuItem);
0504:
0505: // Menu item for popping up a new GLS Client
0506: addGLSMenuItem = new JMenuItem(ADD_GLS_ITEM);
0507: addGLSMenuItem.addActionListener(new ActionListener() {
0508: public void actionPerformed(ActionEvent e) {
0509: model.addGLSWindow();
0510: }
0511: });
0512: addGLSMenuItem
0513: .setToolTipText("Add new GLS Client for sending GLS Init");
0514: appServerMenu.add(addGLSMenuItem);
0515:
0516: JMenu helpMenu = new JMenu(HELP_MENU);
0517: JMenuItem helpMenuItem = new JMenuItem(ABOUT_CONSOLE_ITEM);
0518: helpMenuItem.addActionListener(new ActionListener() {
0519: public void actionPerformed(ActionEvent e) {
0520: URL help = this .getClass().getResource(HELP_DOC);
0521: if (help != null)
0522: Browser.setPage(help);
0523: }
0524: });
0525: helpMenu.add(helpMenuItem);
0526:
0527: legend = new Legend();
0528: JMenuItem legendMenuItem = new JMenuItem(LEGEND_MENU_ITEM);
0529: legendMenuItem.addActionListener(new ActionListener() {
0530: public void actionPerformed(ActionEvent e) {
0531: legend.setVisible(true);
0532: }
0533: });
0534: helpMenu.add(legendMenuItem);
0535:
0536: JMenuItem aboutMenuItem = new JMenuItem(ABOUT_CSMART_ITEM);
0537: aboutMenuItem.addActionListener(new ActionListener() {
0538: public void actionPerformed(ActionEvent e) {
0539: URL about = this .getClass().getResource(ABOUT_DOC);
0540: if (about != null)
0541: Browser.setPage(about);
0542: }
0543: });
0544: helpMenu.add(aboutMenuItem);
0545:
0546: JMenuBar menuBar = new JMenuBar();
0547: menuBar.add(fileMenu);
0548: menuBar.add(viewMenu);
0549: menuBar.add(findMenu);
0550: menuBar.add(notifyMenu);
0551: menuBar.add(appServerMenu);
0552: menuBar.add(helpMenu);
0553: return menuBar;
0554: }
0555:
0556: private void enableFindOptions() {
0557: if (model.getExperiment() == null) {
0558: findHostMenuItem.setEnabled(false);
0559: findNodeMenuItem.setEnabled(false);
0560: findAgentMenuItem.setEnabled(false);
0561: } else {
0562: findHostMenuItem.setEnabled(true);
0563: findNodeMenuItem.setEnabled(true);
0564: findAgentMenuItem.setEnabled(true);
0565: }
0566: }
0567:
0568: private void openMenuItem_actionPerformed(ActionEvent e) {
0569: final SwingWorker worker = new SwingWorker() {
0570: public Object construct() {
0571: return new CreateExperiment();
0572: }
0573: // public void finished() {
0574: // model.setExperiment(exp);
0575: // }
0576: };
0577: worker.start();
0578:
0579: // XMLExperiment exp = new XMLExperiment(chooser.getSelectedFile(), this);
0580: // exp.doParse();
0581: // model.setXMLFile(chooser.getSelectedFile());
0582: // model.setExperiment(exp);
0583: //
0584: // model.setXMLFile(file);
0585:
0586: // Document doc = ComponentDataXML.createXMLDocument(exp.getExperiment());
0587: // try {
0588: // XMLUtils.writeXMLFile(new File("/tmp/"), doc, "dump.xml");
0589: // } catch (IOException e1) {
0590: // e1.printStackTrace();
0591: // }
0592: }
0593:
0594: /**
0595: * Get new App Server polling interval from user.
0596: * A value of 0 means the user entered an invalid value or cancelled.
0597: */
0598: private int getNewASPollInterval() {
0599: if (log.isDebugEnabled()) {
0600: log.debug("Getting new ASPoll Interval");
0601: }
0602: JPanel pollPanel = new JPanel(new GridBagLayout());
0603: int x = 0;
0604: int y = 0;
0605: pollPanel
0606: .add(
0607: new JLabel(
0608: "Interval in milliseconds between polls for live AppServers (0 to not poll):"),
0609: new GridBagConstraints(x++, y, 1, 1, 0.0, 0.0,
0610: GridBagConstraints.WEST,
0611: GridBagConstraints.NONE, new Insets(10,
0612: 0, 5, 5), 0, 0));
0613: JTextField pollField = new JTextField(7);
0614: pollField.setText(String.valueOf(model.getASPollInterval()));
0615: pollPanel.add(pollField, new GridBagConstraints(x, y++, 1, 1,
0616: 1.0, 0.0, GridBagConstraints.WEST,
0617: GridBagConstraints.HORIZONTAL, new Insets(10, 0, 5, 0),
0618: 0, 0));
0619: int result = JOptionPane.showConfirmDialog(null, pollPanel,
0620: "Polling Interval", JOptionPane.OK_CANCEL_OPTION);
0621: if (result != JOptionPane.OK_OPTION)
0622: return 0;
0623: String s = pollField.getText().trim();
0624: if (s == null || s.length() == 0) {
0625: return 0;
0626: } else {
0627: int res = 0;
0628: try {
0629: res = Integer.parseInt(s);
0630: } catch (NumberFormatException e) {
0631: }
0632: if (res < 0)
0633: return 0;
0634: return res;
0635: }
0636: }
0637:
0638: /**
0639: * If there are AppServers,
0640: * then enable the delete and refresh app server controls.
0641: * If there are AppServers with unattached nodes,
0642: * then enable the attach controls.
0643: * If there are AppServers with attached nodes,
0644: * then enable the "kill" menu.
0645: */
0646:
0647: private void updateASControls() {
0648: if (model.getAppServers().size() == 0) {
0649: displayMenuItem.setEnabled(false);
0650: deleteMenuItem.setEnabled(false);
0651: refreshMenuItem.setEnabled(false);
0652: } else {
0653: displayMenuItem.setEnabled(true);
0654: deleteMenuItem.setEnabled(true);
0655: refreshMenuItem.setEnabled(true);
0656: }
0657: if (model.getUnattachedNodes().size() == 0) {
0658: if (!attachButton.isSelected())
0659: attachButton.setEnabled(false);
0660: attachMenuItem.setEnabled(false);
0661: } else {
0662: attachButton.setEnabled(true);
0663: attachMenuItem.setEnabled(true);
0664: }
0665: if (model.getAttachedNodes().size() == 0) {
0666: killAllMenuItem.setEnabled(false);
0667: } else {
0668: killAllMenuItem.setEnabled(true);
0669: }
0670: }
0671:
0672: private void initButtons() {
0673: runButton.setEnabled(model.isRunnable());
0674: stopButton.setEnabled(false);
0675: }
0676:
0677: /**
0678: * Create a panel whose components are layed out horizontally.
0679: */
0680: private JPanel createHorizontalPanel(boolean makeBorder) {
0681: JPanel p = new JPanel();
0682: p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
0683: p.setAlignmentY(TOP_ALIGNMENT);
0684: p.setAlignmentX(LEFT_ALIGNMENT);
0685: if (makeBorder)
0686: p.setBorder(LineBorder.createGrayLineBorder());
0687: return p;
0688: }
0689:
0690: private void createLogger() {
0691: log = CSMART.createLogger(this .getClass().getName());
0692: }
0693:
0694: // Listeners start here.
0695:
0696: /**
0697: * Display information about the selected node.
0698: */
0699: private void displayAboutNode() {
0700: String name = model.getSelectedNodeName();
0701: if (name != null) {
0702: NodeView nodeView = desktop.getNodeFrame(name);
0703: if (nodeView != null)
0704: nodeView.displayAbout();
0705: }
0706: }
0707:
0708: /**
0709: * Reset the notify string and status button for the selected node.
0710: */
0711: private void resetNodeStatus() {
0712: String name = model.getSelectedNodeName();
0713: if (name != null) {
0714: NodeView nodeView = desktop.getNodeFrame(name);
0715: if (nodeView != null)
0716: nodeView.resetNotify();
0717: }
0718: }
0719:
0720: /**
0721: * Set the view size for all the node views.
0722: */
0723: private void viewSizeMenuItem_actionPerformed() {
0724: int newViewSize = displayViewSizeDialog(model.getViewSize());
0725: if (newViewSize == -2)
0726: return; // ignore, user cancelled
0727: model.setViewSize(newViewSize);
0728: }
0729:
0730: /**
0731: * Set the filter for all the node views.
0732: */
0733: private void filterMenuItem_actionPerformed() {
0734: if (displayFilter == null)
0735: displayFilter = new ConsoleNodeOutputFilter(null, true);
0736: else {
0737: displayFilter = new ConsoleNodeOutputFilter(displayFilter
0738: .getValues(), displayFilter.isAllSelected());
0739: }
0740: // this must set the filter values for all the nodes
0741: model.setFilter(displayFilter);
0742: }
0743:
0744: private void setNotifyMenuItem_actionPerformed() {
0745: JPanel notifyPanel = new JPanel(new GridBagLayout());
0746: int x = 0;
0747: int y = 0;
0748: notifyPanel.add(new JLabel("Search string:"),
0749: new GridBagConstraints(x++, y, 1, 1, 0.0, 0.0,
0750: GridBagConstraints.WEST,
0751: GridBagConstraints.NONE,
0752: new Insets(10, 0, 5, 5), 0, 0));
0753: JTextField notifyField = new JTextField(20);
0754: notifyField.setText(model.getNotifyCondition());
0755: notifyPanel.add(notifyField, new GridBagConstraints(x, y++, 1,
0756: 1, 1.0, 0.0, GridBagConstraints.WEST,
0757: GridBagConstraints.HORIZONTAL, new Insets(10, 0, 5, 0),
0758: 0, 0));
0759: x = 0;
0760: JCheckBox stdErrorCB = new JCheckBox(
0761: "Notify on Standard Error", model
0762: .getNotifyOnStandardError());
0763: notifyPanel
0764: .add(stdErrorCB, new GridBagConstraints(x++, y, 1, 1,
0765: 0.0, 0.0, GridBagConstraints.WEST,
0766: GridBagConstraints.NONE,
0767: new Insets(10, 0, 5, 5), 0, 0));
0768: int result = JOptionPane.showConfirmDialog(this , notifyPanel,
0769: "Notification", JOptionPane.OK_CANCEL_OPTION);
0770: if (result != JOptionPane.OK_OPTION)
0771: return;
0772: String s = notifyField.getText();
0773: if (s.length() == 0)
0774: s = null;
0775: model.setNotification(s, stdErrorCB.isSelected());
0776: }
0777:
0778: private void viewNotifyMenuItem_actionPerformed() {
0779: String notifyCondition = model.getNotifyCondition();
0780: if (notifyCondition == null)
0781: JOptionPane.showMessageDialog(this , "No notification set.",
0782: "Notification", JOptionPane.PLAIN_MESSAGE);
0783: else
0784: JOptionPane.showMessageDialog(this ,
0785: "Notify if any node writes: " + notifyCondition,
0786: "Notification", JOptionPane.PLAIN_MESSAGE);
0787: }
0788:
0789: /**
0790: * Remove all notifications.
0791: */
0792: private void removeNotifyMenuItem_actionPerformed() {
0793: model.setNotification(null, false);
0794: }
0795:
0796: /**
0797: * Reset status for all nodes. Resets the "notify" position
0798: * in the text pane and resets the error flag of the node status button.
0799: */
0800: private void resetNotifyMenuItem_actionPerformed() {
0801: model.resetNotifyStatus();
0802: }
0803:
0804: private void killAll_actionPerformed() {
0805: int result = JOptionPane
0806: .showConfirmDialog(
0807: this ,
0808: "Really kill all running Nodes on all known AppServers?",
0809: "Kill All Nodes", JOptionPane.OK_CANCEL_OPTION);
0810: if (result != JOptionPane.OK_OPTION)
0811: return;
0812:
0813: if (log.isDebugEnabled())
0814: log.debug("Killing all Nodes!");
0815:
0816: model.killAllProcesses();
0817: }
0818:
0819: /**
0820: * Invoked from File-Exit menu command or from the window
0821: * close icon.
0822: * Displays a dialog that gives the user the option to
0823: * detach from the nodes, kill the nodes, or cancel the exit.
0824: * If the user cancels the exit, set the dontClose flag,
0825: * which the main CSMART viewer uses in its windowClosing
0826: * method to determine whether or not to ignore the close.
0827: */
0828: private void exitMenuItem_actionPerformed(AWTEvent e) {
0829: dontClose = false;
0830: if (log.isDebugEnabled()) {
0831: log.debug("In exitMenuItem_actionPerformed");
0832: }
0833: if (model.haveAttached()) {
0834: ExitConsole ec = new ExitConsole();
0835: if (ec.reallyExit()) {
0836: if (ec.getResult().equals(ec.SOCIETY_DETACH)) {
0837: model.detachFromSociety();
0838: } else if (ec.getResult().equals(ec.KILL_NODES)) {
0839: model.stopNodes();
0840: }
0841: } else {
0842: dontClose = true; // tells the main CSMART viewer to ignore close
0843: return; // user cancelled the close, do nothing
0844: }
0845: }
0846:
0847: // when Console is a part of CSMART
0848: // this removes the window from the list that CSMART maintains
0849: if (!model.isCSMARTNull()) {
0850: if (e instanceof ActionEvent) {
0851: NamedFrame.getNamedFrame().removeFrame(this );
0852: }
0853: dispose();
0854: } else {
0855: if (log.isDebugEnabled()) {
0856: log.debug("Not doing a removeFrame: event was " + e);
0857: }
0858: dispose(); // dispose of this instance (should clean up all instances in console)
0859: System.exit(0);
0860: }
0861: }
0862:
0863: /**
0864: * Get a list of unattached nodes and display these to the user.
0865: * Message the model to attach to each node.
0866: */
0867: private void attachStateChanged() {
0868: ArrayList nodes = model.getUnattachedNodes();
0869: Object[] selected = Util.getObjectsFromList(null, nodes,
0870: "Attach to Nodes", "Select Nodes:");
0871: if (selected != null) {
0872: for (int i = 0; i < selected.length; i++)
0873: model.attachToNode((String) selected[i]);
0874: }
0875: }
0876:
0877: // End Listeners
0878:
0879: public static void main(String[] args) {
0880: CSMARTConsoleView ccv = new CSMARTConsoleView(null);
0881: }
0882:
0883: /**
0884: * This is an observer on the CSMARTConsoleModel;
0885: * it handles the following events:
0886: * If an AppServer was added or deleted or a node added,
0887: * it updates the Attach button and the AppServer menu.
0888: * If a new NodeView was created,
0889: * it adds it and its status button to the display.
0890: * If a NodeView is removed, it updates the display.
0891: * If a GLS window is added, it updates the display.
0892: * If the experiment timer should be started or stopped, it does that.
0893: * If the state of a node changed,
0894: * it updates the Run and Stop buttons.
0895: */
0896: public void update(Observable o, Object arg) {
0897: if (arg.equals(CSMARTConsoleModel.APP_SERVER_ADDED)
0898: || arg.equals(CSMARTConsoleModel.APP_SERVER_DELETED)
0899: || arg.equals(CSMARTConsoleModel.NODE_ADDED)) {
0900: updateASControls();
0901: } else if (arg instanceof NodeView) {
0902: desktop.addNodeFrame((NodeView) arg, ((NodeView) arg)
0903: .getNodeName());
0904: ((NodeView) arg)
0905: .addInternalFrameListener(new NodeFrameListener());
0906: NodeModel nm = model.getNodeModel(((NodeView) arg)
0907: .getNodeName());
0908: statusButtons.add(nm.getStatusButton());
0909: nm.getStatusButton().addMouseListener(myMouseListener);
0910: buttonPanel.add(nm.getStatusButton());
0911: } else if (arg instanceof NodeChange) {
0912: NodeChange nc = (NodeChange) arg;
0913: if (nc.action.equals(CSMARTConsoleModel.NODE_REMOVED))
0914: removeNodeView(nc.nodeName);
0915: } else if (arg.equals(CSMARTConsoleModel.ADD_GLS_WINDOW)) {
0916: if (!haveGLS) {
0917: JInternalFrame gls = GLSClientView
0918: .getGLSClientView(model.getGLSContactInfo());
0919: desktop.add(gls, JLayeredPane.DEFAULT_LAYER);
0920: try {
0921: gls.setIcon(true);
0922: } catch (PropertyVetoException e) {
0923: // Ignore exception, the window will not be set as icon.
0924: }
0925:
0926: haveGLS = true;
0927: }
0928: } else if (arg
0929: .equals(CSMARTConsoleModel.START_EXPERIMENT_TIMER)) {
0930: startExperimentTime = new Date().getTime();
0931: experimentTimer.start();
0932: } else if (arg.equals(CSMARTConsoleModel.STOP_EXPERIMENT_TIMER)) {
0933: experimentTimer.stop();
0934: } else if (arg instanceof String
0935: && ((String) arg).startsWith("NODE_STATE")) {
0936: updateButtons();
0937: } else if (arg.equals(CSMARTConsoleModel.NEW_EXPERIMENT)) {
0938: initButtons();
0939: createHostConfiguration();
0940: updateASControls();
0941: enableFindOptions();
0942: }
0943: }
0944:
0945: /**
0946: * If any node is in the running state, enable Stop.
0947: * If any node is in the initted or stopped states, enable Run.
0948: * If any node is in the starting or running states, select Run.
0949: * If any node is in the stopping or stopped states, select Stop.
0950: * Selected buttons are also enabled.
0951: */
0952: // private void updateButtons() {
0953: // boolean runSelected = false;
0954: // boolean stopSelected = false;
0955: // ArrayList nodeModels = model.getNodeModels();
0956: // for (int i = 0; i < nodeModels.size(); i++) {
0957: // NodeModel nodeModel = (NodeModel)nodeModels.get(i);
0958: // String state = nodeModel.getState();
0959: // if (state.equals(NodeModel.STATE_STARTING) ||
0960: // state.equals(NodeModel.STATE_RUNNING))
0961: // runSelected = true;
0962: // else if (state.equals(NodeModel.STATE_STOPPING) ||
0963: // state.equals(NodeModel.STATE_STOPPED))
0964: // stopSelected = true;
0965: // }
0966: // runButton.setSelected(runSelected);
0967: // stopButton.setSelected(stopSelected);
0968: // boolean enableRun = false;
0969: // boolean enableStop = false;
0970: // for (int i = 0; i < nodeModels.size(); i++) {
0971: // NodeModel nodeModel = (NodeModel)nodeModels.get(i);
0972: // String state = nodeModel.getState();
0973: // if (state.equals(NodeModel.STATE_RUNNING)) {
0974: // enableStop = true;
0975: // } else if (state.equals(NodeModel.STATE_INITTED) ||
0976: // state.equals(NodeModel.STATE_STOPPED)) {
0977: // enableRun = true;
0978: // }
0979: // }
0980: // runButton.setEnabled(enableRun || runSelected);
0981: // stopButton.setEnabled(enableStop || stopSelected);
0982: // }
0983: /**
0984: * Called when any model changes state.
0985: * AttachButton:
0986: * Enable when there are 1 or more unattached nodes (handled in updateASControls)
0987: * Disable wen there are 0 unattached nodes and its not selected
0988: * Deselect when there are 0 nodes in the Running state.
0989: * RunButton:
0990: * Enable when 1 or more nodes are in the Initted or Stopped states.
0991: * Disable when 0 nodes are in the Initted or Stopped states and it's not selected.
0992: * Select when 1 or more nodes are in the Running state.
0993: * Deselect when 0 nodes are in the Running state.
0994: * StopButton:
0995: * Enable when 1 or more nodes are in the Running state.
0996: * Disable when 0 nodes are in the Running state and it's not selected.
0997: * Select when 1 or more nodes are in the Stopping or Stopped states.
0998: * Deselect when 0 nodes are in the Stopping or Stopped states.
0999: */
1000: private void updateButtons() {
1001: boolean haveInitted = false;
1002: boolean haveRunning = false;
1003: boolean haveStopping = false;
1004: boolean haveStopped = false;
1005:
1006: ArrayList nodeModels = model.getNodeModels();
1007: for (int i = 0; i < nodeModels.size(); i++) {
1008: NodeModel nodeModel = (NodeModel) nodeModels.get(i);
1009: String state = nodeModel.getState();
1010: if (state.equals(NodeModel.STATE_RUNNING))
1011: haveRunning = true;
1012: else if (state.equals(NodeModel.STATE_INITTED))
1013: haveInitted = true;
1014: else if (state.equals(NodeModel.STATE_STOPPING))
1015: haveStopping = true;
1016: else if (state.equals(NodeModel.STATE_STOPPED))
1017: haveStopped = true;
1018: }
1019: if (haveInitted || haveStopped)
1020: runButton.setEnabled(true);
1021: if (!haveInitted && !haveStopped && !runButton.isSelected())
1022: runButton.setEnabled(false);
1023: if (haveRunning) {
1024: runButton.setSelected(true);
1025: // if you select a button, you have to enable it
1026: runButton.setEnabled(true);
1027: stopButton.setEnabled(true);
1028: } else {
1029: attachButton.setSelected(false);
1030: if (model.getUnattachedNodes().size() == 0)
1031: attachButton.setEnabled(false);
1032: runButton.setSelected(false);
1033: if (!stopButton.isSelected())
1034: stopButton.setEnabled(false);
1035: }
1036: if (haveStopping || haveStopped) {
1037: stopButton.setSelected(true);
1038: // if you select a button, you have to enable it
1039: stopButton.setEnabled(true);
1040: } else
1041: stopButton.setSelected(false);
1042: }
1043:
1044: /**
1045: * Remove node view and node status button.
1046: */
1047: public void removeNodeView(String nodeName) {
1048: NodeStatusButton button = model.getNodeModel(nodeName)
1049: .getStatusButton();
1050: if (button != null) {
1051: statusButtons.remove(button);
1052: buttonPanel.remove(button);
1053: }
1054: NodeView view = desktop.getNodeFrame(nodeName);
1055: if (view != null)
1056: desktop.removeFrame(view);
1057: }
1058:
1059: /**
1060: * Display dialog to set size of screen buffer for node output.
1061: * Return user's response. An value of -1 means display all.
1062: * A value of -2 means that the user cancelled the dialog.
1063: */
1064: static int displayViewSizeDialog(int currentViewSize) {
1065: JPanel bufferEventsPanel = new JPanel();
1066: JRadioButton allButton = new JRadioButton("All");
1067: JRadioButton sizeButton = new JRadioButton("Buffer Size");
1068: JTextField sizeTF = new JTextField(8);
1069: Logger log = CSMART.createLogger(CSMARTConsoleView.class
1070: .getName());
1071: if (currentViewSize == -1) {
1072: allButton.setSelected(true);
1073: sizeButton.setSelected(false);
1074: sizeTF.setText(String
1075: .valueOf(CSMARTConsoleModel.DEFAULT_VIEW_SIZE));
1076: } else {
1077: allButton.setSelected(false);
1078: sizeButton.setSelected(true);
1079: sizeTF.setText(String.valueOf(currentViewSize));
1080: }
1081: String oldTFVal = sizeTF.getText();
1082: ButtonGroup bufferButtonGroup = new ButtonGroup();
1083: bufferButtonGroup.add(allButton);
1084: bufferButtonGroup.add(sizeButton);
1085: bufferEventsPanel.add(allButton);
1086: bufferEventsPanel.add(sizeButton);
1087: bufferEventsPanel.add(sizeTF);
1088:
1089: int newViewSize = 0;
1090: while (true) {
1091: int result = JOptionPane.showConfirmDialog(null,
1092: bufferEventsPanel, "Node View",
1093: JOptionPane.OK_CANCEL_OPTION,
1094: JOptionPane.QUESTION_MESSAGE, null);
1095: if (result != JOptionPane.OK_OPTION)
1096: return -2; // user cancelled
1097: newViewSize = 0;
1098: if (allButton.isSelected()) {
1099: return -1;
1100: } else {
1101: try {
1102: newViewSize = Integer.parseInt(sizeTF.getText());
1103: } catch (NumberFormatException e) {
1104: if (log.isErrorEnabled()) {
1105: log.error("Bad new view size: "
1106: + sizeTF.getText());
1107: }
1108: }
1109: if (newViewSize < 1) {
1110: // Invalid size. Show error message.
1111: JOptionPane
1112: .showMessageDialog(
1113: null,
1114: "Invalid buffer size. Must be a whole number, at least 1.",
1115: "Invalid entry",
1116: JOptionPane.WARNING_MESSAGE);
1117: sizeTF.setText(oldTFVal);
1118: } else {
1119: // Legitimate result
1120: break;
1121: }
1122: }
1123: } // end of while loop
1124: return newViewSize;
1125: }
1126:
1127: /**
1128: * Select status button for node.
1129: */
1130: private void selectStatusButton(String nodeName) {
1131: NodeStatusButton button = model.getNodeModel(nodeName)
1132: .getStatusButton();
1133: if (button != null)
1134: button.setSelected(true);
1135: }
1136:
1137: /**
1138: * Listener on the node status buttons.
1139: * Right click pops-up a menu with the "About" node menu item.
1140: * Left click opens the node standard out frame,
1141: * and highlights the node in the configuration tree.
1142: */
1143: private MouseListener myMouseListener = new MouseAdapter() {
1144: public void mouseClicked(MouseEvent e) {
1145: if (e.isPopupTrigger()) {
1146: doPopup(e);
1147: } else {
1148: String nodeName = ((JRadioButton) e.getSource())
1149: .getActionCommand();
1150: displayNodeFrame(nodeName);
1151: selectNodeInHostTree(nodeName);
1152: }
1153: }
1154:
1155: public void mousePressed(MouseEvent e) {
1156: if (e.isPopupTrigger())
1157: doPopup(e);
1158: }
1159:
1160: public void mouseReleased(MouseEvent e) {
1161: if (e.isPopupTrigger())
1162: doPopup(e);
1163: }
1164: };
1165:
1166: /**
1167: * Display pop-up menu with "about" menu item, which provides
1168: * the same functionality as the "about" menu item in the node window,
1169: * but from the node status lamp.
1170: */
1171:
1172: private void doPopup(MouseEvent e) {
1173: model.setSelectedNodeName(((JRadioButton) e.getSource())
1174: .getActionCommand());
1175: nodeMenu.show((Component) e.getSource(), e.getX(), e.getY());
1176: }
1177:
1178: private void displayNodeFrame(String nodeName) {
1179: JInternalFrame frame = desktop.getNodeFrame(nodeName);
1180: if (frame == null)
1181: return; // frame not created yet
1182: try {
1183: frame.setIcon(false);
1184: frame.setSelected(true);
1185: } catch (PropertyVetoException exc) {
1186: }
1187: }
1188:
1189: /**
1190: * Query the user for the host and port of the remote app server.
1191: * Message the model to try to add this app server.
1192: */
1193: private void addAppServer() {
1194: int port = Experiment.APP_SERVER_DEFAULT_PORT;
1195: JTextField tf = new JTextField("localhost:" + port, 20);
1196: JPanel panel = new JPanel();
1197: panel.add(new JLabel("Enter HostName:Port:"));
1198: panel.add(tf);
1199: int result = JOptionPane.showOptionDialog(null, panel,
1200: "Add Application Server", JOptionPane.OK_CANCEL_OPTION,
1201: JOptionPane.PLAIN_MESSAGE, null, null, null);
1202: if (result != JOptionPane.OK_OPTION)
1203: return;
1204: String s = tf.getText().trim();
1205: int index = s.indexOf(':');
1206: String hostName = s;
1207:
1208: if (index != -1) {
1209: // Then hostname is the part before
1210: hostName = s.substring(0, index);
1211: hostName = hostName.trim();
1212: // But if there's nothing before the colon, use localhost
1213: if (hostName.equals(""))
1214: hostName = "localhost";
1215: // Port is the part after the colon
1216: String portString = s.substring(index + 1);
1217: portString = portString.trim();
1218: if (!portString.equals("")) {
1219: try {
1220: port = Integer.parseInt(portString);
1221: } catch (Exception e) {
1222: return;
1223: }
1224: if (port < 1)
1225: return;
1226: }
1227: }
1228: // check for duplicates
1229: ArrayList appServers = model.getAppServers();
1230: for (int i = 0; i < appServers.size(); i++) {
1231: AppServerDesc desc = (AppServerDesc) appServers.get(i);
1232: if (desc.hostName.equals(hostName) && desc.port == port) {
1233: JOptionPane
1234: .showMessageDialog(
1235: null,
1236: "This is a known application server; use Refresh to update information from it.",
1237: "Known Application Server",
1238: JOptionPane.INFORMATION_MESSAGE);
1239: return;
1240: }
1241: }
1242: model.requestAppServerAdd(hostName, port);
1243: }
1244:
1245: /**
1246: * Display a list of known app servers to the user.
1247: * Message the model to delete the app servers that the user selects.
1248: */
1249: private void deleteAppServers() {
1250: ArrayList appServers = model.getAppServers();
1251: Object[] appServersSelected = Util.getObjectsFromList(null,
1252: appServers, "Application Servers",
1253: "Select Application Servers To Ignore:");
1254: if (appServersSelected == null)
1255: return;
1256: for (int i = 0; i < appServersSelected.length; i++) {
1257: AppServerDesc appServerDesc = (AppServerDesc) appServersSelected[i];
1258: model.appServerDelete(appServerDesc);
1259: }
1260: }
1261:
1262: private void refreshAppServers() {
1263: model.refreshAppServers();
1264: }
1265:
1266: private void displayAppServers() {
1267: Util.showObjectsInList(this , model.getAppServers(),
1268: "Application Servers", "Application Servers");
1269: }
1270:
1271: /**
1272: * TreeSelectionListener interface.
1273: * If user selects an agent in the "Hosts" tree,
1274: * then pop the pane for that node to the foreground, and
1275: * select the node status button.
1276: */
1277: private TreeSelectionListener myTreeListener = new TreeSelectionListener() {
1278: public void valueChanged(TreeSelectionEvent event) {
1279: TreePath path = event.getPath();
1280: if (path == null)
1281: return;
1282: DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) path
1283: .getLastPathComponent();
1284: ConsoleTreeObject cto = (ConsoleTreeObject) treeNode
1285: .getUserObject();
1286: if (!cto.isNode())
1287: return; // ignore selecting if it's not a node
1288: String nodeName = ((ConsoleTreeObject) treeNode
1289: .getUserObject()).getName();
1290: if (model.getNodeModel(nodeName) != null) {
1291: displayNodeFrame(nodeName);
1292: selectStatusButton(nodeName);
1293: }
1294: }
1295: };
1296:
1297: /**
1298: * Select node in host tree; called when user selects corresponding
1299: * pane or status button.
1300: */
1301: private void selectNodeInHostTree(String nodeName) {
1302: if (hostConfiguration == null)
1303: return;
1304: hostConfiguration
1305: .removeHostTreeSelectionListener(myTreeListener);
1306: hostConfiguration.selectNodeInHostTree(nodeName);
1307: hostConfiguration.addHostTreeSelectionListener(myTreeListener);
1308: }
1309:
1310: /**
1311: * Listener on node frame. When frame is selected,
1312: * select status button and node in configuration tree.
1313: */
1314: class NodeFrameListener implements InternalFrameListener {
1315: public void internalFrameClosed(InternalFrameEvent e) {
1316: }
1317:
1318: public void internalFrameClosing(InternalFrameEvent e) {
1319: }
1320:
1321: public void internalFrameDeactivated(InternalFrameEvent e) {
1322: }
1323:
1324: public void internalFrameIconified(InternalFrameEvent e) {
1325: }
1326:
1327: public void internalFrameOpened(InternalFrameEvent e) {
1328: }
1329:
1330: public void internalFrameActivated(InternalFrameEvent e) {
1331: frameSelected(e);
1332: }
1333:
1334: public void internalFrameDeiconified(InternalFrameEvent e) {
1335: frameSelected(e);
1336: }
1337:
1338: private void frameSelected(InternalFrameEvent e) {
1339: NodeView nodeView = (NodeView) e.getInternalFrame();
1340: String nodeName = nodeView.getNodeName();
1341: selectStatusButton(nodeName);
1342: selectNodeInHostTree(nodeName);
1343: }
1344: } // end NodeFrameListener
1345:
1346: private String getElapsedTimeLabel(String prefix, long startTime) {
1347: long now = new Date().getTime();
1348: long timeElapsed = now - startTime;
1349: long hours = timeElapsed / MSECS_PER_HOUR;
1350: timeElapsed = timeElapsed - (hours * MSECS_PER_HOUR);
1351: long minutes = timeElapsed / MSECS_PER_MINUTE;
1352: timeElapsed = timeElapsed - (minutes * MSECS_PER_MINUTE);
1353: long seconds = timeElapsed / MSECS_PER_SECOND;
1354: StringBuffer sb = new StringBuffer(20);
1355: sb.append(prefix);
1356: sb.append(myNumberFormat.format(hours));
1357: sb.append(":");
1358: sb.append(myNumberFormat.format(minutes));
1359: sb.append(":");
1360: sb.append(myNumberFormat.format(seconds));
1361: return sb.toString();
1362: }
1363:
1364: class CreateExperiment {
1365:
1366: boolean isValidating = false;
1367: JCheckBox validate = null;
1368:
1369: CreateExperiment() {
1370: JFileChooser chooser = new JFileChooser();
1371: validate = new JCheckBox("Validate with Schema");
1372: validate.addActionListener(new ActionListener() {
1373: public void actionPerformed(ActionEvent e) {
1374: toggleValidate();
1375: }
1376: });
1377:
1378: ChooserUtils utils = new ChooserUtils();
1379: chooser.setAccessory(validate);
1380: chooser.addChoosableFileFilter(utils.getFileFilter("xml",
1381: "Configuration files (*.xml)"));
1382: int option = chooser.showOpenDialog(CSMARTConsoleView.this );
1383: if (option == JFileChooser.APPROVE_OPTION) {
1384: XMLExperiment exp = new XMLExperiment(chooser
1385: .getSelectedFile(), CSMARTConsoleView.this );
1386:
1387: try {
1388: exp.doParse(isValidating);
1389: model.setXMLFile(chooser.getSelectedFile());
1390: if (isValidating) {
1391: // Since we cannot modify XML, if it has been validated once, don't validate it again.
1392: NodeComponent nodes[] = exp.getNodeComponents();
1393: for (int i = 0; i < nodes.length; i++) {
1394: NodeComponent node = nodes[i];
1395: node.addArgument(
1396: "org.cougaar.core.node.validate",
1397: "false");
1398: }
1399: }
1400: model.setExperiment(exp);
1401:
1402: } catch (Exception e) {
1403: JOptionPane.showMessageDialog(
1404: CSMARTConsoleView.this ,
1405: "Parse Failed, or cancel was pushed. "
1406: + "See logs for details",
1407: "Failure", JOptionPane.ERROR_MESSAGE);
1408: }
1409: }
1410: }
1411:
1412: private void toggleValidate() {
1413: isValidating = validate.isSelected();
1414: }
1415: }
1416: }
|