public Writer newConnectionWriter(Writer newWriter) {
   ((ObservableWriter) writer).removeWriterListener(writerListener);
   ObservableWriter debugWriter = new ObservableWriter(newWriter);
   debugWriter.addWriterListener(writerListener);
   writer = debugWriter;
   return writer;
 }
 /** Stops debugging the connection. Removes any listener on the connection. */
 void cancel() {
   connection.removeConnectionListener(connListener);
   connection.removePacketListener(packetReaderListener);
   connection.removePacketSendingListener(packetWriterListener);
   ((ObservableReader) reader).removeReaderListener(readerListener);
   ((ObservableWriter) writer).removeWriterListener(writerListener);
   messagesTable = null;
 }
  private void addBasicPanels() {
    JSplitPane allPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
    allPane.setOneTouchExpandable(true);

    messagesTable =
        new DefaultTableModel(
            new Object[] {"Hide", "Timestamp", "", "", "Message", "Id", "Type", "To", "From"}, 0) {
          private static final long serialVersionUID = 8136121224474217264L;

          public boolean isCellEditable(int rowIndex, int mColIndex) {
            return false;
          }

          public Class<?> getColumnClass(int columnIndex) {
            if (columnIndex == 2 || columnIndex == 3) {
              return Icon.class;
            }
            return super.getColumnClass(columnIndex);
          }
        };
    JTable table = new JTable(messagesTable);
    // Allow only single a selection
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    // Hide the first column
    table.getColumnModel().getColumn(0).setMaxWidth(0);
    table.getColumnModel().getColumn(0).setMinWidth(0);
    table.getTableHeader().getColumnModel().getColumn(0).setMaxWidth(0);
    table.getTableHeader().getColumnModel().getColumn(0).setMinWidth(0);
    // Set the column "timestamp" size
    table.getColumnModel().getColumn(1).setMaxWidth(300);
    table.getColumnModel().getColumn(1).setPreferredWidth(90);
    // Set the column "direction" icon size
    table.getColumnModel().getColumn(2).setMaxWidth(50);
    table.getColumnModel().getColumn(2).setPreferredWidth(30);
    // Set the column "packet type" icon size
    table.getColumnModel().getColumn(3).setMaxWidth(50);
    table.getColumnModel().getColumn(3).setPreferredWidth(30);
    // Set the column "Id" size
    table.getColumnModel().getColumn(5).setMaxWidth(100);
    table.getColumnModel().getColumn(5).setPreferredWidth(55);
    // Set the column "type" size
    table.getColumnModel().getColumn(6).setMaxWidth(200);
    table.getColumnModel().getColumn(6).setPreferredWidth(50);
    // Set the column "to" size
    table.getColumnModel().getColumn(7).setMaxWidth(300);
    table.getColumnModel().getColumn(7).setPreferredWidth(90);
    // Set the column "from" size
    table.getColumnModel().getColumn(8).setMaxWidth(300);
    table.getColumnModel().getColumn(8).setPreferredWidth(90);
    // Create a table listener that listen for row selection events
    SelectionListener selectionListener = new SelectionListener(table);
    table.getSelectionModel().addListSelectionListener(selectionListener);
    table.getColumnModel().getSelectionModel().addListSelectionListener(selectionListener);
    allPane.setTopComponent(new JScrollPane(table));
    messageTextArea = new JTextArea();
    messageTextArea.setEditable(false);
    // Add pop-up menu.
    JPopupMenu menu = new JPopupMenu();
    JMenuItem menuItem1 = new JMenuItem("Copy");
    menuItem1.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // Get the clipboard
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            // Set the sent text as the new content of the clipboard
            clipboard.setContents(new StringSelection(messageTextArea.getText()), null);
          }
        });
    menu.add(menuItem1);
    // Add listener to the text area so the popup menu can come up.
    messageTextArea.addMouseListener(new PopupListener(menu));
    JPanel sublayout = new JPanel(new BorderLayout());
    sublayout.add(new JScrollPane(messageTextArea), BorderLayout.CENTER);

    JButton clearb = new JButton("Clear All Packets");

    clearb.addActionListener(
        new AbstractAction() {
          private static final long serialVersionUID = -8576045822764763613L;

          @Override
          public void actionPerformed(ActionEvent e) {
            messagesTable.setRowCount(0);
          }
        });

    sublayout.add(clearb, BorderLayout.NORTH);
    allPane.setBottomComponent(sublayout);

    allPane.setDividerLocation(150);

    tabbedPane.add("All Packets", allPane);
    tabbedPane.setToolTipTextAt(0, "Sent and received packets processed by Smack");

    // Create UI elements for client generated XML traffic.
    final JTextArea sentText = new JTextArea();
    sentText.setWrapStyleWord(true);
    sentText.setLineWrap(true);
    sentText.setEditable(false);
    sentText.setForeground(new Color(112, 3, 3));
    tabbedPane.add("Raw Sent Packets", new JScrollPane(sentText));
    tabbedPane.setToolTipTextAt(1, "Raw text of the sent packets");

    // Add pop-up menu.
    menu = new JPopupMenu();
    menuItem1 = new JMenuItem("Copy");
    menuItem1.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // Get the clipboard
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            // Set the sent text as the new content of the clipboard
            clipboard.setContents(new StringSelection(sentText.getText()), null);
          }
        });

    JMenuItem menuItem2 = new JMenuItem("Clear");
    menuItem2.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            sentText.setText("");
          }
        });

    // Add listener to the text area so the popup menu can come up.
    sentText.addMouseListener(new PopupListener(menu));
    menu.add(menuItem1);
    menu.add(menuItem2);

    // Create UI elements for server generated XML traffic.
    final JTextArea receivedText = new JTextArea();
    receivedText.setWrapStyleWord(true);
    receivedText.setLineWrap(true);
    receivedText.setEditable(false);
    receivedText.setForeground(new Color(6, 76, 133));
    tabbedPane.add("Raw Received Packets", new JScrollPane(receivedText));
    tabbedPane.setToolTipTextAt(2, "Raw text of the received packets before Smack process them");

    // Add pop-up menu.
    menu = new JPopupMenu();
    menuItem1 = new JMenuItem("Copy");
    menuItem1.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // Get the clipboard
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            // Set the sent text as the new content of the clipboard
            clipboard.setContents(new StringSelection(receivedText.getText()), null);
          }
        });

    menuItem2 = new JMenuItem("Clear");
    menuItem2.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            receivedText.setText("");
          }
        });

    // Add listener to the text area so the popup menu can come up.
    receivedText.addMouseListener(new PopupListener(menu));
    menu.add(menuItem1);
    menu.add(menuItem2);

    // Create a special Reader that wraps the main Reader and logs data to the GUI.
    ObservableReader debugReader = new ObservableReader(reader);
    readerListener =
        new ReaderListener() {
          public void read(final String str) {
            SwingUtilities.invokeLater(
                new Runnable() {
                  public void run() {
                    if (EnhancedDebuggerWindow.PERSISTED_DEBUGGER
                        && !EnhancedDebuggerWindow.getInstance().isVisible()) {
                      // Do not add content if the parent is not visible
                      return;
                    }

                    int index = str.lastIndexOf(">");
                    if (index != -1) {
                      if (receivedText.getLineCount() >= EnhancedDebuggerWindow.MAX_TABLE_ROWS) {
                        try {
                          receivedText.replaceRange("", 0, receivedText.getLineEndOffset(0));
                        } catch (BadLocationException e) {
                          e.printStackTrace();
                        }
                      }
                      receivedText.append(str.substring(0, index + 1));
                      receivedText.append(NEWLINE);
                      if (str.length() > index) {
                        receivedText.append(str.substring(index + 1));
                      }
                    } else {
                      receivedText.append(str);
                    }
                  }
                });
          }
        };
    debugReader.addReaderListener(readerListener);

    // Create a special Writer that wraps the main Writer and logs data to the GUI.
    ObservableWriter debugWriter = new ObservableWriter(writer);
    writerListener =
        new WriterListener() {
          public void write(final String str) {
            SwingUtilities.invokeLater(
                new Runnable() {
                  public void run() {
                    if (EnhancedDebuggerWindow.PERSISTED_DEBUGGER
                        && !EnhancedDebuggerWindow.getInstance().isVisible()) {
                      // Do not add content if the parent is not visible
                      return;
                    }

                    if (sentText.getLineCount() >= EnhancedDebuggerWindow.MAX_TABLE_ROWS) {
                      try {
                        sentText.replaceRange("", 0, sentText.getLineEndOffset(0));
                      } catch (BadLocationException e) {
                        e.printStackTrace();
                      }
                    }

                    sentText.append(str);
                    if (str.endsWith(">")) {
                      sentText.append(NEWLINE);
                    }
                  }
                });
          }
        };
    debugWriter.addWriterListener(writerListener);

    // Assign the reader/writer objects to use the debug versions. The packet reader
    // and writer will use the debug versions when they are created.
    reader = debugReader;
    writer = debugWriter;
  }