// initialize client UI
  private void initComponents() {
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setTitle("Distributed Hash Table Client");
    keyBox = new JTextField(7);
    valueBox = new JTextField(15);
    serverBox = new JTextField(2);
    keyLabel = new JLabel("Key: ");
    keyLabel.setLabelFor(keyBox);
    valueLabel = new JLabel("Value: ");
    valueLabel.setLabelFor(valueBox);
    serverLabel = new JLabel("Server Id: ");
    serverLabel.setLabelFor(serverBox);
    serverOutput = new JLabel("Server Output:");

    JPanel pane = new JPanel(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 0;
    pane.add(keyLabel, c);
    c.gridx = 1;
    pane.add(keyBox, c);

    c.gridx = 0;
    c.gridy = 1;
    pane.add(valueLabel, c);
    c.gridx = 1;
    pane.add(valueBox, c);

    c.gridx = 0;
    c.gridy = 2;
    pane.add(serverLabel, c);
    c.gridx = 1;
    pane.add(serverBox, c);

    RadioListener radioListener = new RadioListener();
    actionGroup = new ButtonGroup();
    insertRadionButton = new JRadioButton("Insert");
    insertRadionButton.setSelected(true);
    insertRadionButton.setActionCommand("insert");
    insertRadionButton.addActionListener(radioListener);
    lookupRadionButton = new JRadioButton("Lookup");
    lookupRadionButton.setActionCommand("lookup");
    lookupRadionButton.addActionListener(radioListener);
    deleteRadionButton = new JRadioButton("Delete");
    deleteRadionButton.setActionCommand("delete");
    deleteRadionButton.addActionListener(radioListener);
    countRadionButton = new JRadioButton("Count");
    countRadionButton.setActionCommand("count");
    countRadionButton.addActionListener(radioListener);
    actionGroup.add(insertRadionButton);
    actionGroup.add(lookupRadionButton);
    actionGroup.add(deleteRadionButton);
    actionGroup.add(countRadionButton);

    c.gridx = 2;
    c.gridy = 0;
    pane.add(insertRadionButton, c);
    c.gridy = 1;
    pane.add(lookupRadionButton, c);
    c.gridy = 2;
    pane.add(deleteRadionButton, c);
    c.gridy = 3;
    pane.add(countRadionButton, c);

    execButton = new JButton("Execute");
    execButton.addActionListener(new ExecButtonListener());
    c.gridx = 3;
    c.gridy = 0;
    pane.add(execButton, c);

    purgeButton = new JButton("Purge");
    purgeButton.addActionListener(new PurgeButtonListener());
    c.gridx = 3;
    c.gridy = 2;
    pane.add(purgeButton, c);

    resultArea = new JTextArea(28, 70);
    resultArea.setEditable(false);
    scrollingArea = new JScrollPane(resultArea);

    upperPanel = new Panel(new BorderLayout());
    upperPanel.add(pane, BorderLayout.CENTER);

    resultPanel = new Panel();
    resultPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
    resultPanel.add(serverOutput);
    resultPanel.add(scrollingArea);

    add(upperPanel, BorderLayout.NORTH);
    add(resultPanel, BorderLayout.CENTER);
    setSize(800, 600);
    this.setVisible(true);
  }
 // append string to the output text area
 private void appendOutput(String msg) {
   resultArea.append(msg + "\n");
   resultArea.append("             ******************************\n");
 }