This section contains the code for the P2P Dashboard program. Three Java classes make up the P2P Dashboard sample program: P2PDashboard, the main class; PeerDiscovery, a class that handles local/remote peer discovery management; and GroupDiscovery, a class that handles local/remote group discovery management. Details of the P2PDashboard ClassP2PDashboard.java is the main class that encapsulates all graphical user interface elements, such as the window frame, command buttons, scroll pane, text fields, radio buttons, tree structure, and button groups for the Dashboard, and it directly interfaces with the JXTA platform. P2Pdashboard.java employs the following methods:
P2PDashboard utilizes the following JXTA methods:
Listing 19.1 presents the code for P2PDashboard.java. Listing 19.1 P2PDashboard.javaimport java.awt.Container; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.lang.String; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.DefaultListSelectionModel; import javax.swing.border.TitledBorder; import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionEvent; import net.jxta.credential.AuthenticationCredential; import net.jxta.document.StructuredDocument; import net.jxta.document.MimeMediaType; import net.jxta.discovery.DiscoveryService; import net.jxta.exception.PeerGroupException; import net.jxta.membership.Authenticator; import net.jxta.membership.MembershipService; import net.jxta.peergroup.PeerGroup; import net.jxta.peergroup.PeerGroupFactory; import net.jxta.protocol.ModuleImplAdvertisement; import net.jxta.protocol.PeerGroupAdvertisement; import net.jxta.protocol.PeerAdvertisement; import net.jxta.impl.protocol.PeerGroupAdv; import net.jxta.impl.protocol.PeerAdv; import net.jxta.impl.id.UUID.PeerID; import net.jxta.impl.id.UUID.PeerGroupID; /* P2P Dashboard application */ public class P2PDashboard extends JFrame { // frame reference for JOptionPane message dialogs private JFrame frame; // group section private JScrollPane groupScrollPane; private JList groupList; private Hashtable groupHT; private JTextField groupAddTextField; private JButton groupAddButton; private JButton groupFlushButton; private JButton groupRemoveButton; private JRadioButton groupLocalRadioButton; private JRadioButton groupRemoteRadioButton; private ButtonGroup groupDiscoveryButtonGroup; private JButton groupDiscoveryButton; // peer section private JScrollPane peerScrollPane; private JList peerList; private JTextField peerAddTextField; private JButton peerAddButton; private JButton peerFlushButton; private JCheckBox peerCheckBox; private JButton peerRemoveButton; private JRadioButton peerLocalRadioButton; private JRadioButton peerRemoteRadioButton; private ButtonGroup peerDiscoveryButtonGroup; private JButton peerDiscoveryButton; private boolean displayPeerGroups; // Default NetPeerGroup and discovery service private static PeerGroup netPeerGroup; private DiscoveryService discovery; private String defaultGroupName; private String defaultPeerName; // peer and group discovery event handlers private PeerDiscovery peerDiscovery; private GroupDiscovery groupDiscovery; /*********************/ /* Dashboard Methods */ /*********************/ /* *Command line arguments */ public static void main(String args[]) { P2PDashboard p2p = new P2PDashboard(); p2p.show(); // setup localPeer in NetPeerGroup p2p.initializeNetPeerGroup(); // prepare peer and group discovery services p2p.initializeDiscovery(); } /* *Create a new P2PDashboard frame. */ public P2PDashboard() { frame = this; // group groupScrollPane = new JScrollPane(); groupList = new JList(new SortedListModel()); groupHT = new Hashtable(); groupAddTextField = new JTextField(); groupAddButton = new JButton(); groupFlushButton = new JButton(); groupRemoveButton = new JButton(); groupLocalRadioButton = new JRadioButton(); groupRemoteRadioButton = new JRadioButton(); groupDiscoveryButtonGroup = new ButtonGroup(); groupDiscoveryButton = new JButton(); // peer peerScrollPane = new JScrollPane(); peerList = new JList(new SortedListModel()); peerAddTextField = new JTextField(); peerAddButton = new JButton(); peerFlushButton = new JButton(); peerCheckBox = new JCheckBox(); peerRemoveButton = new JButton(); peerLocalRadioButton = new JRadioButton(); peerRemoteRadioButton = new JRadioButton(); peerDiscoveryButtonGroup = new ButtonGroup(); peerDiscoveryButton = new JButton(); displayPeerGroups = false; initializeGUIComponents(); configureGroupEvents(); configurePeerEvents(); } /* *P2PDashboard uses this to setup GUI objects and *their properties. */ private void initializeGUIComponents() { Container contentPane = getContentPane(); Insets insets = contentPane.getInsets(); contentPane.setLayout(null); // group section groupScrollPane.setViewportBorder (new TitledBorder("Groups")); groupScrollPane.setViewportView(groupList); contentPane.add(groupScrollPane); groupScrollPane.setBounds(10+insets.left, 10+insets.top, 250, 230); groupAddTextField.setToolTipText("Add a new group"); contentPane.add(groupAddTextField); groupAddTextField.setBounds(10+insets.left, 250+insets.top, 140, 20); groupAddButton.setText("Add"); groupAddButton.setToolTipText("Add a new group"); contentPane.add(groupAddButton); groupAddButton.setBounds(170+insets.left, 250+insets.top, 90, 20); groupFlushButton.setText("Flush"); groupFlushButton.setToolTipText ("Flush local group cache"); contentPane.add(groupFlushButton); groupFlushButton.setBounds(10+insets.left, 280+insets.top, 90, 20); groupRemoveButton.setText("Remove"); groupRemoveButton.setToolTipText("Remove a group"); contentPane.add(groupRemoveButton); groupRemoveButton.setBounds(170+insets.left, 280+insets.top, 90, 20); groupLocalRadioButton.setSelected(true); groupLocalRadioButton.setText("Local"); groupLocalRadioButton.setToolTipText ("Search for local groups"); contentPane.add(groupLocalRadioButton); groupLocalRadioButton.setBounds(10+insets.left, 310+insets.top, 60, 20); groupRemoteRadioButton.setText("Remote"); groupRemoteRadioButton.setToolTipText ("Search for remote groups"); contentPane.add(groupRemoteRadioButton); groupRemoteRadioButton.setBounds(90+insets.left, 310+insets.top, 70, 20); groupDiscoveryButtonGroup.add(groupLocalRadioButton); groupDiscoveryButtonGroup.add(groupRemoteRadioButton); groupDiscoveryButton.setText("Discover"); groupDiscoveryButton.setToolTipText("Find groups"); contentPane.add(groupDiscoveryButton); groupDiscoveryButton.setBounds(170+insets.left, 310+insets.top, 90, 20); // peer section peerScrollPane.setViewportBorder (new TitledBorder("Peers")); peerScrollPane.setViewportView(peerList); contentPane.add(peerScrollPane); peerScrollPane.setBounds(290+insets.left, 10+insets.top, 250, 230); peerAddTextField.setToolTipText("Add a new peer"); contentPane.add(peerAddTextField); peerAddTextField.setBounds(290+insets.left, 250+insets.top, 140, 20); peerAddButton.setText("Add"); peerAddButton.setToolTipText("Add a new peer"); contentPane.add(peerAddButton); peerAddButton.setBounds(450+insets.left, 250+insets.top, 90, 20); peerFlushButton.setText("Flush"); peerFlushButton.setToolTipText ("Flush local peer cache"); contentPane.add(peerFlushButton); peerFlushButton.setBounds(290+insets.left, 280+insets.top, 90, 20); peerCheckBox.setSelected(false); peerCheckBox.setText("Groups"); peerCheckBox.setToolTipText ("Display groups peer is in."); contentPane.add(peerCheckBox); peerCheckBox.setBounds(386+insets.left, 280+insets.top, 60, 20); peerRemoveButton.setText("Remove"); peerRemoveButton.setToolTipText("Remove a peer"); contentPane.add(peerRemoveButton); peerRemoveButton.setBounds(450+insets.left, 280+insets.top, 90, 20); peerLocalRadioButton.setSelected(true); peerLocalRadioButton.setText("Local"); peerLocalRadioButton.setToolTipText ("Search for local peers"); contentPane.add(peerLocalRadioButton); peerLocalRadioButton.setBounds(290+insets.left, 310+insets.top, 60, 20); peerRemoteRadioButton.setText("Remote"); peerRemoteRadioButton.setToolTipText ("Search for remote peers"); contentPane.add(peerRemoteRadioButton); peerRemoteRadioButton.setBounds(370+insets.left, 310+insets.top, 70, 20); peerDiscoveryButtonGroup.add(peerLocalRadioButton); peerDiscoveryButtonGroup.add(peerRemoteRadioButton); peerDiscoveryButton.setText("Discover"); peerDiscoveryButton.setToolTipText("Find peers"); contentPane.add(peerDiscoveryButton); peerDiscoveryButton.setBounds(450+insets.left, 310+insets.top, 90, 20); pack(); setTitle("P2P Dashboard"); setSize(558, 365); setResizable(false); // JFrame event addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { exitForm(evt); } }); } /* P2PDashboard uses this to handle GUI object events. */ private void configureGroupEvents() { // group JList event groupList.setSelectionMode (ListSelectionModel.SINGLE_SELECTION); groupList.addListSelectionListener (new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) { return; } JList list = (JList)e.getSource(); // whenever a group is selected, // retrieve its corresponding peer list and // display it. if (list.isSelectionEmpty() == false) { String group = (String)list.getSelectedValue(); SortedListModel peers = (SortedListModel) groupHT.get(group); peerList.setModel(peers); } } }); // group Add JButton event groupAddButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String group = groupAddTextField.getText(); SortedListModel list = null; if (checkAddRules(group) == false) { return; } list = (SortedListModel)groupList.getModel(); // ensure new group does not already exist if (list.contains(group) == false) { list.addElement(group); addGroup(group); SortedListModel slm = new SortedListModel(); groupHT.put(group, slm); groupList.setModel(list); groupList.setSelectedValue(group, true); peerList.clearSelection(); } else { handleError("Group `" + group + "` already in use.", "Invalid group name", null, false); } groupAddTextField.setText(""); } }); // peer Flush JButton event groupFlushButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // remove all groups except the netPeerGroup SortedListModel list = (SortedListModel) groupList.getModel(); Enumeration enum = list.elements(); String group = null; while (enum.hasMoreElements()) { group = (String)enum.nextElement(); if (group.equals(defaultGroupName) == false) { list.removeElement(group); groupHT.remove(group); } } groupList.setModel(list); groupList.setSelectedValue(defaultGroupName, true); peerList.clearSelection(); // flush actual local group advertisements groupDiscovery.flushGroupInfo(); } }); // group Remove JButton event groupRemoveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String group = (String)groupList.getSelectedValue(); if (group == null || group.equals("") == true || group.equals(defaultGroupName)) { return; } SortedListModel list = (SortedListModel) groupList.getModel(); list.removeElement(group); groupList.setModel(list); groupList.setSelectedValue(defaultGroupName, true); peerList.clearSelection(); removeAdvertisement(group, false); } }); // group Discovery JButton event groupDiscoveryButton.addActionListener (new ActionListener() { public void actionPerformed(ActionEvent e) { // initiate local group discovery if (groupLocalRadioButton.isSelected()) { groupDiscovery.setLocalDiscovery(true); groupDiscovery.run(); } // initiate remote group discovery else if (groupRemoteRadioButton.isSelected()) { groupDiscovery.setLocalDiscovery(false); groupDiscovery.run(); } } }); } /* P2PDashboard uses this to handle peer GUI object events. */ private void configurePeerEvents() { // peer JList event peerList.setSelectionMode (ListSelectionModel.SINGLE_SELECTION); peerList.addListSelectionListener (new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { JList list = (JList)e.getSource(); String selectedPeer = (String)list.getSelectedValue(); if (e.getValueIsAdjusting() || displayPeerGroups == false) { return; } // whenever a peer is selected, // retrieve its corresponding group list and // display it. if (list.isSelectionEmpty() == false) { SortedListModel peerInGroup = new SortedListModel(); SortedListModel peers = null; String group = null; Enumeration keys = groupHT.keys(); while (keys.hasMoreElements()) { group = (String)keys.nextElement(); peers = (SortedListModel)groupHT.get(group); if (peers.contains(selectedPeer) == true) { peerInGroup.addElement(group); } } groupList.setModel(peerInGroup); groupList.clearSelection(); } } }); // peer Add JButton event peerAddButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String peer = peerAddTextField.getText(); String group = (String)groupList.getSelectedValue(); // allow defaultPeerName to be added to new groups if (peer != null && !peer.equals("") && group != null && !group.equals("") && peer.equals(defaultPeerName) && !group.equals(defaultGroupName)) { System.out.println ("Adding " + peer + " to group '" + group + "'"); } // default peer name checking else if (checkAddRules(peer) == false || group == null || group.equals("") == true) { handleError("Invalid peer name.", "Invalid peer ", null, false); return; } // do not allow a peer to be the same name as the // currently selected group if (peer.equals(group)) { handleError("Peer cannot be same name as group.", "Invalid peer ", null, false); return; } // retrieve peer list of currently selected group SortedListModel list = (SortedListModel)peerList.getModel(); // ensure new peer does not already exist if (list.contains(peer) == false) { list.addElement(peer); peerList.setModel(list); groupHT.put(group, list); addPeer(peer); } else { handleError("Peer `" + peer + "` already in use.", "Invalid peer ", null, false); } peerAddTextField.setText(""); } }); // peer Flush JButton event peerFlushButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // remove every peer in every group // except defaultPeerName in the netPeerGroup Enumeration keys = groupHT.keys(); Enumeration enum = null; SortedListModel peers = null; String group = null; String peer = null; while (keys.hasMoreElements()) { group = (String)keys.nextElement(); peers = (SortedListModel)groupHT.get(group); enum = peers.elements(); while (enum.hasMoreElements()) { peer = (String)enum.nextElement(); if (peer.equals(defaultPeerName) == true && group.equals(defaultGroupName) == true) { System.out.println (defaultPeerName + " not flushed from " + Details of the PeerDiscovery ClassThe PeerDiscovery class is responsible for the local and remote discovery of peers, as well as for updating the peer information in the GUI. The PeerDiscovery class implements the Runnable and DiscoveryListener interfaces and the following methods:
Listing 19.2 presents the code for PeerDiscovery.java. Listing 19.2 PeerDiscovery.javaimport java.io.InputStream; import java.io.IOException; import java.io.ByteArrayInputStream; import java.lang.String; import java.util.Enumeration; import javax.swing.JList; import net.jxta.document.Advertisement; import net.jxta.document.AdvertisementFactory; import net.jxta.document.MimeMediaType; import net.jxta.discovery.DiscoveryService; import net.jxta.discovery.DiscoveryListener; import net.jxta.discovery.DiscoveryEvent; import net.jxta.exception.PeerGroupException; import net.jxta.peergroup.PeerGroup; import net.jxta.peergroup.PeerGroupFactory; import net.jxta.protocol.DiscoveryResponseMsg; import net.jxta.protocol.PeerAdvertisement; /* *PeerDiscovery *Responsible for local and remote discovery of peers. *Also responsible for updating the peer info in the GUI. */ public class PeerDiscovery implements Runnable, DiscoveryListener { // necessary links to important local peer information private PeerGroup netPeerGroup; private DiscoveryService discovery; private PeerAdvertisement peerAdv; // link to peer GUI list private JList peerList; private String defaultPeerName; // link to GUI discovery selection type (local or remote) private boolean local; /* *Update peer GUI for adding/removing peers */ private void updateGUI(boolean stringCast, Enumeration enum) { String str = null; PeerAdvertisement newAdv = null; MimeMediaType mmt = new MimeMediaType("text/xml"); SortedListModel peers = (SortedListModel)peerList.getModel(); while (enum.hasMoreElements()) { // Processing String objects if (stringCast) { str = (String)enum.nextElement(); try { // create an advertisement for each element newAdv = (PeerAdvertisement) AdvertisementFactory.newAdvertisement (mmt, new Details of the GroupDiscovery.java ClassThe GroupDiscovery class is responsible for handling local and remote discovery of groups, as well as updating the group information on the GUI. The GroupDiscovery class implements the Runnable and DiscoveryListener interfaces. It uses the following methods:
Listing 19.3 presents the code for GroupDiscovery.java. Listing 19.3 GroupDiscovery.javaimport java.io.InputStream; import java.io.IOException; import java.io.ByteArrayInputStream; import java.lang.String; import java.util.Enumeration; import javax.swing.JList; import net.jxta.document.Advertisement; import net.jxta.document.AdvertisementFactory; import net.jxta.document.MimeMediaType; import net.jxta.discovery.DiscoveryService; import net.jxta.discovery.DiscoveryListener; import net.jxta.discovery.DiscoveryEvent; import net.jxta.exception.PeerGroupException; import net.jxta.peergroup.PeerGroup; import net.jxta.peergroup.PeerGroupFactory; import net.jxta.protocol.DiscoveryResponseMsg; import net.jxta.protocol.PeerAdvertisement; import net.jxta.protocol.PeerGroupAdvertisement; /* *GroupDiscovery *Responsible for local and remote discovery of groups. *Also responsible for updating the group information *in the GUI. */ public class GroupDiscovery implements Runnable, DiscoveryListener { // necessary links to important group information private PeerGroup netPeerGroup; private DiscoveryService discovery; private PeerAdvertisement peerAdv; // link to group tree GUI private JList groupList; private String defaultGroupName; // link to GUI discovery selection type (local or remote) private boolean local; /* *Update group GUI for adding/removing groups and *respective peers under groups. */ private void updateGUI (boolean stringCast, Enumeration enum) { String str = null; PeerGroupAdvertisement newAdv = null; MimeMediaType mmt = new MimeMediaType("text/xml"); SortedListModel groups = (SortedListModel)groupList.getModel(); while (enum.hasMoreElements()) { // Processing String objects if (stringCast) { str = (String)enum.nextElement(); try { // create an advertisement from each element newAdv = (PeerGroupAdvertisement) AdvertisementFactory.newAdvertisement (mmt, Details of the SortedListModel ClassThe SortedListModel class is responsible for creating a tree of listmodel objects and storing them in a sorted set. It sorts the listmodel objects that are used to manage either peer or group lists. The SortedListModel class employs the following methods:
Listing 19.4 presents the code for SortedListModel.java. Listing 19.4 SortedListModel.java// Original source from : // // Copyright 1999 MageLang Institute // $Id //depot/main/src/edu/modules/Collections/magercises/Jlist /Solution/ |