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 1998-2002 by 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 /**
  47  * Dialog to create/duplicate/edit an option.
  48  */
  49 public class CreateOptionDialog extends JDialog implements ButtonPanelListener {
  50     public static final int CREATE = 0;
  51     public static final int EDIT = 1;
  52     public static final int DUPLICATE = 2;
  53     
  54     private int mode = CREATE;
  55     private OptionNameField name;
  56     private JComboBox category;
  57     private IntegerField code;
  58     private JComboBox type;
  59     private JList classList;
  60     private JTextField clientClass;
  61     private IntegerField granularity;
  62     private IntegerField maximum;
  63     private JCheckBox signalBox;
  64     private Vector listeners;
  65     private Option option, originalOption;
  66     private ButtonPanel buttonPanel;
  67     private ClassListModel classListModel;
  68     private JButton add, delete;
  69     private UpButton moveUp;
  70     private DownButton moveDown;
  71     private OptionContext [] categories = {
  72         Option.ctxts[Option.EXTEND],
  73         Option.ctxts[Option.VENDOR],
  74         Option.ctxts[Option.SITE]
  75     };
  76     
  77     // Model for the list of vendor classes
  78     class ClassListModel extends AbstractListModel {
  79     
  80         public ClassListModel() {
  81             super();
  82         }
  83         
  84         public int getSize() {
  85             return option.getVendorCount();
  86         }
  87         
  88         public Object getElementAt(int index) {
  89             return option.getVendorAt(index);
  90         }
  91 
  92         public void addElement(String v) throws ValidationException {
  93             option.addVendor(v);
  94             fireIntervalAdded(this, option.getVendorCount()-1,
  95                 option.getVendorCount()-1);
  96         }
  97         
  98         public void removeElementAt(int index) {
  99             option.removeVendorAt(index);
 100             fireIntervalRemoved(this, index, index);
 101         }
 102         
 103         public void moveUp(int index) {
 104             String t = (String)option.getVendorAt(index-1);
 105             option.setVendorAt(option.getVendorAt(index), index-1);
 106             option.setVendorAt(t, index);
 107             fireContentsChanged(this, index-1, index);
 108         }
 109         
 110         public void moveDown(int index) {
 111             String t = (String)option.getVendorAt(index+1);
 112             option.setVendorAt(option.getVendorAt(index), index+1);
 113             option.setVendorAt(t, index);
 114             fireContentsChanged(this, index, index+1);
 115         }
 116         
 117         public void reset() {
 118             fireContentsChanged(this, 0, getSize());
 119         }
 120     }   
 121 
 122     public CreateOptionDialog(Frame f, int mode) {
 123         super(f);
 124         setLocationRelativeTo(f);
 125         JPanel classPanel;
 126 
 127         listeners = new Vector();
 128         
 129         this.mode = mode;
 130         switch (mode) {
 131         case CREATE:
 132             setTitle(ResourceStrings.getString("create_option_title"));
 133             break;
 134         case EDIT:
 135             setTitle(ResourceStrings.getString("edit_option_title"));
 136             break;
 137         case DUPLICATE:
 138             setTitle(ResourceStrings.getString("duplicate_option_title"));
 139             break;
 140         default:
 141             break;
 142         }
 143         
 144         getContentPane().setLayout(new BoxLayout(getContentPane(),
 145             BoxLayout.Y_AXIS));
 146         
 147         JPanel mainPanel = new JPanel(new BorderLayout());
 148         mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
 149         
 150         JPanel fieldPanel = new JPanel();
 151         GridBagLayout bag = new GridBagLayout();
 152         fieldPanel.setLayout(bag);
 153 
 154         // Initialize constraints
 155         GridBagConstraints c = new GridBagConstraints();
 156         c.gridx = c.gridy = 0;
 157         c.gridwidth = c.gridheight = 1;
 158         c.fill = GridBagConstraints.HORIZONTAL;
 159         c.insets = new Insets(5, 5, 5, 5);
 160         c.weightx = c.weighty = 1.0;
 161 
 162         // Label and text field for name
 163         Mnemonic mnOname =
 164             new Mnemonic(ResourceStrings.getString("op_name"));
 165         JLabel l = new JLabel(mnOname.getString(), SwingConstants.RIGHT);
 166 
 167         bag.setConstraints(l, c);
 168         fieldPanel.add(l);
 169         name = new OptionNameField("");
 170 
 171         l.setLabelFor(name);
 172         l.setToolTipText(mnOname.getString());
 173         l.setDisplayedMnemonic(mnOname.getMnemonic());
 174 
 175         l.setLabelFor(name);
 176         ++c.gridx;
 177         bag.setConstraints(name, c);
 178         fieldPanel.add(name);
 179         
 180         // Label and combo box for category
 181         Mnemonic mnCat =
 182             new Mnemonic(ResourceStrings.getString("category_label"));
 183         l = new JLabel(mnCat.getString(), SwingConstants.RIGHT);
 184 
 185         c.gridx = 0;
 186         ++c.gridy;
 187         bag.setConstraints(l, c);
 188         fieldPanel.add(l);
 189         category = new JComboBox(categories);
 190 
 191         l.setLabelFor(category);
 192         l.setToolTipText(mnCat.getString());
 193         l.setDisplayedMnemonic(mnCat.getMnemonic());
 194 
 195         category.setEditable(false);
 196         ++c.gridx;
 197         bag.setConstraints(category, c);
 198         fieldPanel.add(category);
 199         
 200         // Label and text field for code
 201         Mnemonic mnCode =
 202             new Mnemonic(ResourceStrings.getString("option_code_label"));
 203         l = new JLabel(mnCode.getString(), SwingConstants.RIGHT);
 204 
 205         c.gridx = 0;
 206         ++c.gridy;
 207         bag.setConstraints(l, c);
 208         fieldPanel.add(l);
 209         code = new IntegerField();
 210 
 211         l.setLabelFor(code);
 212         l.setToolTipText(mnCode.getString());
 213         l.setDisplayedMnemonic(mnCode.getMnemonic());
 214 
 215         ++c.gridx;
 216         bag.setConstraints(code, c);
 217         fieldPanel.add(code);
 218         
 219         // Label and combo box for data type
 220         Mnemonic mnType =
 221             new Mnemonic(ResourceStrings.getString("data_type_label"));
 222         l = new JLabel(mnType.getString(), SwingConstants.RIGHT);
 223 
 224         c.gridx = 0;
 225         ++c.gridy;
 226         bag.setConstraints(l, c);
 227         fieldPanel.add(l);
 228         type = new JComboBox(Option.types);
 229 
 230         l.setLabelFor(type);
 231         l.setToolTipText(mnType.getString());
 232         l.setDisplayedMnemonic(mnType.getMnemonic());
 233 
 234         type.setEditable(false);
 235         ++c.gridx;
 236         bag.setConstraints(type, c);
 237         fieldPanel.add(type);
 238         
 239         // Label and text field for granularity
 240         Mnemonic mnGran =
 241             new Mnemonic(ResourceStrings.getString("granularity_label"));
 242         l = new JLabel(mnGran.getString(), SwingConstants.RIGHT);
 243 
 244         c.gridx = 0;
 245         ++c.gridy;
 246         bag.setConstraints(l, c);
 247         fieldPanel.add(l);
 248         granularity = new IntegerField(5);
 249 
 250         l.setLabelFor(granularity);
 251         l.setToolTipText(mnGran.getString());
 252         l.setDisplayedMnemonic(mnGran.getMnemonic());
 253 
 254         ++c.gridx;
 255         bag.setConstraints(granularity, c);
 256         fieldPanel.add(granularity);
 257         
 258         // Label and text field for maximum
 259         Mnemonic mnMax =
 260             new Mnemonic(ResourceStrings.getString("maximum_label"));
 261         l = new JLabel(mnMax.getString(), SwingConstants.RIGHT);
 262 
 263         c.gridx = 0;
 264         ++c.gridy;
 265         bag.setConstraints(l, c);
 266         fieldPanel.add(l);
 267         maximum = new IntegerField(5);
 268 
 269         l.setLabelFor(maximum);
 270         l.setToolTipText(mnMax.getString());
 271         l.setDisplayedMnemonic(mnMax.getMnemonic());
 272 
 273         ++c.gridx;
 274         bag.setConstraints(maximum, c);
 275         fieldPanel.add(maximum);
 276         
 277         mainPanel.add(fieldPanel, BorderLayout.WEST);
 278         
 279         // Editing controls for client classes
 280         bag = new GridBagLayout();
 281         classPanel = new JPanel(bag);
 282         Border tb = BorderFactory.createTitledBorder(
 283             BorderFactory.createLineBorder(Color.black),
 284             ResourceStrings.getString("client_classes_label"));
 285         classPanel.setBorder(BorderFactory.createCompoundBorder(tb,
 286             BorderFactory.createEmptyBorder(5, 5, 5, 5)));
 287         
 288         c = new GridBagConstraints();
 289         c.gridx = c.gridy = 0;
 290         c.weightx = c.weighty = 1.0;
 291         c.gridheight = 1;
 292         c.gridwidth = 1;
 293         
 294         // Field to type in new classes
 295         clientClass = new JTextField("", 20);
 296         c.fill = GridBagConstraints.HORIZONTAL;
 297         bag.setConstraints(clientClass, c);
 298         classPanel.add(clientClass);
 299 
 300         // Button for Add operation
 301         Mnemonic mnAdd = 
 302             new Mnemonic(ResourceStrings.getString("add"));
 303         add = new JButton(mnAdd.getString());
 304         add.setToolTipText(mnAdd.getString());
 305         add.setMnemonic(mnAdd.getMnemonic());
 306 
 307         c.fill = GridBagConstraints.NONE;
 308         ++c.gridx;
 309         c.weightx = 0.5;
 310         bag.setConstraints(add, c);
 311         classPanel.add(add);
 312         
 313         // List for classes
 314         classListModel = new ClassListModel();
 315         classList = new JList(classListModel);
 316 
 317         // Make sure it's approximately wide enough for our purposes, 20 chars
 318         classList.setPrototypeCellValue("abcdefghijklmnopqrst");
 319         classList.setSelectionMode(
 320             ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 321         JScrollPane scrollPane = new JScrollPane(classList);
 322         c.fill = GridBagConstraints.BOTH;
 323         c.gridx = 0;
 324         ++c.gridy;
 325         c.weightx = 1.0;
 326         bag.setConstraints(scrollPane, c);
 327         classPanel.add(scrollPane);
 328         
 329         // Buttons to manipulate the list contents
 330         JPanel editButtonPanel = new JPanel(new VerticalButtonLayout());
 331         moveUp = new UpButton();
 332         editButtonPanel.add(moveUp);
 333         moveDown = new DownButton();
 334         editButtonPanel.add(moveDown);
 335 
 336         Mnemonic mnDelete = 
 337             new Mnemonic(ResourceStrings.getString("delete"));
 338         delete = new JButton(mnDelete.getString());
 339         delete.setToolTipText(mnDelete.getString());
 340         delete.setMnemonic(mnDelete.getMnemonic());
 341 
 342         editButtonPanel.add(delete);
 343         ++c.gridx;
 344         c.weightx = 0.5;
 345         bag.setConstraints(editButtonPanel, c);
 346         classPanel.add(editButtonPanel);
 347         
 348         /*
 349          * Disable all buttons to start; selection changes will adjust button
 350          * state as necessary
 351          */
 352         add.setEnabled(false);
 353         delete.setEnabled(false);
 354         moveUp.setEnabled(false);
 355         moveDown.setEnabled(false);
 356         
 357         // Create listener for button presses, take action as needed
 358         ActionListener al = new ActionListener() {
 359             public void actionPerformed(ActionEvent e) {
 360                 if (e.getSource() == add || e.getSource() == clientClass) {
 361                     try {
 362                         classListModel.addElement(clientClass.getText());
 363                     } catch (ValidationException ex) {
 364                         // Something wrong with class name
 365                         MessageFormat form = new MessageFormat(
 366                             ResourceStrings.getString("invalid_client_class"));
 367                         Object [] args = new Object[] { clientClass.getText() };
 368                         JOptionPane.showMessageDialog(CreateOptionDialog.this,
 369                             form.format(args),
 370                             ResourceStrings.getString("input_error"),
 371                             JOptionPane.ERROR_MESSAGE);
 372                         return;
 373                     }
 374                 } else if (e.getSource() == delete) {
 375                     int [] indices = classList.getSelectedIndices();
 376                     if (indices.length > 1) {
 377                         /*
 378                          * Need to sort them so that the delete's don't
 379                          * interfere with each other
 380                          */
 381                         for (int i = 0; i < indices.length; ++i) {
 382                             for (int j = i; j < indices.length; ++j) {
 383                                 if (indices[i] > indices[j]) {
 384                                     int k = indices[i];
 385                                     indices[i] = indices[j];
 386                                     indices[j] = k;
 387                                 }
 388                             }
 389                         }
 390                     }
 391                     // Now delete from high index to low
 392                     for (int i = indices.length - 1; i >= 0; --i) {
 393                         classListModel.removeElementAt(indices[i]);
 394                     }
 395                     if (indices.length > 1) {
 396                         // Clear selection if multiple deleted
 397                         classList.clearSelection();
 398                         /*
 399                          * XXX We don't get a selection event for some reason,
 400                          * make it work for now
 401                          */
 402                         delete.setEnabled(false);
 403                     } else {
 404                         // Make sure to select something in the list
 405                         if (classListModel.getSize() == 0) {
 406                             // List is empty, so disable delete
 407                             delete.setEnabled(false);
 408                         } else if (indices[0] >= classListModel.getSize()) {
 409                             // Select last one if we're off the end
 410                             classList.setSelectedIndex(
 411                                 classListModel.getSize()-1);
 412                         } else {
 413                             // Select next one in list
 414                             classList.setSelectedIndex(indices[0]);
 415                         }
 416                     }
 417                 } else if (e.getSource() == moveUp) {
 418                     int i = classList.getSelectedIndex();
 419                     classListModel.moveUp(i);
 420                     // Keep item selected so repeated moveUp's affect same item
 421                     classList.setSelectedIndex(i-1);
 422                 } else if (e.getSource() == moveDown) {
 423                     int i = classList.getSelectedIndex();
 424                     classListModel.moveDown(i);
 425                     // Keep item selected so repeated moveDowns affect same item
 426                     classList.setSelectedIndex(i+1);
 427                 }
 428             }
 429         };
 430         clientClass.addActionListener(al);
 431         add.addActionListener(al);
 432         delete.addActionListener(al);
 433         moveUp.addActionListener(al);
 434         moveDown.addActionListener(al);
 435         
 436         // Put a selection listener on the list to enable buttons appropriately
 437         classList.addListSelectionListener(new ListSelectionListener() {
 438             public void valueChanged(ListSelectionEvent e) {
 439                 int [] indices = classList.getSelectedIndices();
 440                 switch (indices.length) {
 441                 case 0:
 442                     // Nothing selected; disable them all
 443                     delete.setEnabled(false);
 444                     moveUp.setEnabled(false);
 445                     moveDown.setEnabled(false);
 446                     break;
 447                 case 1:
 448                     delete.setEnabled(true);
 449                     // Can't move first one up
 450                     moveUp.setEnabled(indices[0] != 0);
 451                     // Can't move last one down
 452                     if (indices[0] == (classListModel.getSize() - 1)) {
 453                         moveDown.setEnabled(false);
 454                     } else {
 455                         moveDown.setEnabled(true);
 456                     }
 457                     break;
 458                 default:
 459                     // More than one; only delete is allowed
 460                     delete.setEnabled(true);
 461                     moveUp.setEnabled(false);
 462                     moveDown.setEnabled(false);
 463                 }
 464             }
 465         });
 466         // Enable Add when class is not empty.
 467         clientClass.getDocument().addDocumentListener(new DocumentListener() {
 468             public void insertUpdate(DocumentEvent e) {
 469                 add.setEnabled(clientClass.getText().length() != 0);
 470             }
 471             public void changedUpdate(DocumentEvent e) {
 472                 insertUpdate(e);
 473             }
 474             public void removeUpdate(DocumentEvent e) {
 475                 insertUpdate(e);
 476             }
 477         });
 478 
 479         mainPanel.add(classPanel, BorderLayout.CENTER);
 480         
 481         signalBox = new JCheckBox(ResourceStrings.getString("signal_server"),
 482             true);
 483         signalBox.setToolTipText(
 484             ResourceStrings.getString("signal_server"));
 485         signalBox.setHorizontalAlignment(SwingConstants.CENTER);
 486         JPanel signalPanel = new JPanel();
 487         signalPanel.add(signalBox);
 488         mainPanel.add(signalPanel, BorderLayout.SOUTH);
 489         
 490         getContentPane().add(mainPanel);
 491         getContentPane().add(new JSeparator());
 492         
 493         buttonPanel = new ButtonPanel(true);
 494         buttonPanel.addButtonPanelListener(this);
 495         getContentPane().add(buttonPanel);
 496         
 497         setOption(new Option());
 498         
 499         if (mode == EDIT) {
 500             buttonPanel.setOkEnabled(true);
 501         }
 502 
 503         // Enable OK when there is data in the name field
 504         name.getDocument().addDocumentListener(new DocumentListener() {
 505             public void insertUpdate(DocumentEvent e) {
 506                 buttonPanel.setOkEnabled(e.getDocument().getLength() != 0);
 507             }
 508             public void changedUpdate(DocumentEvent e) {
 509                 insertUpdate(e);
 510             }
 511             public void removeUpdate(DocumentEvent e) {
 512                 insertUpdate(e);
 513             }
 514         });
 515         
 516         // If category != VENDOR you can't mess with the client class data
 517         category.addItemListener(new ItemListener() {
 518             public void itemStateChanged(ItemEvent e) {
 519                 OptionContext ctxt = categories[category.getSelectedIndex()];
 520                 boolean isVendor =
 521                     (ctxt.getCode() == Option.ctxts[Option.VENDOR].getCode());
 522                 if (!isVendor) {
 523                     option.clearVendors();
 524                     clientClass.setText("");
 525                 }
 526                 clientClass.setEnabled(isVendor);
 527                 classList.setEnabled(isVendor);         
 528             }
 529         });
 530         
 531         // Update state of granularity & maximum depending on data type selected
 532         type.addItemListener(new ItemListener() {
 533             public void itemStateChanged(ItemEvent e) {
 534                 OptionType stype = Option.types[type.getSelectedIndex()];
 535                 byte code = stype.getCode();
 536                 // Set granularity to correct minimum for type
 537                 if (code == Option.types[Option.BOOLEAN].getCode()) {
 538                     granularity.setText("0");
 539                 } else if ("0".equals(granularity.getText())) {
 540                     granularity.setText("1");
 541                 }
 542                 // Now set editability of the granularity and max fields
 543                 if (code == Option.types[Option.ASCII].getCode() ||
 544                     code == Option.types[Option.OCTET].getCode()) {
 545                     granularity.setEditable(false);
 546                     maximum.setEditable(true);
 547                 } else if (code == Option.types[Option.BOOLEAN].getCode()) {
 548                     granularity.setEditable(false);
 549                     // Also reset maximum value in this case
 550                     maximum.setText("0");
 551                     maximum.setEditable(false);
 552                 } else if (code == Option.types[Option.NUMBER].getCode() ||
 553                     code == Option.types[Option.UNUMBER8].getCode() ||
 554                     code == Option.types[Option.UNUMBER16].getCode() ||
 555                     code == Option.types[Option.UNUMBER32].getCode() ||
 556                     code == Option.types[Option.UNUMBER64].getCode() ||
 557                     code == Option.types[Option.SNUMBER8].getCode() ||
 558                     code == Option.types[Option.SNUMBER16].getCode() ||
 559                     code == Option.types[Option.SNUMBER32].getCode() ||
 560                     code == Option.types[Option.SNUMBER64].getCode() ||
 561                     code == Option.types[Option.IP].getCode()) {
 562                     granularity.setEditable(true);
 563                     maximum.setEditable(true);
 564                 }
 565             }
 566         });
 567     }
 568     
 569     public void setOption(Option o) {
 570         originalOption = o; // Keep a copy so reset will work
 571         option = (Option)o.clone();
 572         resetValues();
 573     }
 574     
 575     private void resetValues() {
 576         if (mode == DUPLICATE) {
 577             name.setText("");
 578         } else {
 579             name.setText(option.getKey());
 580         }
 581         for (int i = 0; i < categories.length; i++) {
 582             if (categories[i].getCode() == option.getContext()) {
 583                 category.setSelectedIndex(i);
 584                 break;
 585             }
 586         }
 587 
 588         for (int i = 0; i < Option.types.length; i++) {
 589             if (Option.types[i].getCode() == option.getType()) {
 590                 type.setSelectedIndex(i);
 591                 break;
 592             }
 593         }
 594 
 595         code.setValue(option.getCode());
 596         granularity.setValue(option.getGranularity());
 597         maximum.setValue(option.getMaximum());
 598         classListModel.reset();
 599         signalBox.setSelected(true);
 600     }
 601     
 602     public void buttonPressed(int buttonId) {
 603         switch (buttonId) {
 604         case OK:
 605             try {
 606                 OptionContext sctxt = categories[category.getSelectedIndex()];
 607                 OptionType stype = Option.types[type.getSelectedIndex()];
 608                 option.setKey(name.getText());
 609                 option.setContext(sctxt.getCode());
 610                 option.setCode((short)code.getValue());
 611                 option.setType(stype.getCode());
 612                 option.setGranularity(granularity.getValue());
 613                 option.setMaximum(maximum.getValue());
 614                 if (sctxt.getCode() == Option.ctxts[Option.VENDOR].getCode() &&
 615                         option.getVendorCount() == 0) {
 616                     JOptionPane.showMessageDialog(this,
 617                         ResourceStrings.getString("empty_vendor_error"),
 618                         ResourceStrings.getString("server_error_title"),
 619                         JOptionPane.ERROR_MESSAGE);
 620                     return;
 621                 }
 622                 DhcptabMgr server = DataManager.get().getDhcptabMgr();
 623                 if ((mode == CREATE) || (mode == DUPLICATE)) {
 624                     server.createRecord(option, signalBox.isSelected());
 625                 } else if (mode == EDIT) {
 626                     server.modifyRecord(originalOption, option,
 627                         signalBox.isSelected());
 628                 }
 629                 fireActionPerformed();
 630                 setVisible(false);
 631                 dispose();
 632             } catch (NotRunningException e) {
 633                 // Server not running, put up a warning
 634                 JOptionPane.showMessageDialog(this,
 635                     ResourceStrings.getString("server_not_running"),
 636                     ResourceStrings.getString("warning"),
 637                     JOptionPane.WARNING_MESSAGE);
 638                 fireActionPerformed();
 639                 setVisible(false);
 640                 dispose();
 641             } catch (Exception e) {
 642                 MessageFormat form = null;
 643                 Object [] args = new Object[2];
 644                 switch (mode) {
 645                 case CREATE:
 646                 case DUPLICATE:
 647                     form = new MessageFormat(
 648                         ResourceStrings.getString("create_option_error"));
 649                     args[0] = option.getKey();
 650                     break;
 651                 case EDIT:
 652                     form = new MessageFormat(
 653                         ResourceStrings.getString("edit_option_error"));
 654                     args[0] = originalOption.getKey();
 655                     break;
 656                 }
 657                 args[1] = e.getMessage();
 658                 JOptionPane.showMessageDialog(this, form.format(args),
 659                     ResourceStrings.getString("server_error_title"),
 660                     JOptionPane.ERROR_MESSAGE);
 661             }
 662             break;
 663         case CANCEL:
 664             setVisible(false);
 665             dispose();
 666             break;
 667         case HELP:
 668             String helpTag = null;
 669             switch (mode) {
 670             case CREATE:
 671                 helpTag = "create_option";
 672                 break;
 673             case DUPLICATE:
 674                 helpTag = "duplicate_option";
 675                 break;
 676             case EDIT:
 677                 helpTag = "modify_option";
 678                 break;
 679             }
 680             DhcpmgrApplet.showHelp(helpTag);
 681             break;
 682         case RESET:
 683             setOption(originalOption);
 684             break;
 685         }
 686     }
 687     
 688     public void addActionListener(ActionListener l) {
 689         listeners.addElement(l);
 690     }
 691     
 692     public void removeActionListener(ActionListener l) {
 693         listeners.removeElement(l);
 694     }
 695     
 696     protected void fireActionPerformed() {
 697         String command = null;
 698         switch (mode) {
 699         case CREATE:
 700             command = DialogActions.CREATE;
 701         case DUPLICATE:
 702             command = DialogActions.DUPLICATE;
 703             break;
 704         case EDIT:
 705             command = DialogActions.EDIT;
 706             break;
 707         }
 708         ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
 709             command);
 710         Enumeration en = listeners.elements();
 711         while (en.hasMoreElements()) {
 712             ActionListener l = (ActionListener)en.nextElement();
 713             l.actionPerformed(e);
 714         }
 715     }
 716 }