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.experiment;
028:
029: import org.cougaar.tools.csmart.ui.console.CSMARTConsoleModel;
030: import org.cougaar.tools.csmart.ui.viewer.CSMART;
031: import org.cougaar.util.log.Logger;
032:
033: import javax.swing.*;
034: import javax.swing.event.ListSelectionEvent;
035: import javax.swing.event.ListSelectionListener;
036: import java.awt.*;
037: import java.awt.event.ActionEvent;
038: import java.awt.event.ActionListener;
039: import java.awt.event.WindowAdapter;
040: import java.awt.event.WindowEvent;
041: import java.io.File;
042: import java.io.FileInputStream;
043: import java.util.Enumeration;
044: import java.util.Properties;
045:
046: /**
047: * Set and edit Command line arguments for the Node.
048: * @property org.cougaar.install.path is used to find a file of Node -D arguments
049: */
050: public class NodeArgumentDialog extends JDialog {
051: Properties props;
052: JTable argTable;
053: NodeArgumentTableModel model;
054: JTextArea args;
055: int returnValue;
056: JButton deleteButton;
057: private transient Logger log;
058:
059: public NodeArgumentDialog(String title, Properties props,
060: boolean isLocal, boolean isEditable) {
061: super ((Frame) null, title, isEditable); // display modal dialog
062:
063: createLogger();
064:
065: Box nodeArgPanel = Box.createVerticalBox();
066:
067: // create JTable
068: if (isEditable)
069: argTable = new JTable();
070: else {
071: argTable = new JTable() {
072: public boolean isCellEditable(int row, int column) {
073: return false;
074: }
075: };
076: }
077: // don't allow user to reorder columns
078: argTable.getTableHeader().setReorderingAllowed(false);
079: argTable.setColumnSelectionAllowed(false);
080: argTable.getSelectionModel().setSelectionMode(
081: ListSelectionModel.SINGLE_SELECTION);
082: JScrollPane scrollPane = new JScrollPane(argTable);
083:
084: // listen for table selections in local argument table
085: // and disable Delete button if the argument is global
086: if (isLocal && isEditable) {
087: ListSelectionModel lsm = argTable.getSelectionModel();
088: lsm.addListSelectionListener(new ListSelectionListener() {
089: public void valueChanged(ListSelectionEvent e) {
090: //Ignore extra messages.
091: if (e.getValueIsAdjusting())
092: return;
093:
094: ListSelectionModel lsm2 = (ListSelectionModel) e
095: .getSource();
096: if (!lsm2.isSelectionEmpty()) {
097: int selectedRow = lsm2.getMinSelectionIndex();
098: Object o = argTable.getModel().getValueAt(
099: selectedRow, 2);
100: if (o.equals("*"))
101: deleteButton.setEnabled(false);
102: else
103: deleteButton.setEnabled(true);
104: }
105: }
106: });
107: }
108:
109: JPanel tablePanel = new JPanel(new BorderLayout());
110: tablePanel.setBorder(BorderFactory
111: .createTitledBorder("-D Options"));
112: tablePanel.add(scrollPane);
113:
114: // initialize text area and table from properties
115: JPanel argumentPanel = new JPanel();
116: argumentPanel.setBorder(BorderFactory
117: .createTitledBorder("Arguments"));
118: args = new JTextArea(10, 40);
119: args.setEditable(isEditable);
120: args
121: .setToolTipText("Enter command line args one per line. Node class must be first.");
122: argumentPanel.add(args);
123:
124: this .props = props;
125: String value = props
126: .getProperty(CSMARTConsoleModel.COMMAND_ARGUMENTS);
127: setArguments(value);
128: model = new NodeArgumentTableModel(props, isLocal);
129: argTable.setModel(model);
130:
131: // simplified version if not editable
132: if (!isEditable) {
133: JButton okButton = new JButton("OK");
134: okButton.addActionListener(new ActionListener() {
135: public void actionPerformed(ActionEvent e) {
136: setVisible(false);
137: }
138: });
139: nodeArgPanel.add(tablePanel);
140: nodeArgPanel.add(argumentPanel);
141: JPanel panel = new JPanel();
142: panel.add(okButton);
143: nodeArgPanel.add(panel);
144: getContentPane().add(nodeArgPanel);
145: pack();
146: return;
147: }
148:
149: // ok and cancel buttons panel
150: JPanel buttonPanel = new JPanel();
151: JButton okButton = new JButton("OK");
152: // if user confirms the dialog and hasn't terminated editing a table cell
153: // then get the value from that cell editor and set it in the cell
154: okButton.addActionListener(new ActionListener() {
155: public void actionPerformed(ActionEvent e) {
156: Component c = argTable.getEditorComponent();
157: if (c != null)
158: if (c instanceof JTextField) {
159: int rowIndex = argTable.getEditingRow();
160: int colIndex = argTable.getEditingColumn();
161: if (rowIndex != -1 && colIndex != -1)
162: model.setValueAt(
163: ((JTextField) c).getText(),
164: rowIndex, colIndex);
165: } else if (log.isErrorEnabled()) {
166: log.error("Unexpected editor class: "
167: + c.getClass());
168: }
169: returnValue = JOptionPane.OK_OPTION;
170: setVisible(false);
171: }
172: });
173: buttonPanel.add(okButton);
174: JButton cancelButton = new JButton("Cancel");
175: cancelButton.addActionListener(new ActionListener() {
176: public void actionPerformed(ActionEvent e) {
177: returnValue = JOptionPane.CANCEL_OPTION;
178: setVisible(false);
179: }
180: });
181: buttonPanel.add(cancelButton);
182:
183: // add buttons to add/delete properties
184: JPanel tableButtonPanel = new JPanel();
185: JButton addButton = new JButton("Add Property");
186: addButton.addActionListener(new ActionListener() {
187: public void actionPerformed(ActionEvent e) {
188: model.addRow("", "");
189: }
190: });
191: tableButtonPanel.add(addButton);
192: deleteButton = new JButton("Delete Property");
193: deleteButton.addActionListener(new ActionListener() {
194: public void actionPerformed(ActionEvent e) {
195: int i = argTable.getSelectedRow();
196: if (i != -1)
197: model.removeRow(i);
198: }
199: });
200: tableButtonPanel.add(deleteButton);
201: JButton fileButton = new JButton("Read From File");
202: fileButton.addActionListener(new ActionListener() {
203: public void actionPerformed(ActionEvent e) {
204: readPropertiesFromFile();
205: }
206: });
207: tableButtonPanel.add(fileButton);
208: tablePanel.add(tableButtonPanel, BorderLayout.SOUTH);
209:
210: nodeArgPanel.add(tablePanel);
211: nodeArgPanel.add(argumentPanel);
212: nodeArgPanel.add(buttonPanel);
213: getContentPane().add(nodeArgPanel);
214:
215: addWindowListener(new WindowAdapter() {
216: public void windowClosing(WindowEvent e) {
217: returnValue = JOptionPane.CLOSED_OPTION;
218: NodeArgumentDialog.this .setVisible(false);
219: }
220: });
221:
222: pack();
223: }
224:
225: public void createLogger() {
226: log = CSMART.createLogger(this .getClass().getName());
227: }
228:
229: /**
230: * Return a value indicating how the dialog was dismissed: one of
231: * JOptionPane.OK_OPTION, JOptionPane.CANCEL_OPTION,
232: * JOptionPane.CLOSED_OPTION
233: */
234: public int getValue() {
235: return returnValue;
236: }
237:
238: /**
239: * Update the properties from the table.
240: * @return true if any modifications, false otherwise
241: */
242: public boolean updateProperties() {
243: boolean isModified = model.updateProperties();
244: String s = getArguments();
245: if (s != null
246: && !s
247: .equals(props
248: .getProperty(CSMARTConsoleModel.COMMAND_ARGUMENTS))) {
249: props.setProperty(CSMARTConsoleModel.COMMAND_ARGUMENTS, s);
250: isModified = true;
251: }
252: return isModified;
253: }
254:
255: /**
256: * Set the arguments displayed in the dialog.
257: */
258: private void setArguments(String arguments) {
259: args.setText(arguments);
260: }
261:
262: /**
263: * Get the arguments displayed in the dialog.
264: */
265: private String getArguments() {
266: return args.getText();
267: }
268:
269: private void readPropertiesFromFile() {
270: String dirName = ".";
271: try {
272: dirName = System.getProperty("org.cougaar.install.path");
273: } catch (RuntimeException e) {
274: // just use default
275: }
276: if (dirName == null)
277: dirName = ".";
278: JFileChooser chooser = new JFileChooser(dirName);
279: chooser.setDialogTitle("Select Java Properties file to apply");
280: int result = chooser.showOpenDialog(this );
281: if (result != JFileChooser.APPROVE_OPTION)
282: return;
283:
284: File sel = chooser.getSelectedFile();
285: if (sel == null || !sel.canRead() || sel.isDirectory())
286: return;
287:
288: FileInputStream in = null;
289: Properties properties = new Properties();
290: try {
291: in = new FileInputStream(sel);
292: properties.load(in);
293: } catch (Exception e) {
294: if (log.isErrorEnabled()) {
295: log.error("Exception reading properties file: ", e);
296: }
297: return;
298: }
299: // add all properties from the file, overwriting any existing property
300: Enumeration keys = properties.propertyNames();
301: while (keys.hasMoreElements()) {
302: String key = (String) keys.nextElement();
303: if (key.equals(CSMARTConsoleModel.COMMAND_ARGUMENTS))
304: setArguments(properties.getProperty(key));
305: else
306: model.addRow(key, properties.getProperty(key));
307: }
308: }
309:
310: public static void main(String[] args) {
311: Properties props = new Properties();
312: props.setProperty("Color", "Red");
313: props.setProperty("Number", "33");
314: props.setProperty("Day", "Friday");
315: NodeArgumentDialog nad = new NodeArgumentDialog("Test", props,
316: true, false);
317: nad.setVisible(true);
318: if (nad.getValue() != JOptionPane.OK_OPTION)
319: return;
320: nad.updateProperties();
321: props.list(System.out);
322: }
323:
324: }
|