public Reader newConnectionReader(Reader newReader) {
   ((ObservableReader) reader).removeReaderListener(readerListener);
   ObservableReader debugReader = new ObservableReader(newReader);
   debugReader.addReaderListener(readerListener);
   reader = debugReader;
   return reader;
 }
 /** 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;
 }
  /** Creates the debug process, which is a GUI window that displays XML traffic. */
  private void createDebug() {
    frame =
        new JFrame(
            "Smack Debug Window -- " + connection.getServiceName() + ":" + connection.getPort());

    // Add listener for window closing event
    frame.addWindowListener(
        new WindowAdapter() {
          public void windowClosing(WindowEvent evt) {
            rootWindowClosing(evt);
          }
        });

    // We'll arrange the UI into four tabs. The first tab contains all data, the second
    // client generated XML, the third server generated XML, and the fourth is packet
    // data from the server as seen by Smack.
    JTabbedPane tabbedPane = new JTabbedPane();

    JPanel allPane = new JPanel();
    allPane.setLayout(new GridLayout(3, 1));
    tabbedPane.add("All", allPane);

    // Create UI elements for client generated XML traffic.
    final JTextArea sentText1 = new JTextArea();
    final JTextArea sentText2 = new JTextArea();
    sentText1.setEditable(false);
    sentText2.setEditable(false);
    sentText1.setForeground(new Color(112, 3, 3));
    sentText2.setForeground(new Color(112, 3, 3));
    allPane.add(new JScrollPane(sentText1));
    tabbedPane.add("Sent", new JScrollPane(sentText2));

    // 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(sentText1.getText()), null);
          }
        });

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

    // Add listener to the text area so the popup menu can come up.
    MouseListener popupListener = new PopupListener(menu);
    sentText1.addMouseListener(popupListener);
    sentText2.addMouseListener(popupListener);
    menu.add(menuItem1);
    menu.add(menuItem2);

    // Create UI elements for server generated XML traffic.
    final JTextArea receivedText1 = new JTextArea();
    final JTextArea receivedText2 = new JTextArea();
    receivedText1.setEditable(false);
    receivedText2.setEditable(false);
    receivedText1.setForeground(new Color(6, 76, 133));
    receivedText2.setForeground(new Color(6, 76, 133));
    allPane.add(new JScrollPane(receivedText1));
    tabbedPane.add("Received", new JScrollPane(receivedText2));

    // 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(receivedText1.getText()), null);
          }
        });

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

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

    // Create UI elements for interpreted XML traffic.
    final JTextArea interpretedText1 = new JTextArea();
    final JTextArea interpretedText2 = new JTextArea();
    interpretedText1.setEditable(false);
    interpretedText2.setEditable(false);
    interpretedText1.setForeground(new Color(1, 94, 35));
    interpretedText2.setForeground(new Color(1, 94, 35));
    allPane.add(new JScrollPane(interpretedText1));
    tabbedPane.add("Interpreted", new JScrollPane(interpretedText2));

    // 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(interpretedText1.getText()), null);
          }
        });

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

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

    frame.getContentPane().add(tabbedPane);

    frame.setSize(550, 400);
    frame.setVisible(true);

    // 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(String str) {
            int index = str.lastIndexOf(">");
            if (index != -1) {
              receivedText1.append(str.substring(0, index + 1));
              receivedText2.append(str.substring(0, index + 1));
              receivedText1.append(NEWLINE);
              receivedText2.append(NEWLINE);
              if (str.length() > index) {
                receivedText1.append(str.substring(index + 1));
                receivedText2.append(str.substring(index + 1));
              }
            } else {
              receivedText1.append(str);
              receivedText2.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(String str) {
            sentText1.append(str);
            sentText2.append(str);
            if (str.endsWith(">")) {
              sentText1.append(NEWLINE);
              sentText2.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;

    // Create a thread that will listen for all incoming packets and write them to
    // the GUI. This is what we call "interpreted" packet data, since it's the packet
    // data as Smack sees it and not as it's coming in as raw XML.
    listener =
        new PacketListener() {
          public void processPacket(Packet packet) {
            interpretedText1.append(packet.toXML());
            interpretedText2.append(packet.toXML());
            interpretedText1.append(NEWLINE);
            interpretedText2.append(NEWLINE);
          }
        };
  }
  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;
  }
 /**
  * Notification that the root window is closing. Stop listening for received and transmitted
  * packets.
  *
  * @param evt the event that indicates that the root window is closing
  */
 public void rootWindowClosing(WindowEvent evt) {
   connection.removePacketListener(listener);
   ((ObservableReader) reader).removeReaderListener(readerListener);
   ((ObservableWriter) writer).removeWriterListener(writerListener);
 }