/** Listener to handle button actions */
 public void actionPerformed(ActionEvent e) {
   // Check if the user pressed the remove button
   if (e.getSource() == remove_button) {
     int row = table.getSelectedRow();
     model.removeRow(row);
     table.clearSelection();
     table.repaint();
     valueChanged(null);
   }
   // Check if the user pressed the remove all button
   if (e.getSource() == remove_all_button) {
     model.clearAll();
     table.setRowSelectionInterval(0, 0);
     table.repaint();
     valueChanged(null);
   }
   // Check if the user pressed the filter button
   if (e.getSource() == filter_button) {
     filter.showDialog();
     if (filter.okPressed()) {
       // Update the display with new filter
       model.setFilter(filter);
       table.repaint();
     }
   }
   // Check if the user pressed the start button
   if (e.getSource() == start_button) {
     start();
   }
   // Check if the user pressed the stop button
   if (e.getSource() == stop_button) {
     stop();
   }
   // Check if the user wants to switch layout
   if (e.getSource() == layout_button) {
     details_panel.remove(details_soap);
     details_soap.removeAll();
     if (details_soap.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
       details_soap = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
     } else {
       details_soap = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
     }
     details_soap.setTopComponent(request_panel);
     details_soap.setRightComponent(response_panel);
     details_soap.setResizeWeight(.5);
     details_panel.add(details_soap, BorderLayout.CENTER);
     details_panel.validate();
     details_panel.repaint();
   }
   // Check if the user is changing the reflow option
   if (e.getSource() == reflow_xml) {
     request_text.setReflowXML(reflow_xml.isSelected());
     response_text.setReflowXML(reflow_xml.isSelected());
   }
 }
 /** Listener to handle table selection changes */
 public void valueChanged(ListSelectionEvent e) {
   int row = table.getSelectedRow();
   // Check if they selected a specific row
   if (row > 0) {
     remove_button.setEnabled(true);
   } else {
     remove_button.setEnabled(false);
   }
   // Check for "most recent" selection
   if (row == 0) {
     row = model.getRowCount() - 1;
     if (row == 0) {
       row = -1;
     }
   }
   if (row == -1) {
     // Clear the details panel
     details_time_value.setText("");
     details_target_value.setText("");
     details_status_value.setText("");
     request_text.setText("");
     response_text.setText("");
   } else {
     // Show the details for the row
     SOAPMonitorData soap = model.getData(row);
     details_time_value.setText(soap.getTime());
     details_target_value.setText(soap.getTargetService());
     details_status_value.setText(soap.getStatus());
     if (soap.getSOAPRequest() == null) {
       request_text.setText("");
     } else {
       request_text.setText(soap.getSOAPRequest());
       request_text.setCaretPosition(0);
     }
     if (soap.getSOAPResponse() == null) {
       response_text.setText("");
     } else {
       response_text.setText(soap.getSOAPResponse());
       response_text.setCaretPosition(0);
     }
   }
 }
    /** Background thread used to receive data from the server. */
    public void run() {
      Long id;
      Integer message_type;
      String target;
      String soap;
      SOAPMonitorData data;
      int selected;
      int row;
      boolean update_needed;
      while (socket != null) {
        try {
          // Get the data from the server
          message_type = (Integer) in.readObject();
          // Process the data depending on its type
          switch (message_type.intValue()) {
            case SOAPMonitorConstants.SOAP_MONITOR_REQUEST:
              // Get the id, target and soap info
              id = (Long) in.readObject();
              target = (String) in.readObject();
              soap = (String) in.readObject();
              // Add new request data to the table
              data = new SOAPMonitorData(id, target, soap);
              model.addData(data);
              // If "most recent" selected then update
              // the details area if needed
              selected = table.getSelectedRow();
              if ((selected == 0) && model.filterMatch(data)) {
                valueChanged(null);
              }
              break;
            case SOAPMonitorConstants.SOAP_MONITOR_RESPONSE:
              // Get the id and soap info
              id = (Long) in.readObject();
              soap = (String) in.readObject();
              data = model.findData(id);
              if (data != null) {
                update_needed = false;
                // Get the selected row
                selected = table.getSelectedRow();
                // If "most recent", then always
                // update details area
                if (selected == 0) {
                  update_needed = true;
                }
                // If the data being updated is
                // selected then update details
                row = model.findRow(data);
                if ((row != -1) && (row == selected)) {
                  update_needed = true;
                }
                // Set the response and update table
                data.setSOAPResponse(soap);
                model.updateData(data);
                // Refresh details area (if needed)
                if (update_needed) {
                  valueChanged(null);
                }
              }
              break;
          }

        } catch (Exception e) {
          // Exceptions are expected here when the
          // server communication has been terminated.
          if (stop_button.isEnabled()) {
            stop();
            setErrorStatus(STATUS_CLOSED);
          }
        }
      }
    }