Mercurial > illumos > onarm
view usr/src/cmd/cmd-inet/usr.sadm/dhcpmgr/com/sun/dhcpmgr/client/AddressWizard.java @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
line wrap: on
line source
/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * ident "@(#)AddressWizard.java 1.16 05/06/08 SMI" * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ package com.sun.dhcpmgr.client; import com.sun.dhcpmgr.ui.*; import com.sun.dhcpmgr.data.*; import com.sun.dhcpmgr.bridge.BridgeException; import com.sun.dhcpmgr.bridge.NoEntryException; import com.sun.dhcpmgr.bridge.ExistsException; import com.sun.dhcpmgr.bridge.HostExistsException; import com.sun.dhcpmgr.bridge.NoTableException; import com.sun.dhcpmgr.server.DhcpNetMgr; import javax.swing.*; import javax.swing.table.*; import javax.swing.event.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.*; import java.util.*; import java.text.MessageFormat; import java.net.*; /** * A wizard to configure a group of addresses. */ public class AddressWizard extends Wizard { private Network network; private int number = 10; private String comment = ""; private String server = DataManager.get().getShortServerName(); private IPAddress serverIP; private IPAddress startAddress; private boolean generateNames = false; private String baseName = DataManager.get().getShortServerName(); private String macro = DataManager.get().getShortServerName(); private boolean unusable = false; private boolean dynamic = true; private WizardTableModel addressTableModel; private Macro noMacro; class Address { IPAddress addr; String name; public Address() { addr = null; name = ""; } public Address(int a, String n) { name = n; setAddr(a); } public Address(String a, String n) { name = n; setAddr(a); } public void setAddr(int a) { addr = new IPAddress(a); } public void setAddr(String a) { try { addr = new IPAddress(a); } catch (ValidationException e) { // Do nothing } } public String toString() { return addr.getHostAddress(); } } class WizardTableModel extends AbstractTableModel { private Vector addrs = new Vector(); public int getRowCount() { return addrs.size(); } public int getColumnCount() { return 2; } public Object getValueAt(int row, int column) { if (column == 0) { return ((Address)addrs.elementAt(row)).addr; } else { return ((Address)addrs.elementAt(row)).name; } } public Class getColumnClass(int column) { if (column == 0) { return IPAddress.class; } else { return String.class; } } public String getColumnName(int column) { if (column == 0) { return ResourceStrings.getString("address_column"); } else { return ResourceStrings.getString("client_name_column"); } } public long generateAddresses() { if (!network.containsAddress(startAddress)) { return 0; } int net = network.getAddress().intValue(); int mask = network.getMask().intValue(); int start = startAddress.intValue(); addrs.removeAllElements(); long max = (long)(net + ~mask) & 0xffffffffL; int count = 0; int index = start - net; if (index == 0) { // Don't try allocating the network address as a client address ++index; } DhcpClientRecord [] clients = null; try { /* * Sort the data so we can generate the list of addresses * with a minimal number of comparisons here. First, though, * clone the array so that sorting won't affect the original * data set and throw off the main display. */ clients = (DhcpClientRecord [])DataManager.get().getClients( network.getAddress().toString(), false).clone(); Arrays.sort(clients); } catch (Throwable e) { // XXX What to do here??? e.printStackTrace(); } int base = 0; long searchAddress = 0; while (count < number) { long address = (long)(net + index) & 0xffffffffL; if (address == max) { // We finished searching before satisfying the request break; } /* * If clients == null then this is an empty network, * so searching for holes is unnecessary */ if (clients != null) { // Advance search pointer past lower-numbered addresses while ((base < clients.length) && ((searchAddress = clients[base].getBinaryAddress()) < address)) { ++base; } } if (searchAddress != address) { // found an empty slot; create the address Address addr; if (generateNames) { addr = new Address((int)address, baseName + "-" + String.valueOf(index)); } else { addr = new Address((int)address, ""); } addrs.addElement(addr); ++count; } ++index; } // Inform UI that the data is ready. fireTableDataChanged(); return count; } public Address getAddressAt(int index) { return (Address)addrs.elementAt(index); } } // This step selects the number of addresses and a comment class NumberStep implements WizardStep { private Box stepBox; private IntegerField addressCount; private JTextField commentField; public NumberStep() { stepBox = Box.createVerticalBox(); // Explanatory text at the top stepBox.add(Wizard.createTextArea( ResourceStrings.getString("add_wiz_explain"), 4, 45)); stepBox.add(Box.createVerticalStrut(10)); stepBox.add(Box.createVerticalGlue()); // Get the number of addresses to create stepBox.add(Wizard.createTextArea( ResourceStrings.getString("add_wiz_count_explain"), 1, 45)); Mnemonic mnCount = new Mnemonic(ResourceStrings.getString("add_wiz_count_label")); JLabel label = new JLabel(mnCount.getString()); addressCount = new IntegerField(); // Ensure numeric input addressCount.setMaximumSize(addressCount.getPreferredSize()); label.setLabelFor(addressCount); label.setToolTipText(mnCount.getString()); label.setDisplayedMnemonic(mnCount.getMnemonic()); Box box = Box.createHorizontalBox(); box.add(Box.createHorizontalStrut(10)); box.add(label); box.add(Box.createHorizontalStrut(5)); box.add(addressCount); box.add(Box.createHorizontalGlue()); stepBox.add(box); stepBox.add(Box.createVerticalStrut(10)); stepBox.add(Box.createVerticalGlue()); stepBox.add(Wizard.createTextArea( ResourceStrings.getString("add_wiz_comment_explain"), 2, 45)); // Let user supply a comment Mnemonic mnComm = new Mnemonic(ResourceStrings.getString( "add_wiz_comment_label")); label = new JLabel(mnComm.getString()); commentField = new JTextField("", 20); label.setLabelFor(commentField); label.setToolTipText(mnComm.getString()); label.setDisplayedMnemonic(mnComm.getMnemonic()); commentField.setMaximumSize(commentField.getPreferredSize()); box = Box.createHorizontalBox(); box.add(Box.createHorizontalStrut(10)); box.add(label); box.add(Box.createHorizontalStrut(5)); box.add(commentField); stepBox.add(box); stepBox.add(Box.createVerticalGlue()); /* * This listener ensures that the forward button is enabled only * when there is a count of addresses in the addressCount field. */ addressCount.getDocument().addDocumentListener( new DocumentListener() { public void insertUpdate(DocumentEvent e) { setForwardEnabled(e.getDocument().getLength() != 0); } public void changedUpdate(DocumentEvent e) { insertUpdate(e); } public void removeUpdate(DocumentEvent e) { insertUpdate(e); } }); } public String getDescription() { return ResourceStrings.getString("add_wiz_number_desc"); } public Component getComponent() { return stepBox; } public void setActive(int direction) { addressCount.setValue(number); commentField.setText(comment); setForwardEnabled(addressCount.getValue() != 0); } public boolean setInactive(int direction) { number = addressCount.getValue(); if (number == 0) { /* * Going forward with 0 addresses makes no sense, * display error and veto the move. */ JOptionPane.showMessageDialog(AddressWizard.this, ResourceStrings.getString("add_wiz_count_error"), ResourceStrings.getString("error_message"), JOptionPane.ERROR_MESSAGE); return false; } comment = commentField.getText(); return true; } } // This step selects the server and starting address class ServerStep implements WizardStep { private Box stepBox; private IPAddressField startField; private HostnameField baseNameField; private JCheckBox generateNamesBox; private HostnameField serverField; public ServerStep() { stepBox = Box.createVerticalBox(); // Explanatory text at the top stepBox.add(Wizard.createTextArea( ResourceStrings.getString("add_wiz_server_explain"), 1, 45)); // Server to own these addresses Mnemonic mnMan = new Mnemonic(ResourceStrings.getString("add_wiz_server_label")); JLabel jl = new JLabel(mnMan.getString()); Box box = Box.createHorizontalBox(); box.add(jl); box.add(Box.createHorizontalStrut(5)); serverField = new HostnameField("", 15); jl.setLabelFor(serverField); jl.setToolTipText(mnMan.getString()); jl.setDisplayedMnemonic(mnMan.getMnemonic()); serverField.setMaximumSize(serverField.getPreferredSize()); box.add(serverField); box.add(Box.createHorizontalGlue()); stepBox.add(box); // Add some spacing stepBox.add(Box.createVerticalStrut(5)); stepBox.add(Box.createVerticalGlue()); // Starting address stepBox.add(Wizard.createTextArea( ResourceStrings.getString("add_wiz_start_explain"), 2, 45)); box = Box.createHorizontalBox(); Mnemonic mnStart = new Mnemonic(ResourceStrings.getString("add_wiz_start_label")); JLabel startLbl = new JLabel(mnStart.getString()); box.add(startLbl); box.add(Box.createHorizontalStrut(5)); startField = new IPAddressField(); // Ensure it's an IP address startLbl.setLabelFor(startField); startLbl.setToolTipText(mnStart.getString()); startLbl.setDisplayedMnemonic(mnStart.getMnemonic()); startField.setMaximumSize(startField.getPreferredSize()); box.add(startField); stepBox.add(box); // Add some more spacing, and an explanation of generating names stepBox.add(Box.createVerticalStrut(5)); stepBox.add(Box.createVerticalGlue()); stepBox.add(Wizard.createTextArea( ResourceStrings.getString("add_wiz_generate_explain"), 4, 45)); // Control to indicate whether names should be generated JPanel panel = new JPanel(new GridLayout(2, 1, 0, 0)); generateNamesBox = new JCheckBox( ResourceStrings.getString("add_wiz_generate_label")); generateNamesBox.setToolTipText( ResourceStrings.getString("add_wiz_generate_label")); panel.add(generateNamesBox); generateNamesBox.setEnabled(true); try { DhcpdOptions opts = DataManager.get().getDhcpServiceMgr().readDefaults(); if (opts.getHostsResource() == null) { generateNamesBox.setEnabled(false); } } catch (BridgeException e) { // Assume set } baseNameField = new HostnameField(); baseNameField.setEnabled(false); baseNameField.setMaximumSize(baseNameField.getPreferredSize()); box = Box.createHorizontalBox(); box.add(Box.createHorizontalStrut(17)); Mnemonic mnRoot = new Mnemonic(ResourceStrings.getString( "add_wiz_rootname_label")); JLabel rootNameLbl = new JLabel(mnRoot.getString()); box.add(rootNameLbl); rootNameLbl.setLabelFor(baseNameField); rootNameLbl.setToolTipText(mnRoot.getString()); rootNameLbl.setDisplayedMnemonic(mnRoot.getMnemonic()); box.add(Box.createHorizontalStrut(5)); box.add(baseNameField); panel.add(box); stepBox.add(panel); stepBox.add(Box.createVerticalGlue()); // Only enable the text input if name generation is requested generateNamesBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { baseNameField.setEnabled(generateNamesBox.isSelected()); } }); DocumentListener docListener = new DocumentListener() { public void insertUpdate(DocumentEvent e) { setForwardEnabled((startField.getText().length() != 0) && (serverField.getText().length() != 0)); } public void changedUpdate(DocumentEvent e) { insertUpdate(e); } public void removeUpdate(DocumentEvent e) { insertUpdate(e); } }; startField.getDocument().addDocumentListener(docListener); serverField.getDocument().addDocumentListener(docListener); } public String getDescription() { return ResourceStrings.getString("add_wiz_server_desc"); } public Component getComponent() { return stepBox; } public void setActive(int direction) { serverField.setText(server); startField.setValue(startAddress); baseNameField.setText(baseName); generateNamesBox.setSelected(generateNames); setForwardEnabled(true); } public boolean setInactive(int direction) { if (direction == FORWARD) { // Validate that address is on the network we're working on IPAddress a = startField.getValue(); if (a == null) { // Not a valid address at all MessageFormat form = new MessageFormat( ResourceStrings.getString("add_wiz_invalid_address")); Object [] args = new Object[1]; args[0] = startField.getText(); JOptionPane.showMessageDialog(AddressWizard.this, form.format(args), ResourceStrings.getString("input_error"), JOptionPane.ERROR_MESSAGE); return false; } else if (!network.containsAddress(a)) { // Address is not on network MessageFormat form = new MessageFormat( ResourceStrings.getString("bad_network_address")); Object [] args = new Object[2]; args[0] = startField.getText(); args[1] = network.getAddress(); JOptionPane.showMessageDialog(AddressWizard.this, form.format(args), ResourceStrings.getString("input_error"), JOptionPane.ERROR_MESSAGE); return false; } try { serverIP = new IPAddress(serverField.getText()); } catch (Throwable e) { /* * Unknown hostname, probably, so put up the message and * decline to continue */ MessageFormat form = new MessageFormat( ResourceStrings.getString("bad_server_name")); Object [] args = new Object[1]; args[0] = serverField.getText(); JOptionPane.showMessageDialog(AddressWizard.this, form.format(args), ResourceStrings.getString("error_message"), JOptionPane.ERROR_MESSAGE); return false; } } server = serverField.getText(); startAddress = startField.getValue(); generateNames = generateNamesBox.isSelected(); baseName = baseNameField.getText(); return true; } } // This step confirms the list of addresses to be generated class ConfirmStep implements WizardStep { private JPanel stepPanel; private JTable addressTable; public ConfirmStep() { stepPanel = new JPanel(new BorderLayout(10, 10)); // Explanatory text at the top stepPanel.add(Wizard.createTextArea( ResourceStrings.getString("add_wiz_confirm_explain"), 3, 45), BorderLayout.NORTH); // Label the table JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); Mnemonic mnIP = new Mnemonic(ResourceStrings.getString( "add_wiz_confirm_label")); JLabel label = new JLabel(mnIP.getString()); panel.add(label, BorderLayout.NORTH); // Display the addresses in a table addressTable = new JTable(addressTableModel); label.setLabelFor(addressTable); label.setToolTipText(mnIP.getString()); label.setDisplayedMnemonic(mnIP.getMnemonic()); addressTable.setDefaultRenderer(IPAddress.class, new ExtendedCellRenderer()); // Table is not selectable in any way addressTable.setRowSelectionAllowed(false); addressTable.setColumnSelectionAllowed(false); addressTable.setCellSelectionEnabled(false); // Wrap in a scroll pane so column headings display JScrollPane scrollPane = new JScrollPane(addressTable); panel.add(scrollPane, BorderLayout.CENTER); stepPanel.add(panel, BorderLayout.CENTER); } public String getDescription() { return ResourceStrings.getString("add_wiz_confirm_desc"); } public Component getComponent() { return stepPanel; } public void setActive(int direction) { /* * If we're activating coming from the previous step, * generate the address list */ if (direction == FORWARD) { long count = addressTableModel.generateAddresses(); // Error if no addresses could be generated if (count == 0) { JOptionPane.showMessageDialog(AddressWizard.this, ResourceStrings.getString("add_wiz_none_available"), ResourceStrings.getString("error_message"), JOptionPane.ERROR_MESSAGE); setForwardEnabled(false); } else { if (count != number) { /* * Warn if we couldn't generate the number of addresses * requested */ MessageFormat form = new MessageFormat( ResourceStrings.getString( "generate_addresses_warning")); Object [] args = new Object[2]; args[0] = new Long(count); args[1] = new Long(number); JOptionPane.showMessageDialog(AddressWizard.this, form.format(args), ResourceStrings.getString("warning"), JOptionPane.WARNING_MESSAGE); } setForwardEnabled(true); } } else { setForwardEnabled(true); } } public boolean setInactive(int direction) { return true; // Nothing to do when leaving } } // This step selects the macro and flags class ConfigureStep implements WizardStep { // Model class for the macro list class MacroListModel extends AbstractListModel implements ComboBoxModel { private Object currentValue; private Macro data[] = null; public int getSize() { if (data == null) { try { // If we don't have data yet, grab currently cached list data = DataManager.get().getMacros(false); } catch (NoTableException e) { // can function without table } catch (Throwable e) { e.printStackTrace(); } } if (data == null || data.length == 0) { return 1; } else { return data.length+1; } } public Object getElementAt(int index) { if (data == null) { try { // If we don't have data yet, grab currently cached list data = DataManager.get().getMacros(false); } catch (NoTableException e) { // can function without table } catch (Throwable e) { e.printStackTrace(); } } if (index == 0) { return noMacro.getKey(); } else { return data[index-1].getKey(); } } public void setSelectedItem(Object anItem) { currentValue = noMacro.getKey(); for (int i = 0; data != null && i < data.length; i++) { if (((String)(anItem)).equals(((Macro)data[i]).getKey())) { currentValue = anItem; } } fireContentsChanged(this, -1, -1); } public Object getSelectedItem() { return currentValue; } public Macro getMacroAt(int index) { if (index == 0) { return noMacro; } else { return data[index-1]; } } } private Box stepBox; private JComboBox macroBox; private MacroListModel macroBoxModel; private JButton viewButton; private JCheckBox unusableBox; public ConfigureStep() { stepBox = Box.createVerticalBox(); // Start with some explanatory text JComponent component = Wizard.createTextArea( ResourceStrings.getString("add_wiz_macro_explain"), 3, 45); component.setAlignmentX(Component.LEFT_ALIGNMENT); stepBox.add(component); // Add some spacing stepBox.add(Box.createVerticalStrut(10)); // Let 'em select the macro to use Mnemonic mnConf = new Mnemonic(ResourceStrings.getString("add_wiz_macro_label")); JLabel label = new JLabel(mnConf.getString()); label.setAlignmentX(Component.LEFT_ALIGNMENT); stepBox.add(label); JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); macroBoxModel = new MacroListModel(); macroBox = new JComboBox(macroBoxModel); label.setLabelFor(macroBox); label.setToolTipText(mnConf.getString()); label.setDisplayedMnemonic(mnConf.getMnemonic()); panel.add(macroBox); // Button to view the contents of the selected macro Mnemonic mnView = new Mnemonic(ResourceStrings.getString("add_wiz_view_button")); viewButton = new JButton(mnView.getString()); viewButton.setToolTipText(mnView.getString()); viewButton.setMnemonic(mnView.getMnemonic()); panel.add(viewButton); panel.setAlignmentX(Component.LEFT_ALIGNMENT); stepBox.add(panel); // Give the option to mark them unusable for now component = Wizard.createTextArea( ResourceStrings.getString("add_wiz_flag_explain"), 2, 45); component.setAlignmentX(Component.LEFT_ALIGNMENT); stepBox.add(component); unusableBox = new JCheckBox( ResourceStrings.getString("add_wiz_unusable_label")); unusableBox.setAlignmentX(Component.LEFT_ALIGNMENT); stepBox.add(unusableBox); stepBox.add(Box.createVerticalGlue()); // When user presses View, show the macro's contents viewButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { /* * viewButton is passed as component relative to which the * dialog should be displayed, keeping user more in * context with the task. */ ViewMacroDialog d = new ViewMacroDialog( AddressWizard.this, viewButton, macroBoxModel.getMacroAt(macroBox.getSelectedIndex())); d.pack(); d.setVisible(true); } }); } public String getDescription() { return ResourceStrings.getString("add_wiz_configure_desc"); } public Component getComponent() { return stepBox; } public void setActive(int direction) { macroBox.setSelectedItem(macro); unusableBox.setSelected(unusable); setForwardEnabled(true); } public boolean setInactive(int direction) { macro = (String)macroBox.getSelectedItem(); unusable = unusableBox.isSelected(); return true; } } // This step selects the lease type class LeaseStep implements WizardStep { private Box stepBox; private JRadioButton dynamicButton, permanentButton; private ButtonGroup buttonGroup; public LeaseStep() { stepBox = Box.createVerticalBox(); // Start with explanatory text JComponent component = Wizard.createTextArea( ResourceStrings.getString("add_wiz_lease_explain"), 0, 45); component.setAlignmentX(Component.LEFT_ALIGNMENT); stepBox.add(component); stepBox.add(Box.createVerticalStrut(10)); // User has choice of dynamic or permanent leases Mnemonic mnLease = new Mnemonic(ResourceStrings.getString("add_wiz_lease_label")); JLabel label = new JLabel(mnLease.getString()); JPanel panel = new JPanel(new FieldLayout(10, 0)); label.setToolTipText(mnLease.getString()); label.setDisplayedMnemonic(mnLease.getMnemonic()); panel.add(FieldLayout.LABEL, label); buttonGroup = new ButtonGroup(); dynamicButton = new JRadioButton( ResourceStrings.getString("dynamic"), true); buttonGroup.add(dynamicButton); permanentButton = new JRadioButton( ResourceStrings.getString("permanent"), false); buttonGroup.add(permanentButton); label.setLabelFor(dynamicButton); panel.add(FieldLayout.FIELD, dynamicButton); panel.add(FieldLayout.LABEL, new JLabel("")); panel.add(FieldLayout.FIELD, permanentButton); panel.setAlignmentX(Component.LEFT_ALIGNMENT); stepBox.add(panel); stepBox.add(Box.createVerticalGlue()); } public String getDescription() { return ResourceStrings.getString("add_wiz_lease_desc"); } public Component getComponent() { return stepBox; } public void setActive(int direction) { dynamicButton.setSelected(dynamic); setForwardEnabled(true); } public boolean setInactive(int direction) { dynamic = dynamicButton.isSelected(); return true; } } // Last chance to check work before committing to it class ReviewStep implements WizardStep { private Box stepBox; private JPanel panel; private JTable addressTable; private JLabel numberLabel; private JLabel commentLabel; private JLabel serverLabel; private JLabel macroLabel; private JLabel flagLabel; private JLabel leaseLabel; public ReviewStep() { stepBox = Box.createVerticalBox(); stepBox.add(Wizard.createTextArea( ResourceStrings.getString("add_wiz_review_explain"), 4, 45)); panel = new JPanel(new FieldLayout()); JLabel tmpL; tmpL = addLabelMnemonic("add_wiz_count_label"); numberLabel = addField("20"); tmpL.setLabelFor(numberLabel); tmpL = addLabelMnemonic("add_wiz_comment_label"); commentLabel = addField("Marketing"); tmpL.setLabelFor(commentLabel); tmpL = addLabelMnemonic("add_wiz_server_label"); serverLabel = addField("atlantic"); tmpL.setLabelFor(serverLabel); tmpL = addLabelMnemonic("add_wiz_macro_label"); macroLabel = addField("atlantic"); tmpL.setLabelFor(macroLabel); tmpL = addLabel("add_wiz_review_unusable"); flagLabel = addField("Yes"); tmpL.setLabelFor(flagLabel); tmpL.setToolTipText( ResourceStrings.getString("add_wiz_review_unusable")); tmpL = addLabelMnemonic("add_wiz_lease_label"); leaseLabel = addField(ResourceStrings.getString("dynamic")); tmpL.setLabelFor(leaseLabel); panel.setAlignmentX(Component.LEFT_ALIGNMENT); stepBox.add(panel); stepBox.add(Box.createVerticalStrut(5)); Mnemonic mnAdd = new Mnemonic(ResourceStrings.getString( "add_wiz_confirm_label")); JLabel label = new JLabel(mnAdd.getString()); stepBox.add(label); stepBox.add(Box.createVerticalStrut(2)); addressTable = new JTable(addressTableModel); label.setLabelFor(addressTable); label.setToolTipText(mnAdd.getString()); label.setDisplayedMnemonic(mnAdd.getMnemonic()); addressTable.setDefaultRenderer(IPAddress.class, new ExtendedCellRenderer()); // Table should not be selectable in any way addressTable.setRowSelectionAllowed(false); addressTable.setColumnSelectionAllowed(false); addressTable.setCellSelectionEnabled(false); JScrollPane scrollPane = new JScrollPane(addressTable); Dimension d = addressTable.getPreferredScrollableViewportSize(); d.height = 50; addressTable.setPreferredScrollableViewportSize(d); stepBox.add(scrollPane); stepBox.add(Box.createVerticalGlue()); } private JLabel addLabel(String s) { JLabel l = new JLabel(ResourceStrings.getString(s)); panel.add(FieldLayout.LABEL, l); return l; } private JLabel addLabelMnemonic(String s) { Mnemonic mnStr = new Mnemonic(ResourceStrings.getString(s)); JLabel l = new JLabel(mnStr.getString()); l.setToolTipText(mnStr.getString()); panel.add(FieldLayout.LABEL, l); return l; } private JLabel addField(String s) { JLabel l = new JLabel(s); l.setForeground(Color.black); panel.add(FieldLayout.FIELD, l); return l; } public String getDescription() { return ResourceStrings.getString("add_wiz_review_desc"); } public Component getComponent() { return stepBox; } public void setActive(int direction) { // Use number of addresses actually generated, not requested numberLabel.setText( String.valueOf(addressTableModel.getRowCount())); commentLabel.setText(comment); serverLabel.setText(server); macroLabel.setText(macro); if (unusable) { flagLabel.setText(ResourceStrings.getString("yes")); } else { flagLabel.setText(ResourceStrings.getString("no")); } if (dynamic) { leaseLabel.setText(ResourceStrings.getString("dynamic")); } else { leaseLabel.setText(ResourceStrings.getString("permanent")); } setFinishEnabled(true); } public boolean setInactive(int direction) { // Nothing to do return true; } } public AddressWizard(Frame owner, Network net) { super(owner, ""); setTitle(MessageFormat.format( ResourceStrings.getString("address_wizard_title"), net.toString())); network = net; startAddress = network.getAddress(); try { noMacro = new Macro(ResourceStrings.getString("no_macro_item")); } catch (ValidationException e) { // this should never happen! System.err.println(e.getMessage()); } addressTableModel = new WizardTableModel(); // Create steps in order of appearance addStep(new NumberStep()); addStep(new ServerStep()); addStep(new ConfirmStep()); addStep(new ConfigureStep()); addStep(new LeaseStep()); addStep(new ReviewStep()); showFirstStep(); } public void doFinish() { /* * Method here is as follows: * 1. Create a ProgressManager which will apprise user of our progress * 2. Create a background thread to execute the add operations * 3. Within the background thread, update the progress monitor * as each address is created. * 4. At completion, the background thread displays the error * output, if any, before it invokes one last runnable which pops * down and cleans up. */ // final so that ProgressUpdater can access it final ProgressManager progress = new ProgressManager(this, ResourceStrings.getString("add_wiz_progress"), "", 0, addressTableModel.getRowCount()); final Runnable finisher = new Runnable() { public void run() { reallyFinish(); } }; // Here's the thread which does the adds Thread addThread = new Thread() { public void run() { DhcpNetMgr server = DataManager.get().getDhcpNetMgr(); // Create a template object which we'll use for all the adds DhcpClientRecord rec = new DhcpClientRecord(); rec.setExpiration(new Date(0)); rec.setUnusable(unusable); rec.setPermanent(!dynamic); try { rec.setServerIP(serverIP); } catch (ValidationException e) { // Should never happen as we have a valid IP already } if (macro.equals(noMacro.getKey())) { rec.setMacro(""); } else { rec.setMacro(macro); } rec.setComment(comment); // This is final so it can be used in the errorDisplay Runnable final ErrorTable failedTable = new ErrorTable( ResourceStrings.getString("address_column"), IPAddress.class); /* * For each address, create a client record and possibly a * hosts record, log any errors for later consumption. */ for (int i = 0; i < addressTableModel.getRowCount(); ++i) { Address addr = addressTableModel.getAddressAt(i); try { rec.setClientIP(addr.addr); rec.setClientName(addr.name); server.addClient(rec, network.toString()); progress.update(i+1, addr.addr.toString()); } catch (InterruptedException e) { SwingUtilities.invokeLater(finisher); return; } catch (Throwable e) { // Pick the best message for the exception thrown String msg; if (e instanceof ExistsException) { msg = ResourceStrings.getString("address_exists"); } else if (e instanceof HostExistsException) { msg = ResourceStrings.getString("host_exists"); } else { msg = e.getMessage(); } failedTable.addError(addr.addr, msg); } } // If any errors occurred, display them all at once. if (!failedTable.isEmpty()) { Runnable errorDisplay = new Runnable() { public void run() { Object [] objs = new Object[2]; objs[0] = ResourceStrings.getString("add_wiz_error"); JScrollPane scrollPane = new JScrollPane(failedTable); // Resize the table to something kind of small Dimension d = failedTable. getPreferredScrollableViewportSize(); d.height = 80; failedTable.setPreferredScrollableViewportSize(d); objs[1] = scrollPane; JOptionPane.showMessageDialog(AddressWizard.this, objs, ResourceStrings.getString("server_error_title"), JOptionPane.ERROR_MESSAGE); } }; try { SwingUtilities.invokeAndWait(errorDisplay); } catch (Throwable e) { e.printStackTrace(); } } SwingUtilities.invokeLater(finisher); } }; addThread.start(); } protected void reallyFinish() { super.doFinish(); } public void doHelp() { DhcpmgrApplet.showHelp("address_wizard"); } }