1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * ident        "%Z%%M% %I%     %E% SMI"
  24  *
  25  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
  26  * Use is subject to license terms.
  27  */
  28 package com.sun.dhcpmgr.client;
  29 
  30 import javax.swing.*;
  31 import javax.swing.border.*;
  32 import javax.swing.event.*;
  33 import javax.swing.table.*;
  34 
  35 import java.awt.*;
  36 import java.awt.event.*;
  37 import java.text.MessageFormat;
  38 import java.util.*;
  39 
  40 import com.sun.dhcpmgr.server.*;
  41 import com.sun.dhcpmgr.data.*;
  42 import com.sun.dhcpmgr.ui.*;
  43 import com.sun.dhcpmgr.bridge.NotRunningException;
  44 
  45 /**
  46  * Dialog to create/duplicate/edit a macro.
  47  */
  48 public class CreateMacroDialog extends JDialog implements ButtonPanelListener {
  49 
  50     // Model for the table that displays the macro's contents
  51     class MacroTableModel extends AbstractTableModel {
  52         Macro macro;
  53         
  54         public MacroTableModel() {
  55             setMacro(new Macro());
  56         }
  57         
  58         public MacroTableModel(Macro m) {
  59             super();
  60             setMacro(m);
  61         }
  62         
  63         public void setMacro(Macro m) {
  64             macro = m;
  65             fireTableDataChanged();
  66         }
  67         
  68         public int getRowCount() {
  69             return macro.optionCount();
  70         }
  71         
  72         public int getColumnCount() {
  73             return 2;
  74         }
  75         
  76         public Object getValueAt(int row, int column) {
  77             OptionValue v = null;       
  78             try {
  79                 v = macro.getOptionAt(row);
  80             } catch (ArrayIndexOutOfBoundsException e) {
  81                 return null;
  82             }
  83             if (v == null) {
  84                 return null;
  85             }
  86             switch (column) {
  87             case 0:
  88                 return v.getName();
  89             case 1:
  90                 return v.getValue();
  91             default:
  92                 return null;
  93             }
  94         }
  95         
  96         public Class getColumnClass(int column) {
  97             switch (column) {
  98             case 0:
  99             case 1:
 100                 return String.class;
 101             default:
 102                 return super.getColumnClass(column);
 103             }
 104         }
 105         
 106         public String getColumnName(int column) {
 107             switch (column) {
 108             case 0:
 109                 return ResourceStrings.getString("option_column");
 110             case 1:
 111                 return ResourceStrings.getString("value_column");
 112             default:
 113                 super.getColumnName(column);
 114             }
 115             return null;
 116         }
 117         
 118         public boolean isCellEditable(int row, int column) {
 119             return false;
 120         }
 121         
 122         public void moveRowUp(int row) {
 123             OptionValue v = macro.getOptionAt(row);
 124             macro.deleteOptionAt(row);
 125             macro.insertOptionAt(v, row-1);
 126             fireTableRowsUpdated(row-1, row);
 127         }
 128         
 129         public void moveRowDown(int row) {
 130             OptionValue v = macro.getOptionAt(row);
 131             macro.deleteOptionAt(row);
 132             macro.insertOptionAt(v, row+1);
 133             fireTableRowsUpdated(row, row+1);
 134         }
 135         
 136         public void deleteRow(int row) {
 137             macro.deleteOptionAt(row);
 138             fireTableRowsDeleted(row, row);
 139         }
 140         
 141         public void setOptionAt(OptionValue v, int row) {
 142             macro.setOptionAt(v, row);
 143             fireTableDataChanged();
 144         }
 145 
 146         public int findRowForOption(String opt) {
 147             for (int i = 0; i < getRowCount(); ++i) {
 148                 OptionValue v = macro.getOptionAt(i);
 149                 if (opt.equals(v.getName())) {
 150                     return i;
 151                 }
 152             }
 153             return -1;
 154         }
 155     }
 156     
 157     public static final int CREATE = 0;
 158     public static final int EDIT = 1;
 159     public static final int DUPLICATE = 2;
 160     
 161     private int mode = CREATE;
 162     private Macro originalMacro = null;
 163     private MacroNameField name;
 164     private JTextField optionName;
 165     private JTextField optionValue;
 166     private AutosizingTable macroTable;
 167     private MacroTableModel macroTableModel;
 168     private ButtonPanel buttonPanel;
 169     private JButton deleteButton, addButton, modifyButton, selectButton;
 170     private UpButton upButton;
 171     private DownButton downButton;
 172     private JCheckBox signalBox;
 173     private Vector listeners;
 174     private String savedOptionName = "";
 175 
 176     /*
 177      * Listener for the editing buttons which are used to manipulate the
 178      * table's contents
 179      */
 180     ActionListener listener = new ActionListener() {
 181         public void actionPerformed(ActionEvent e) {
 182             int row = macroTable.getSelectedRow();
 183             int lastRow = macroTable.getRowCount() - 1;
 184             
 185             Object src = e.getSource();
 186             if (src == upButton) {
 187                 if (row == 0)  {
 188                     return; // Can't move the first row up
 189                 }
 190                 macroTableModel.moveRowUp(row);
 191                 /*
 192                  * Keep the row we moved selected so that repeated move up's
 193                  * affect the same data
 194                  */
 195                 macroTable.clearSelection();
 196                 macroTable.addRowSelectionInterval(row-1, row-1);
 197             } else if (src == downButton) {
 198                 if (row == lastRow) {
 199                     return; // Can't move the last row down
 200                 }
 201                 macroTableModel.moveRowDown(row);
 202                 /*
 203                  * Keep the row we moved selected so that repeated move down's
 204                  * affect the same data
 205                  */
 206                 macroTable.clearSelection();
 207                 macroTable.addRowSelectionInterval(row+1, row+1);
 208             } else if (src == deleteButton) {
 209                 macroTableModel.deleteRow(row);
 210                 /*
 211                  * Keep the same row selected so that repeated delete presses
 212                  * can be used to delete a series of options
 213                  */
 214                 macroTable.clearSelection();
 215                 if (row == lastRow) {
 216                     row = macroTableModel.getRowCount()-1;
 217                 }
 218                 if (macroTableModel.getRowCount() > 0) {
 219                     macroTable.addRowSelectionInterval(row, row);
 220                 }
 221                 if (macroTableModel.getRowCount() <= 0) {
 222                     modifyButton.setEnabled(false);
 223                 }
 224             } else if (src == selectButton) {
 225                 // Show dialog that allows selection of options
 226                 String s = SelectOptionDialog.showDialog(selectButton);
 227 
 228                 /*
 229                  * User selected something, put it in the name field
 230                  * set the focus to the value field
 231                  */
 232                 if (s != null) {
 233                     optionName.setText(s);
 234                     optionValue.requestFocus();
 235                 }
 236             } else if ((src == addButton) || (src == modifyButton)) {
 237                 // Update the table from the field contents
 238                 OptionValue v = null;
 239                 v = OptionValueFactory.newOptionValue(optionName.getText());
 240                 if (v instanceof BogusOptionValue) {
 241                     optionName.requestFocus();
 242                     // bad option name
 243                     MessageFormat form = null;
 244                     Object [] args = new Object[1];
 245                     args[0] = optionName.getText();
 246                     form = new MessageFormat(
 247                         ResourceStrings.getString("bad_option_name"));
 248                     JOptionPane.showMessageDialog(macroTable, form.format(args),
 249                         ResourceStrings.getString("input_error"),
 250                         JOptionPane.ERROR_MESSAGE);
 251                     return;
 252                 }
 253                 try {
 254                     /*
 255                      * Catch an empty value field, which is only legal for
 256                      * a boolean option
 257                      */
 258                     String s = optionValue.getText();
 259                     if (s.length() == 0 && !(v instanceof BooleanOptionValue)) {
 260                         throw new ValidationException();
 261                     }
 262                     v.setValue(s);
 263                 } catch (ValidationException ex) {
 264                     // bad option value
 265                     optionValue.requestFocus();
 266                     MessageFormat form = null;
 267                     Object [] args = new Object[2];
 268                     form = new MessageFormat(
 269                         ResourceStrings.getString("bad_option_value"));
 270                     args[0] = optionValue.getText();
 271                     args[1] = optionName.getText();
 272                     JOptionPane.showMessageDialog(macroTable, form.format(args),
 273                         ResourceStrings.getString("input_error"),
 274                         JOptionPane.ERROR_MESSAGE);
 275                     return;
 276                 }
 277                 /*
 278                  * Don't allow a second instance of any option other than
 279                  * Include in a macro, but only check if we're doing an add
 280                  * or if it's a modify and the name has changed.
 281                  */
 282                 if ((!(v instanceof IncludeOptionValue)
 283                         && (src == addButton))
 284                         || ((src == modifyButton)
 285                         && !savedOptionName.equals(v.getName()))) {
 286                     if (macroTableModel.macro.getOption(v.getName()) != null) {
 287                         optionName.requestFocus();
 288                         MessageFormat form = new MessageFormat(
 289                             ResourceStrings.getString("macro_contains_option"));
 290                         Object [] args = new Object[1];
 291                         args[0] = v.getName();
 292                         JOptionPane.showMessageDialog(macroTable,
 293                             form.format(args),
 294                             ResourceStrings.getString("input_error"),
 295                             JOptionPane.ERROR_MESSAGE);
 296                         return;
 297                     }
 298                 }
 299                 // If adding, append it at the end
 300                 if (src == addButton) {
 301                     row = macroTableModel.getRowCount();
 302                 }
 303                 macroTableModel.setOptionAt(v, row);
 304                 macroTable.clearSelection();
 305                 macroTable.addRowSelectionInterval(row, row);
 306                 macroTable.scrollRectToVisible(
 307                     macroTable.getCellRect(row, 0, false));
 308             }           
 309         }
 310     };
 311     
 312     public CreateMacroDialog(Frame f, int mode) {
 313         super(f);
 314         setLocationRelativeTo(f);
 315 
 316         listeners = new Vector();
 317         
 318         this.mode = mode;
 319         switch (mode) {
 320         case CREATE:
 321             setTitle(ResourceStrings.getString("create_macro_title"));
 322             break;
 323         case EDIT:
 324             setTitle(ResourceStrings.getString("edit_macro_title"));
 325             break;
 326         case DUPLICATE:
 327             setTitle(ResourceStrings.getString("duplicate_macro_title"));
 328             break;
 329         default:
 330             break;
 331         }       
 332         
 333         getContentPane().setLayout(new BoxLayout(getContentPane(),
 334             BoxLayout.Y_AXIS));
 335         JPanel mainPanel = new JPanel(new BorderLayout());
 336         mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
 337         
 338         // Name cannot have blanks in it so use a control which disallows them
 339         name = new MacroNameField("", 30);
 340         JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
 341 
 342         Mnemonic mnName =
 343             new Mnemonic(ResourceStrings.getString("md_name_label"));
 344         JLabel nameLbl = new JLabel(mnName.getString());
 345         nameLbl.setLabelFor(name);
 346         nameLbl.setToolTipText(mnName.getString());
 347         nameLbl.setDisplayedMnemonic(mnName.getMnemonic());
 348         panel.add(nameLbl);
 349 
 350         panel.add(name);
 351         mainPanel.add(panel, BorderLayout.NORTH);
 352         
 353         JPanel contentsPanel = new JPanel();
 354         contentsPanel.setLayout(new BorderLayout());
 355         // Put a titled border on the contents panel
 356         Border b = BorderFactory.createCompoundBorder(
 357             BorderFactory.createLineBorder(Color.black),
 358             BorderFactory.createEmptyBorder(5, 10, 5, 10));
 359         contentsPanel.setBorder(BorderFactory.createTitledBorder(b,
 360             ResourceStrings.getString("contents_label")));
 361         
 362         /*
 363          * Create a panel using a couple of text fields to edit the options
 364          * included in the macro
 365          */
 366         JPanel fieldPanel = new JPanel(new FieldLayout());
 367         // Field for option name
 368 
 369         panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
 370         optionName = new JTextField("", 20);
 371         Mnemonic mnOptName =
 372             new Mnemonic(ResourceStrings.getString("md_option_name"));
 373         JLabel optNameLbl =
 374             new JLabel(mnOptName.getString());
 375         fieldPanel.add(FieldLayout.LABEL, optNameLbl);
 376         optNameLbl.setLabelFor(optionName);
 377         optNameLbl.setToolTipText(mnOptName.getString());
 378         optNameLbl.setDisplayedMnemonic(mnOptName.getMnemonic());
 379 
 380         panel.add(optionName);
 381         panel.add(Box.createHorizontalStrut(5));
 382 
 383         Mnemonic mnSelect = 
 384             new Mnemonic(ResourceStrings.getString("select"));
 385         selectButton = new JButton(mnSelect.getString());
 386         selectButton.setToolTipText(mnSelect.getString());
 387         selectButton.setMnemonic(mnSelect.getMnemonic());
 388 
 389         selectButton.addActionListener(listener);
 390         panel.add(selectButton);
 391         fieldPanel.add(FieldLayout.FIELD, panel);
 392 
 393         // Field for option value
 394 
 395         optionValue = new JTextField();
 396 
 397         Mnemonic mnOptVal =
 398             new Mnemonic(ResourceStrings.getString("md_option_value"));
 399         JLabel optValLbl = new JLabel(mnOptVal.getString());
 400         fieldPanel.add(FieldLayout.LABEL, optValLbl);
 401         optValLbl.setLabelFor(optionValue);
 402         optValLbl.setToolTipText(mnOptVal.getString());
 403         optValLbl.setDisplayedMnemonic(mnOptVal.getMnemonic());
 404 
 405         fieldPanel.add(FieldLayout.FIELD, optionValue);
 406 
 407         // Buttons for add/modify
 408 
 409         Mnemonic mnAdd = 
 410             new Mnemonic(ResourceStrings.getString("add"));
 411         addButton = new JButton(mnAdd.getString());        
 412         addButton.setToolTipText(mnAdd.getString());
 413         addButton.setMnemonic(mnAdd.getMnemonic());
 414 
 415         addButton.addActionListener(listener);
 416         addButton.setEnabled(false);
 417 
 418         Mnemonic mnModify =
 419             new Mnemonic(ResourceStrings.getString("modify"));
 420         modifyButton = new JButton(mnModify.getString());
 421         modifyButton.setToolTipText(mnModify.getString()); 
 422         modifyButton.setMnemonic(mnModify.getMnemonic()); 
 423 
 424         modifyButton.addActionListener(listener);
 425         modifyButton.setEnabled(false);
 426         panel = new JPanel(new VerticalButtonLayout());
 427         panel.add(addButton);
 428         panel.add(modifyButton);
 429         
 430         JPanel editPanel = new JPanel(new BorderLayout());
 431         editPanel.add(fieldPanel, BorderLayout.WEST);
 432         editPanel.add(panel, BorderLayout.EAST);
 433         contentsPanel.add(editPanel, BorderLayout.NORTH);
 434         
 435         // Use a table to display the contents of the macro
 436         macroTableModel = new MacroTableModel();
 437         macroTable = new AutosizingTable(macroTableModel);
 438         macroTable.getTableHeader().setReorderingAllowed(false);
 439         macroTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 440         JScrollPane macroTablePane = new JScrollPane(macroTable);
 441         // Resize table as otherwise it asks for a huge area
 442         Dimension d = macroTable.getPreferredScrollableViewportSize();
 443         d.height = 100;
 444         d.width = 300;
 445         macroTable.setPreferredScrollableViewportSize(d);
 446 
 447         contentsPanel.add(macroTablePane, BorderLayout.CENTER);
 448         
 449         // Create buttons for controlling table
 450         JPanel editButtonPanel = new JPanel(new VerticalButtonLayout());
 451         
 452         upButton = new UpButton();
 453         upButton.setEnabled(false);
 454         upButton.addActionListener(listener);
 455         editButtonPanel.add(upButton);
 456 
 457         downButton = new DownButton();
 458         downButton.setEnabled(false);
 459         downButton.addActionListener(listener);
 460         editButtonPanel.add(downButton);
 461 
 462         Mnemonic mnDelete =
 463             new Mnemonic(ResourceStrings.getString("delete"));
 464         deleteButton = new JButton(mnDelete.getString());
 465         deleteButton.setToolTipText(mnDelete.getString());
 466         deleteButton.setMnemonic(mnDelete.getMnemonic());
 467 
 468         deleteButton.setEnabled(false);
 469         deleteButton.addActionListener(listener);
 470         editButtonPanel.add(deleteButton);
 471         contentsPanel.add(editButtonPanel, BorderLayout.EAST);
 472         
 473         mainPanel.add(contentsPanel, BorderLayout.CENTER);
 474                 
 475         signalBox = new JCheckBox(ResourceStrings.getString("signal_server"),
 476             true);
 477         signalBox.setToolTipText(
 478             ResourceStrings.getString("signal_server"));
 479         signalBox.setHorizontalAlignment(SwingConstants.CENTER);
 480         mainPanel.add(signalBox, BorderLayout.SOUTH);
 481         
 482         getContentPane().add(mainPanel);
 483         getContentPane().add(new JSeparator());
 484         
 485         buttonPanel = new ButtonPanel(true);
 486         buttonPanel.addButtonPanelListener(this);
 487         getContentPane().add(buttonPanel);
 488         
 489         // Listen to table selection state and set state of buttons accordingly
 490         macroTable.getSelectionModel().addListSelectionListener(
 491                 new ListSelectionListener() {
 492             public void valueChanged(ListSelectionEvent e) {
 493                 int index = macroTable.getSelectedRow();
 494                 if (index == -1) {
 495                     // Nothing selected, disable all
 496                     upButton.setEnabled(false);
 497                     downButton.setEnabled(false);
 498                     deleteButton.setEnabled(false);
 499                     // Clear the option name we saved
 500                     savedOptionName = "";
 501                 } else {
 502                     if (macroTable.getRowCount() > 0) {
 503                         /*
 504                          * Only allow deleteButton to be activated when 
 505                          * the table is not empty regardless of selection
 506                          * method, mouse or keyboard
 507                          */
 508                         deleteButton.setEnabled(true);
 509                     }
 510                     if (index == 0) {
 511                         // First row can't move up
 512                         upButton.setEnabled(false);
 513                     } else {
 514                         upButton.setEnabled(true);
 515                     }
 516                     if (index == (macroTable.getRowCount() - 1)) {
 517                         // Last row can't move down
 518                         downButton.setEnabled(false);
 519                     } else {
 520                         if (macroTable.getRowCount() > 0) {
 521                             /* 
 522                              * Only allow downButton to be activated when the 
 523                              * table is not empty regardless of selection
 524                              * method, mouse or keyboard 
 525                              */
 526                             downButton.setEnabled(true);
 527                         }       
 528                     }
 529                     // Save editing name so we can detect name change
 530                     savedOptionName =
 531                         (String)macroTableModel.getValueAt(index, 0);
 532                     optionName.setText(savedOptionName);
 533                     optionValue.setText(
 534                         (String)macroTableModel.getValueAt(index, 1));
 535                 }
 536             }
 537         });
 538         
 539         // Only enable OK if the name is not empty
 540         name.getDocument().addDocumentListener(new DocumentListener() {
 541             public void insertUpdate(DocumentEvent e) {
 542                 buttonPanel.setOkEnabled(e.getDocument().getLength() != 0);
 543             }
 544             public void changedUpdate(DocumentEvent e) {
 545                 insertUpdate(e);
 546             }
 547             public void removeUpdate(DocumentEvent e) {
 548                 insertUpdate(e);
 549             }
 550         });
 551 
 552         // Only enable add/modify when option name is non-empty
 553         optionName.getDocument().addDocumentListener(new DocumentListener() {
 554             public void insertUpdate(DocumentEvent e) {
 555                 boolean state = (optionName.getDocument().getLength() != 0);
 556                 addButton.setEnabled(state);
 557                 if (state == false) {
 558                     modifyButton.setEnabled(state);
 559                 } else if (macroTable.getSelectedRowCount() > 0) {
 560                     modifyButton.setEnabled(state);
 561                 }
 562             }
 563             public void changedUpdate(DocumentEvent e) {
 564                 insertUpdate(e);
 565             }
 566             public void removeUpdate(DocumentEvent e) {
 567                 insertUpdate(e);
 568             }
 569         });
 570         
 571         if (mode == EDIT) {
 572             buttonPanel.setOkEnabled(true);
 573         }
 574         setMacro(new Macro());
 575     }
 576 
 577     /**
 578      * Display this dialog, and auto-validate its contents to start with
 579      */
 580     public void setVisible(boolean visible) {
 581         super.setVisible(visible);
 582         /*
 583          * If we're being hidden, then just return
 584          */
 585         if (!visible)
 586                 return;
 587         /*
 588          * Validate the current contents of the macro so we can tell the user
 589          * about any syntax errors in the existing definition.
 590          */
 591         try {
 592             macroTableModel.macro.validate();
 593         } catch (ValidationException e) {
 594             // Errors; advise user by putting up a dialog
 595             MessageFormat form = new MessageFormat(
 596                 ResourceStrings.getString("bad_option_value"));
 597             Object [] args = new Object[2];
 598             OptionValue ov = macroTableModel.macro.getOption(e.getMessage());
 599             if (ov == null) {
 600                 args[0] = "";
 601             } else {
 602                 args[0] = ov.getValue();
 603             }
 604             args[1] = e.getMessage();
 605             JOptionPane.showMessageDialog(this, form.format(args),
 606                 ResourceStrings.getString("server_error_title"),
 607                 JOptionPane.ERROR_MESSAGE);
 608             int row = macroTableModel.findRowForOption(e.getMessage());
 609             if (row != -1) {
 610                 macroTable.clearSelection();
 611                 macroTable.addRowSelectionInterval(row, row);
 612                 macroTable.scrollRectToVisible(
 613                     macroTable.getCellRect(row, 0, false));
 614             }
 615         } 
 616     }
 617     
 618     public void setMacro(Macro m) {
 619         originalMacro = (Macro)m.clone(); // Keep a copy so we can do a reset
 620         if (mode != DUPLICATE) {
 621             name.setText(m.getKey());
 622         }
 623         macroTableModel.setMacro(m);
 624     }
 625     
 626     public void buttonPressed(int buttonId) {
 627         switch (buttonId) {
 628         case OK:
 629             // A macro with no options is not useful, so don't allow it
 630             if (macroTableModel.getRowCount() == 0) {
 631                 JOptionPane.showMessageDialog(this,
 632                     ResourceStrings.getString("empty_macro_error"),
 633                     ResourceStrings.getString("server_error_title"),
 634                     JOptionPane.ERROR_MESSAGE);
 635                 return;
 636             }
 637             try {
 638                 macroTableModel.macro.setKey(name.getText());
 639             } catch (ValidationException e) {
 640                 // Not a valid macro name
 641                 MessageFormat form = new MessageFormat(
 642                     ResourceStrings.getString("bad_macro_name"));
 643                 Object [] args = new Object[] { name.getText() };
 644                 JOptionPane.showMessageDialog(this, form.format(args),
 645                     ResourceStrings.getString("server_error_title"),
 646                     JOptionPane.ERROR_MESSAGE);
 647                 return;
 648             }
 649             try {
 650                 // Validate the macro
 651                 macroTableModel.macro.validate();
 652                 DhcptabMgr server = DataManager.get().getDhcptabMgr();
 653                 if ((mode == CREATE) || (mode == DUPLICATE)) {
 654                     server.createRecord(macroTableModel.macro,
 655                         signalBox.isSelected());
 656                 } else if (mode == EDIT) {
 657                     server.modifyRecord(originalMacro, macroTableModel.macro,
 658                         signalBox.isSelected());
 659                 }
 660                 fireActionPerformed();
 661                 setVisible(false);
 662                 dispose();
 663             } catch (ValidationException ve) {
 664                 MessageFormat form = new MessageFormat(
 665                     ResourceStrings.getString("bad_option_value"));
 666                 Object [] args = new Object[2];
 667                 OptionValue ov =
 668                     macroTableModel.macro.getOption(ve.getMessage());
 669                 if (ov == null) {
 670                     args[0] = "";
 671                 } else {
 672                     args[0] = ov.getValue();
 673                 }
 674                 args[1] = ve.getMessage();
 675                 JOptionPane.showMessageDialog(this, form.format(args),
 676                     ResourceStrings.getString("server_error_title"),
 677                     JOptionPane.ERROR_MESSAGE);
 678             } catch (NotRunningException e) {
 679                     // Server not running, put up a warning
 680                     JOptionPane.showMessageDialog(this,
 681                         ResourceStrings.getString("server_not_running"),
 682                         ResourceStrings.getString("warning"),
 683                         JOptionPane.WARNING_MESSAGE);
 684                     fireActionPerformed();
 685                     setVisible(false);
 686                     dispose();
 687             } catch (Exception e) {
 688                 MessageFormat form = null;
 689                 Object [] args = new Object[2];
 690                 switch (mode) {
 691                 case CREATE:
 692                 case DUPLICATE:
 693                     form = new MessageFormat(
 694                         ResourceStrings.getString("create_macro_error"));
 695                     args[0] = macroTableModel.macro.getKey();
 696                     break;
 697                 case EDIT:
 698                     form = new MessageFormat(
 699                         ResourceStrings.getString("edit_macro_error"));
 700                     args[0] = originalMacro.getKey();
 701                     break;
 702                 }
 703                 args[1] = e.getMessage();
 704                 JOptionPane.showMessageDialog(this, form.format(args),
 705                     ResourceStrings.getString("server_error_title"),
 706                     JOptionPane.ERROR_MESSAGE);
 707             }
 708             break;
 709         case CANCEL:
 710             setVisible(false);
 711             dispose();
 712             break;
 713         case HELP:
 714             String helpTag = null;
 715             switch (mode) {
 716             case CREATE:
 717                 helpTag = "create_macro";
 718                 break;
 719             case DUPLICATE:
 720                 helpTag = "duplicate_macro";
 721                 break;
 722             case EDIT:
 723                 helpTag = "modify_macro";
 724                 break;
 725             }
 726             DhcpmgrApplet.showHelp(helpTag);
 727             break;
 728         case RESET:
 729             setMacro(originalMacro);
 730             signalBox.setSelected(true);
 731             break;
 732         }
 733     }
 734     
 735     public void addActionListener(ActionListener l) {
 736         listeners.addElement(l);
 737     }
 738     
 739     public void removeActionListener(ActionListener l) {
 740         listeners.removeElement(l);
 741     }
 742     
 743     protected void fireActionPerformed() {
 744         String command = null;
 745         switch (mode) {
 746         case CREATE:
 747             command = DialogActions.CREATE;
 748         case DUPLICATE:
 749             command = DialogActions.DUPLICATE;
 750             break;
 751         case EDIT:
 752             command = DialogActions.EDIT;
 753             break;
 754         }
 755         ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
 756             command);
 757         Enumeration en = listeners.elements();
 758         while (en.hasMoreElements()) {
 759             ActionListener l = (ActionListener)en.nextElement();
 760             l.actionPerformed(e);
 761         }
 762     }
 763 }