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 
ClassListModel()80 	public ClassListModel() {
81 	    super();
82 	}
83 
getSize()84 	public int getSize() {
85 	    return option.getVendorCount();
86 	}
87 
getElementAt(int index)88 	public Object getElementAt(int index) {
89 	    return option.getVendorAt(index);
90 	}
91 
addElement(String v)92 	public void addElement(String v) throws ValidationException {
93 	    option.addVendor(v);
94 	    fireIntervalAdded(this, option.getVendorCount()-1,
95 		option.getVendorCount()-1);
96 	}
97 
removeElementAt(int index)98 	public void removeElementAt(int index) {
99 	    option.removeVendorAt(index);
100 	    fireIntervalRemoved(this, index, index);
101 	}
102 
moveUp(int index)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 
moveDown(int index)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 
reset()117 	public void reset() {
118 	    fireContentsChanged(this, 0, getSize());
119 	}
120     }
121 
CreateOptionDialog(Frame f, int mode)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 
setOption(Option o)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 
resetValues()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 
buttonPressed(int buttonId)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 
addActionListener(ActionListener l)688     public void addActionListener(ActionListener l) {
689 	listeners.addElement(l);
690     }
691 
removeActionListener(ActionListener l)692     public void removeActionListener(ActionListener l) {
693 	listeners.removeElement(l);
694     }
695 
fireActionPerformed()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 }
717