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 2005 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.event.*; 32 import javax.swing.table.*; 33 import java.awt.*; 34 import java.awt.event.*; 35 import java.util.*; 36 import java.text.*; 37 import java.net.*; 38 39 import com.sun.dhcpmgr.ui.*; 40 import com.sun.dhcpmgr.server.*; 41 import com.sun.dhcpmgr.data.*; 42 import com.sun.dhcpmgr.bridge.BridgeException; 43 import com.sun.dhcpmgr.bridge.NoEntryException; 44 45 /** 46 * Address View displays the networks currently under DHCP management, and 47 * as a network is selected from the list its addresses are displayed. 48 */ 49 public class AddressView implements View { 50 private JPanel displayPanel; 51 protected static AutosizingTable addressTable; 52 private JScrollPane addressPane; 53 private boolean firstActivation = true; 54 private NetworkListModel networkListModel; 55 private JList networkList; 56 protected static AddressTableModel addressTableModel = null; 57 private TableSorter sortedTableModel; 58 private JCheckBoxMenuItem showGrid; 59 private JCheckBoxMenuItem showAddresses; 60 private JMenuItem addAddrs; 61 private JMenuItem releaseAddrs; 62 private JMenuItem addNet; 63 private JMenuItem deleteNets; 64 private JMenuItem addressHelp; 65 private Vector[] menuItems; 66 private Frame myFrame; 67 private Vector selectionListeners = new Vector(); 68 private int sortModelIndex = -1; 69 private static final String NO_NETWORKS = 70 ResourceStrings.getString("no_networks"); 71 72 // Model class for the network list 73 class NetworkListModel extends AbstractListModel { 74 private Object currentValue; 75 private Network data[] = null; 76 77 public void load() { 78 try { 79 MainFrame.setStatusText( 80 ResourceStrings.getString("loading_networks")); 81 data = DataManager.get().getNetworks(true); 82 } catch (Throwable e) { 83 e.printStackTrace(); 84 } finally { 85 int len = 0; 86 if (data != null) { 87 len = data.length; 88 } 89 MainFrame.setStatusText( 90 MessageFormat.format( 91 ResourceStrings.getString("networks_loaded"), len)); 92 } 93 } 94 95 public void reload() { 96 load(); 97 fireContentsChanged(this, -1, -1); 98 } 99 100 public int getSize() { 101 if (data == null) { 102 load(); 103 } 104 if (data == null) { 105 return 0; 106 } else { 107 return data.length; 108 } 109 } 110 111 public Object getElementAt(int index) { 112 if (data == null) { 113 load(); 114 } 115 if (data == null || index >= data.length) { 116 return ""; 117 } else { 118 return data[index].toString(); 119 } 120 } 121 122 public Network getNetworkAt(int index) { 123 if (data == null || index >= data.length) { 124 return null; 125 } else { 126 return data[index]; 127 } 128 } 129 } 130 131 // Container class for the address data 132 class AddressTableModel extends AbstractTableModel { 133 private DhcpClientRecord [] data; 134 private String network; 135 private boolean showAddresses; 136 private boolean firstLoad; 137 138 public AddressTableModel() { 139 data = null; 140 network = ""; 141 showAddresses = false; 142 firstLoad = true; 143 } 144 145 public void load(String network) { 146 data = null; 147 fireTableDataChanged(); 148 if (network.length() == 0) { 149 // No network number supplied, so can't load 150 return; 151 } 152 this.network = network; 153 154 // Update the status line 155 Object [] objs = {network}; 156 String s = MessageFormat.format( 157 ResourceStrings.getString("loading_addresses"), objs); 158 MainFrame.setStatusText(s); 159 160 // Kick off background loading of addresses 161 AddressLoader loader = new AddressLoader(); 162 163 } 164 165 // Loading is done, re-sort and tell the view to repaint 166 protected void doneLoading() { 167 sortedTableModel.reallocateIndexes(); 168 if (firstLoad) { 169 sortedTableModel.sortByColumn(0); 170 firstLoad = false; 171 } 172 fireTableDataChanged(); 173 } 174 175 protected String getNetwork() { 176 return network; 177 } 178 179 protected void setData(DhcpClientRecord [] newdata) { 180 data = newdata; 181 } 182 183 public void setShowAddresses(boolean state) { 184 showAddresses = state; 185 fireTableStructureChanged(); 186 sortedTableModel.sortByColumn(sortModelIndex); 187 } 188 189 public int getRowCount() { 190 if (data == null) { 191 return 0; 192 } else { 193 return data.length; 194 } 195 } 196 197 public int getColumnCount() { 198 return 7; 199 } 200 201 public Object getValueAt(int row, int column) { 202 switch (column) { 203 case 0: 204 if (showAddresses) { 205 return data[row].getClientIP(); 206 } else { 207 return data[row].getClientName(); 208 } 209 case 1: 210 if (data[row].isUnusable()) { 211 return ResourceStrings.getString("unusable"); 212 } else if (data[row].isBootp()) { 213 return ResourceStrings.getString("bootp"); 214 } else if (data[row].isManual()) { 215 return ResourceStrings.getString("manual"); 216 } else if (data[row].isPermanent()) { 217 return ResourceStrings.getString("permanent"); 218 } else { 219 return ResourceStrings.getString("dynamic"); 220 } 221 case 2: 222 return data[row].getExpiration(); 223 case 3: 224 if (showAddresses) { 225 return data[row].getServerIP(); 226 } else { 227 return data[row].getServerName(); 228 } 229 case 4: 230 return data[row].getMacro(); 231 case 5: 232 return data[row].getClientId(); 233 case 6: 234 return data[row].getComment(); 235 default: 236 return null; 237 } 238 } 239 240 public Class getColumnClass(int column) { 241 switch (column) { 242 case 0: 243 case 3: 244 if (showAddresses) { 245 return IPAddress.class; 246 } else { 247 return String.class; 248 } 249 case 2: 250 return Date.class; 251 case 1: 252 case 4: 253 case 5: 254 case 6: 255 return String.class; 256 default: 257 return super.getColumnClass(column); 258 } 259 } 260 261 public String getColumnName(int column) { 262 switch (column) { 263 case 0: 264 if (showAddresses) { 265 return ResourceStrings.getString("address_column"); 266 } else { 267 return ResourceStrings.getString("client_name_column"); 268 } 269 case 1: 270 return ResourceStrings.getString("flags_column"); 271 case 2: 272 return ResourceStrings.getString("expires_column"); 273 case 3: 274 return ResourceStrings.getString("server_column"); 275 case 4: 276 return ResourceStrings.getString("macro_column"); 277 case 5: 278 return ResourceStrings.getString("client_column"); 279 case 6: 280 return ResourceStrings.getString("comment_column"); 281 default: 282 return super.getColumnName(column); 283 } 284 } 285 286 protected DhcpClientRecord getClientAt(int row) { 287 return data[row]; 288 } 289 } 290 291 // Background loader for addresses. 292 class AddressLoader extends com.sun.dhcpmgr.ui.SwingWorker { 293 public Object construct() { 294 try { 295 String net = addressTableModel.getNetwork(); 296 return DataManager.get().getClients(net, true); 297 } catch (final BridgeException e) { 298 // Since we're in a background thread, ask Swing to run ASAP. 299 SwingUtilities.invokeLater(new Runnable() { 300 Object [] args = new Object[] { e.getMessage() }; 301 public void run() { 302 MessageFormat form = new MessageFormat( 303 ResourceStrings.getString("error_loading_addrs")); 304 JOptionPane.showMessageDialog(null, form.format(args), 305 ResourceStrings.getString("server_error_title"), 306 JOptionPane.ERROR_MESSAGE); 307 } 308 }); 309 } 310 return null; 311 } 312 313 public void finished() { 314 addressTableModel.setData((DhcpClientRecord [])get()); 315 addressTableModel.doneLoading(); 316 MainFrame.setStatusText( 317 MessageFormat.format( 318 ResourceStrings.getString("address_status_message"), 319 addressTableModel.getRowCount())); 320 addressTable.clearSelection(); 321 } 322 } 323 324 // Renderer class used to make unusable addresses bold in the display 325 class AddressTableCellRenderer extends ExtendedCellRenderer { 326 public Component getTableCellRendererComponent(JTable table, 327 Object value, boolean isSelected, boolean hasFocus, int row, 328 int column) { 329 Component c = super.getTableCellRendererComponent(table, value, 330 isSelected, hasFocus, row, column); 331 int modelRow = sortedTableModel.mapRowAt(row); 332 if (modelRow != -1) { 333 if (addressTableModel.getClientAt(modelRow).isUnusable()) { 334 Font f = c.getFont(); 335 c.setFont(new Font(f.getName(), Font.BOLD, f.getSize())); 336 } 337 } 338 return c; 339 } 340 } 341 342 // Recipient of update messages sent when the editing dialogs exit 343 class DialogListener implements ActionListener { 344 public void actionPerformed(ActionEvent e) { 345 // Don't reload if cancel happened 346 if (!e.getActionCommand().equals(DialogActions.CANCEL)) { 347 AddressView.this.reload(); 348 } 349 } 350 } 351 352 public AddressView() { 353 displayPanel = new JPanel(new BorderLayout()); 354 355 // Create network selection list, tie it to table 356 networkListModel = new NetworkListModel(); 357 networkList = new JList(networkListModel); 358 networkList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 359 networkList.addListSelectionListener(new ListSelectionListener() { 360 public void valueChanged(ListSelectionEvent e) { 361 // Ignore all but the last in a series of these events 362 if (e.getValueIsAdjusting()) { 363 return; 364 } 365 String net = ""; 366 int index = networkList.getSelectedIndex(); 367 if (index != -1) { 368 net = (String)networkListModel.getElementAt( 369 networkList.getSelectedIndex()); 370 } 371 if (net.length() == 0) { 372 // No networks are selected; disable menu items 373 deleteNets.setEnabled(false); 374 addAddrs.setEnabled(false); 375 showAddresses.setEnabled(false); 376 showGrid.setEnabled(false); 377 } else { 378 deleteNets.setEnabled(true); 379 addAddrs.setEnabled(true); 380 showAddresses.setEnabled(true); 381 showGrid.setEnabled(true); 382 } 383 addressTableModel.load(net); 384 } 385 }); 386 387 // Use a prototype value as a performance enhancement 388 networkList.setPrototypeCellValue("222.222.222.222"); 389 JScrollPane networkPane = new JScrollPane(networkList); 390 JPanel networkPanel = new JPanel(new BorderLayout()); 391 networkPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); 392 393 Mnemonic mnNetwork = new Mnemonic(ResourceStrings.getString("network")); 394 JLabel nwLbl = new JLabel(mnNetwork.getString()); 395 nwLbl.setLabelFor(networkPanel); 396 nwLbl.setToolTipText(mnNetwork.getString()); 397 networkPanel.add(nwLbl, BorderLayout.NORTH); 398 nwLbl.setDisplayedMnemonic(mnNetwork.getMnemonic()); 399 400 networkPanel.add(networkPane, BorderLayout.CENTER); 401 displayPanel.add(networkPanel, BorderLayout.WEST); 402 403 // Create table to display in data area 404 addressTableModel = new AddressTableModel(); 405 sortedTableModel = new TableSorter(addressTableModel); 406 addressTable = new AutosizingTable(sortedTableModel); 407 sortedTableModel.addMouseListenerToHeaderInTable(addressTable); 408 addressTable.getTableHeader().setReorderingAllowed(true); 409 addressTable.getTableHeader().setResizingAllowed(true); 410 addressTable.setSelectionMode( 411 ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 412 413 sortedTableModel.addActionListener(new ActionListener() { 414 private SortedHeaderRenderer sortedRenderer = 415 new SortedHeaderRenderer(addressTable); 416 private TableCellRenderer savedRenderer; 417 public void actionPerformed(ActionEvent e) { 418 // Clear the selection when sorting is changed 419 addressTable.clearSelection(); 420 /* 421 * Change the header rendering to show which column is 422 * being used for sorting of the data. 423 */ 424 int modelIndex = Integer.parseInt(e.getActionCommand()); 425 int viewIndex = 426 addressTable.convertColumnIndexToView(modelIndex); 427 if (sortModelIndex != -1) { 428 int sortViewIndex = 429 addressTable.convertColumnIndexToView(sortModelIndex); 430 addressTable.getColumnModel().getColumn( 431 sortViewIndex).setHeaderRenderer(savedRenderer); 432 } 433 /* 434 * Save the column currently being sorted so we can restore 435 * the renderer later. We save model columns rather than 436 * view columns because model columns are invariant while 437 * view columns can be reordered with confusion resulting. 438 */ 439 TableColumn c = 440 addressTable.getColumnModel().getColumn(viewIndex); 441 savedRenderer = c.getHeaderRenderer(); 442 c.setHeaderRenderer(sortedRenderer); 443 sortModelIndex = modelIndex; 444 } 445 }); 446 447 // Make double-clicks the same as Edit->Properties 448 addressTable.addMouseListener(new MouseAdapter() { 449 public void mouseClicked(MouseEvent e) { 450 if (e.getClickCount() == 2) { 451 handleProperties(); 452 } 453 } 454 }); 455 456 // Install custom renderer to bold the entries which are unusable 457 TableCellRenderer renderer = new AddressTableCellRenderer(); 458 addressTable.setDefaultRenderer(String.class, renderer); 459 addressTable.setDefaultRenderer(IPAddress.class, renderer); 460 addressTable.setDefaultRenderer(Date.class, renderer); 461 462 // Wrap it in a scroll pane 463 addressPane = new JScrollPane(addressTable); 464 465 displayPanel.add(addressPane, BorderLayout.CENTER); 466 467 // Create menu items 468 Mnemonic mnShowAddrs = 469 new Mnemonic(ResourceStrings.getString("show_addresses")); 470 showAddresses = new JCheckBoxMenuItem(mnShowAddrs.getString(), 471 false); 472 showAddresses.setMnemonic(mnShowAddrs.getMnemonic()); 473 showAddresses.addActionListener(new ActionListener() { 474 public void actionPerformed(ActionEvent e) { 475 addressTableModel.setShowAddresses(showAddresses.getState()); 476 } 477 }); 478 479 Mnemonic mnShowGrid = 480 new Mnemonic(ResourceStrings.getString("show_grid")); 481 showGrid = new JCheckBoxMenuItem(mnShowGrid.getString(), 482 true); 483 showGrid.setMnemonic(mnShowGrid.getMnemonic()); 484 showGrid.addActionListener(new ActionListener() { 485 public void actionPerformed(ActionEvent e) { 486 addressTable.setShowGrid(showGrid.getState()); 487 } 488 }); 489 490 Mnemonic mnAddNet = 491 new Mnemonic(ResourceStrings.getString("add_network")); 492 addNet = new JMenuItem(mnAddNet.getString()); 493 addNet.setMnemonic(mnAddNet.getMnemonic()); 494 addNet.addActionListener(new ActionListener() { 495 public void actionPerformed(ActionEvent e) { 496 ConfigWizard wiz = new ConfigWizard(myFrame, 497 ResourceStrings.getString("net_wiz_title"), false); 498 wiz.addActionListener(new ActionListener() { 499 public void actionPerformed(ActionEvent e) { 500 if (e.getActionCommand().equals("finished")) { 501 reload(); 502 } 503 } 504 }); 505 wiz.pack(); 506 wiz.setVisible(true); 507 } 508 }); 509 510 511 Mnemonic mnDelNets = 512 new Mnemonic(ResourceStrings.getString("delete_networks")); 513 deleteNets = new JMenuItem(mnDelNets.getString()); 514 deleteNets.setMnemonic(mnDelNets.getMnemonic()); 515 deleteNets.addActionListener(new ActionListener() { 516 public void actionPerformed(ActionEvent e) { 517 DeleteNetworksDialog d = new DeleteNetworksDialog(myFrame); 518 d.addActionListener(new ActionListener() { 519 public void actionPerformed(ActionEvent e) { 520 if (e.getActionCommand().equals(DialogActions.OK)) { 521 reload(); 522 } 523 } 524 }); 525 d.pack(); 526 d.setVisible(true); 527 } 528 }); 529 530 Mnemonic mnAddAddr = 531 new Mnemonic(ResourceStrings.getString("add_addresses")); 532 addAddrs = new JMenuItem(mnAddAddr.getString()); 533 addAddrs.setMnemonic(mnAddAddr.getMnemonic()); 534 addAddrs.setEnabled(false); // Start out disabled 535 addAddrs.addActionListener(new ActionListener() { 536 public void actionPerformed(ActionEvent e) { 537 AddressWizard wiz = new AddressWizard(myFrame, 538 networkListModel.getNetworkAt( 539 networkList.getSelectedIndex())); 540 wiz.addActionListener(new DialogListener()); 541 wiz.pack(); 542 wiz.setVisible(true); 543 } 544 }); 545 546 Mnemonic mnRelAddr = 547 new Mnemonic(ResourceStrings.getString("release_addresses")); 548 releaseAddrs = new JMenuItem(mnRelAddr.getString()); 549 releaseAddrs.setMnemonic(mnRelAddr.getMnemonic()); 550 releaseAddrs.setEnabled(false); // Start out disabled 551 releaseAddrs.addActionListener(new ActionListener() { 552 public void actionPerformed(ActionEvent e) { 553 int [] rows = addressTable.getSelectedRows(); 554 if (rows.length == 0) { 555 return; 556 } 557 DhcpClientRecord [] recs = new DhcpClientRecord[rows.length]; 558 for (int i = 0; i < rows.length; ++i) { 559 recs[i] = addressTableModel.getClientAt( 560 sortedTableModel.mapRowAt(rows[i])); 561 } 562 ReleaseAddressDialog d = new ReleaseAddressDialog(myFrame, recs, 563 (String)networkListModel.getElementAt( 564 networkList.getSelectedIndex()), 565 showAddresses.isSelected()); 566 d.addActionListener(new DialogListener()); 567 d.pack(); 568 d.setVisible(true); 569 } 570 }); 571 572 Mnemonic mnOnAddrs = 573 new Mnemonic(ResourceStrings.getString("on_addresses_item")); 574 addressHelp = new JMenuItem(mnOnAddrs.getString()); 575 addressHelp.setMnemonic(mnOnAddrs.getMnemonic()); 576 addressHelp.addActionListener(new ActionListener() { 577 public void actionPerformed(ActionEvent e) { 578 DhcpmgrApplet.showHelp("addresses_reference"); 579 } 580 }); 581 582 /* 583 * Construct the menu lists 584 */ 585 menuItems = new Vector[MainFrame.MENU_COUNT]; 586 for (int i = 0; i < menuItems.length; ++i) { 587 menuItems[i] = new Vector(); 588 } 589 menuItems[MainFrame.VIEW_MENU].addElement(showAddresses); 590 menuItems[MainFrame.VIEW_MENU].addElement(showGrid); 591 menuItems[MainFrame.EDIT_MENU].addElement(addAddrs); 592 menuItems[MainFrame.EDIT_MENU].addElement(releaseAddrs); 593 menuItems[MainFrame.EDIT_MENU].addElement(addNet); 594 menuItems[MainFrame.EDIT_MENU].addElement(deleteNets); 595 menuItems[MainFrame.HELP_MENU].addElement(addressHelp); 596 597 // Listen for selections events, manipulate menu item state as needed 598 addressTable.getSelectionModel().addListSelectionListener( 599 new ListSelectionListener() { 600 public void valueChanged(ListSelectionEvent e) { 601 if (addressTable.getSelectionModel().isSelectionEmpty()) { 602 // Disable menu items 603 releaseAddrs.setEnabled(false); 604 } else { 605 // Enable menu items 606 releaseAddrs.setEnabled(true); 607 } 608 // Notify listeners that our selection state may have changed 609 notifySelectionListeners(); 610 } 611 }); 612 } 613 614 public String getName() { 615 return ResourceStrings.getString("address_view_name"); 616 } 617 618 // Return custom menus for this view, which is nothing at this time 619 public Enumeration menus() { 620 return null; 621 } 622 623 // Return custom menu items for each menu as requested. 624 public Enumeration menuItems(int menu) { 625 return menuItems[menu].elements(); 626 } 627 628 public Component getDisplay() { 629 return displayPanel; 630 } 631 632 public void setActive(boolean state) { 633 if (state) { 634 if (firstActivation) { 635 // Find frame we're in for use when creating dialogs 636 myFrame = (Frame)SwingUtilities.getAncestorOfClass( 637 MainFrame.class, addressTable); 638 if (networkListModel.getSize() != 0) { 639 networkList.setSelectedIndex(0); 640 } 641 firstActivation = false; 642 } else { 643 // Clear any messages left from other views 644 MainFrame.setStatusText(""); 645 } 646 } 647 } 648 649 // Handle a find 650 public void find(String s) { 651 int startRow = addressTable.getSelectedRow() + 1; 652 for (int i = startRow; i < sortedTableModel.getRowCount(); ++i) { 653 DhcpClientRecord rec = 654 addressTableModel.getClientAt(sortedTableModel.mapRowAt(i)); 655 if (rec.getClientName().indexOf(s) != -1 || 656 rec.toString().indexOf(s) != -1) { 657 addressTable.setRowSelectionInterval(i, i); 658 addressTable.scrollRectToVisible( 659 addressTable.getCellRect(i, 0, false)); 660 return; 661 } 662 } 663 // Got to the end, wrap around 664 for (int i = 0; i < startRow; ++i) { 665 DhcpClientRecord rec = 666 addressTableModel.getClientAt(sortedTableModel.mapRowAt(i)); 667 if (rec.getClientName().indexOf(s) != -1 || 668 rec.toString().indexOf(s) != -1) { 669 addressTable.setRowSelectionInterval(i, i); 670 addressTable.scrollRectToVisible( 671 addressTable.getCellRect(i, 0, false)); 672 return; 673 } 674 } 675 } 676 677 public void handleCreate() { 678 if (networkList.getSelectedIndex() == -1) { 679 // Tell user to use Network Wizard 680 JOptionPane.showMessageDialog(myFrame, 681 ResourceStrings.getString("run_network_wizard"), 682 ResourceStrings.getString("error_message"), 683 JOptionPane.ERROR_MESSAGE); 684 } else { 685 CreateAddressDialog d = new CreateAddressDialog(myFrame, 686 CreateAddressDialog.CREATE, new DhcpClientRecord(), 687 networkListModel.getNetworkAt(networkList.getSelectedIndex())); 688 d.addActionListener(new DialogListener()); 689 d.pack(); 690 d.setVisible(true); 691 } 692 } 693 694 public void handleDelete() { 695 int [] rows = addressTable.getSelectedRows(); 696 if (rows.length == 0) { 697 return; 698 } 699 DhcpClientRecord [] recs = new DhcpClientRecord[rows.length]; 700 for (int i = 0; i < rows.length; ++i) { 701 recs[i] = addressTableModel.getClientAt( 702 sortedTableModel.mapRowAt(rows[i])); 703 } 704 DeleteAddressDialog d = new DeleteAddressDialog(myFrame, recs, 705 (String)networkListModel.getElementAt( 706 networkList.getSelectedIndex())); 707 d.addActionListener(new DialogListener()); 708 d.pack(); 709 d.setVisible(true); 710 } 711 712 public void handleDuplicate() { 713 int row = addressTable.getSelectedRow(); 714 if (row == -1) { 715 return; 716 } 717 DhcpClientRecord rec = 718 addressTableModel.getClientAt(sortedTableModel.mapRowAt(row)); 719 if (rec == null) { 720 return; 721 } 722 CreateAddressDialog d = new CreateAddressDialog(myFrame, 723 CreateAddressDialog.DUPLICATE, (DhcpClientRecord)rec.clone(), 724 networkListModel.getNetworkAt(networkList.getSelectedIndex())); 725 d.addActionListener(new DialogListener()); 726 d.pack(); 727 d.setVisible(true); 728 } 729 730 public void handleProperties() { 731 int [] rows = addressTable.getSelectedRows(); 732 if (rows.length == 0) { 733 return; 734 } 735 DhcpClientRecord [] recs = new DhcpClientRecord[rows.length]; 736 for (int i = 0; i < rows.length; ++i) { 737 recs[i] = 738 addressTableModel.getClientAt( 739 sortedTableModel.mapRowAt(rows[i])); 740 } 741 if (recs.length == 1) { 742 // Edit a single address 743 CreateAddressDialog d = new CreateAddressDialog(myFrame, 744 CreateAddressDialog.EDIT, (DhcpClientRecord)recs[0].clone(), 745 networkListModel.getNetworkAt(networkList.getSelectedIndex())); 746 d.addActionListener(new DialogListener()); 747 d.pack(); 748 d.setVisible(true); 749 } else { 750 // Edit a group of addresses 751 ModifyAddressesDialog d = new ModifyAddressesDialog(myFrame, recs, 752 (String)networkListModel.getElementAt( 753 networkList.getSelectedIndex())); 754 d.addActionListener(new DialogListener()); 755 d.pack(); 756 d.setVisible(true); 757 } 758 } 759 760 public void handleUpdate() { 761 reload(); 762 } 763 764 protected void reload() { 765 Object value = networkList.getSelectedValue(); 766 networkListModel.reload(); 767 networkList.clearSelection(); 768 networkList.setSelectedValue(value, true); 769 if (networkListModel.getSize() != 0 && 770 networkList.getSelectedIndex() == -1) { 771 // Didn't get selected, must be gone. Select first item in list 772 networkList.setSelectedIndex(0); 773 } 774 } 775 776 public void addSelectionListener(SelectionListener listener) { 777 selectionListeners.addElement(listener); 778 } 779 780 public void removeSelectionListener(SelectionListener listener) { 781 selectionListeners.removeElement(listener); 782 } 783 784 private void notifySelectionListeners() { 785 Enumeration en = selectionListeners.elements(); 786 while (en.hasMoreElements()) { 787 SelectionListener l = (SelectionListener)en.nextElement(); 788 l.valueChanged(); 789 } 790 } 791 792 public boolean isSelectionEmpty() { 793 return addressTable.getSelectionModel().isSelectionEmpty(); 794 } 795 796 public boolean isSelectionMultiple() { 797 return (addressTable.getSelectedRowCount() > 1); 798 } 799 800 public void startAddressWizard() { 801 addAddrs.doClick(); 802 } 803 }