From 7a699cd280172e9fe437e3a804ef741340cae4c2 Mon Sep 17 00:00:00 2001 From: GustavoHMDS Date: Wed, 7 Oct 2026 17:13:03 -0300 Subject: [PATCH] Arquivos faltando no commit anterior --- pitiupi.mpChat/.idea/.gitignore | 5 + pitiupi.mpChat/.idea/misc.xml | 5 + pitiupi.mpChat/.idea/modules.xml | 8 + pitiupi.mpChat/.idea/vcs.xml | 6 + .../META-INF/services/pitiupi.models.Plugin | 1 + pitiupi.mpChat/src/GUI/PrivateChatWindow.java | 194 ++++++++++++++++-- pitiupi.mpChat/src/GUI/PublicChatWindow.java | 155 ++++++++++++-- pitiupi.mpChat/src/GUI/UnicastMpChatMenu.java | 23 ++- .../src/plugin/MultiProtocolChat.java | 58 +++--- 9 files changed, 395 insertions(+), 60 deletions(-) create mode 100644 pitiupi.mpChat/.idea/.gitignore create mode 100644 pitiupi.mpChat/.idea/misc.xml create mode 100644 pitiupi.mpChat/.idea/modules.xml create mode 100644 pitiupi.mpChat/.idea/vcs.xml create mode 100644 pitiupi.mpChat/out/META-INF/services/pitiupi.models.Plugin diff --git a/pitiupi.mpChat/.idea/.gitignore b/pitiupi.mpChat/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/pitiupi.mpChat/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/pitiupi.mpChat/.idea/misc.xml b/pitiupi.mpChat/.idea/misc.xml new file mode 100644 index 0000000..8547fc5 --- /dev/null +++ b/pitiupi.mpChat/.idea/misc.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/pitiupi.mpChat/.idea/modules.xml b/pitiupi.mpChat/.idea/modules.xml new file mode 100644 index 0000000..93aa0d1 --- /dev/null +++ b/pitiupi.mpChat/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/pitiupi.mpChat/.idea/vcs.xml b/pitiupi.mpChat/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/pitiupi.mpChat/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pitiupi.mpChat/out/META-INF/services/pitiupi.models.Plugin b/pitiupi.mpChat/out/META-INF/services/pitiupi.models.Plugin new file mode 100644 index 0000000..3240a6f --- /dev/null +++ b/pitiupi.mpChat/out/META-INF/services/pitiupi.models.Plugin @@ -0,0 +1 @@ +plugin.MultiProtocolChat diff --git a/pitiupi.mpChat/src/GUI/PrivateChatWindow.java b/pitiupi.mpChat/src/GUI/PrivateChatWindow.java index ad60dc4..d811a9b 100644 --- a/pitiupi.mpChat/src/GUI/PrivateChatWindow.java +++ b/pitiupi.mpChat/src/GUI/PrivateChatWindow.java @@ -3,41 +3,199 @@ package GUI; import net.MpChatMessage; import pitiupi.control.ConnectionManager; import pitiupi.net.tcp.TcpConnection; +import pitiupi.plugin.Pitiupi; import javax.swing.*; import java.awt.*; +import java.net.InetAddress; +import java.util.HashMap; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -public class PrivateChatWindow extends ChatWindow { +public class PrivateChatWindow extends JFrame { - private final TcpConnection connection; + private final Pitiupi pitiupi; - public PrivateChatWindow(ConnectionManager ConnectionManager, TcpConnection connection) { - super(ConnectionManager); - this.connection = connection; + private final Map chats; + + private final JPanel chatPanel; + private final CardLayout cardLayout; + + private final DefaultListModel connectionListModel; + private final JList connectionList; + + public PrivateChatWindow(Pitiupi pitiupi) { + this.pitiupi = pitiupi; + this.chats = new HashMap<>(); + + setTitle("Chats privados"); + setSize(700, 500); + setLocationRelativeTo(null); + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + + JPanel mainPanel = new JPanel(new BorderLayout(10, 10)); + mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + connectionListModel = new DefaultListModel<>(); + connectionList = new JList<>(connectionListModel); + + connectionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + connectionList.setPreferredSize(new Dimension(180, 0)); + + connectionList.addListSelectionListener(e -> { + if (!e.getValueIsAdjusting()) { + TcpConnection connection = connectionList.getSelectedValue(); + + if (connection != null) { + showChat(connection); + } + } + }); + + JScrollPane connectionScrollPane = new JScrollPane(connectionList); + connectionScrollPane.setBorder( + BorderFactory.createTitledBorder("Usuários") + ); + + mainPanel.add(connectionScrollPane, BorderLayout.WEST); + + cardLayout = new CardLayout(); + chatPanel = new JPanel(cardLayout); + + mainPanel.add(chatPanel, BorderLayout.CENTER); + + setContentPane(mainPanel); } - @Override - protected void initButtons(JPanel bottomPanel) { - JButton tcpButton = new JButton("TCP"); + public void addConnection(TcpConnection connection) { + if (chats.containsKey(connection)) { + return; + } - tcpButton.addActionListener(e -> sendTCP()); + PrivateChatPanel panel = new PrivateChatPanel(connection); - JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0)); + chats.put(connection, panel); + connectionListModel.addElement(connection); - buttonsPanel.add(tcpButton); + String cardName = getCardName(connection); + chatPanel.add(panel, cardName); - bottomPanel.add(buttonsPanel, BorderLayout.EAST); + if (connectionList.getSelectedValue() == null) { + connectionList.setSelectedValue(connection, true); + } } - private void sendTCP() { - try { - MpChatMessage msg = createMessage("TCP Private"); - connection.send(msg.toByteArray()); + public void removeConnection(TcpConnection connection) { + PrivateChatPanel panel = chats.remove(connection); - } catch (Exception ex) { - Logger.getLogger(PrivateChatWindow.class.getName()).log(Level.SEVERE, null, ex); + if (panel == null) { + return; + } + + chatPanel.remove(panel); + connectionListModel.removeElement(connection); + + if (!connectionListModel.isEmpty()) { + connectionList.setSelectedIndex(0); + } + } + + public void receiveMessage(TcpConnection connection, MpChatMessage message) { + PrivateChatPanel panel = chats.get(connection); + + if (panel == null) { + return; + } + + panel.receiveMessage(message); + } + + private void showChat(TcpConnection connection) { + cardLayout.show(chatPanel, getCardName(connection)); + } + + private String getCardName(TcpConnection connection) { + return Integer.toHexString(System.identityHashCode(connection)); + } + + private class PrivateChatPanel extends JPanel { + + private final TcpConnection connection; + + private final JTextArea receivedMessagesArea; + private final JTextField messageField; + + public PrivateChatPanel(TcpConnection connection) { + this.connection = connection; + + setLayout(new BorderLayout(10, 10)); + + receivedMessagesArea = new JTextArea(); + receivedMessagesArea.setEditable(false); + receivedMessagesArea.setLineWrap(true); + receivedMessagesArea.setWrapStyleWord(true); + + JScrollPane messagesScrollPane = + new JScrollPane(receivedMessagesArea); + + messagesScrollPane.setBorder( + BorderFactory.createTitledBorder("Mensagens") + ); + + add(messagesScrollPane, BorderLayout.CENTER); + + JPanel bottomPanel = new JPanel(new BorderLayout(10, 10)); + + messageField = new JTextField(); + + JButton tcpButton = new JButton("TCP"); + tcpButton.addActionListener(e -> sendTCP()); + + bottomPanel.add(messageField, BorderLayout.CENTER); + bottomPanel.add(tcpButton, BorderLayout.EAST); + + add(bottomPanel, BorderLayout.SOUTH); + } + + private void sendTCP() { + try { + String nome = pitiupi.getUserName(); + + MpChatMessage message = new MpChatMessage( + nome, + InetAddress.getLocalHost().toString(), + "TCP Private", + messageField.getText() + ); + + connection.send(message.toByteArray()); + + messageField.setText(""); + + } catch (Exception ex) { + Logger.getLogger( + PrivateChatWindow.class.getName() + ).log(Level.SEVERE, null, ex); + } + } + + public void receiveMessage(MpChatMessage message) { + SwingUtilities.invokeLater(() -> { + String texto = String.format( + "[%s] %s (%s): %s%n", + message.getTipoMensagem(), + message.getNome(), + message.getIp(), + message.getMessage() + ); + + receivedMessagesArea.append(texto); + + receivedMessagesArea.setCaretPosition( + receivedMessagesArea.getDocument().getLength() + ); + }); } } } diff --git a/pitiupi.mpChat/src/GUI/PublicChatWindow.java b/pitiupi.mpChat/src/GUI/PublicChatWindow.java index ff6967e..3599eb8 100644 --- a/pitiupi.mpChat/src/GUI/PublicChatWindow.java +++ b/pitiupi.mpChat/src/GUI/PublicChatWindow.java @@ -2,36 +2,95 @@ package GUI; import net.MpChatMessage; import pitiupi.control.ConnectionManager; +import pitiupi.plugin.Pitiupi; import javax.swing.*; +import javax.swing.text.BadLocationException; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; import java.awt.*; import java.net.InetAddress; import java.util.logging.Level; import java.util.logging.Logger; -public class PublicChatWindow extends ChatWindow { +public class PublicChatWindow extends JFrame { + private final Pitiupi pitiupi; + private JTextPane receivedMessagesArea; + private JTextField messageField; private JTextField ipField; - public PublicChatWindow(ConnectionManager connectionManager) { - super(connectionManager); + public PublicChatWindow(Pitiupi pitiupi) { + this.pitiupi = pitiupi; + + initComponents(); } - @Override - protected void initButtons(JPanel bottomPanel) { + private void initComponents() { + setTitle("Public Chat"); + setSize(700, 500); + setLocationRelativeTo(null); + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + + JPanel mainPanel = new JPanel(new BorderLayout(10, 10)); + + mainPanel.setBorder( + BorderFactory.createEmptyBorder(10, 10, 10, 10) + ); + + initReceivedMessagesPanel(mainPanel); + initBottomPanel(mainPanel); + + setContentPane(mainPanel); + } + + private void initReceivedMessagesPanel(JPanel mainPanel) { + receivedMessagesArea = new JTextPane(); + + receivedMessagesArea.setEditable(false); + + JScrollPane messagesScrollPane = new JScrollPane(receivedMessagesArea); + + messagesScrollPane.setBorder( + BorderFactory.createTitledBorder("Mensagens recebidas") + ); + + mainPanel.add(messagesScrollPane, BorderLayout.CENTER); + } + + private void initBottomPanel(JPanel mainPanel) { + messageField = new JTextField(); + + JPanel bottomPanel = new JPanel( + new BorderLayout(10, 10) + ); + + bottomPanel.add(messageField, BorderLayout.CENTER); + initIpField(bottomPanel); initCommunicationButtons(bottomPanel); + + mainPanel.add(bottomPanel, BorderLayout.SOUTH); } private void initIpField(JPanel bottomPanel) { ipField = new JTextField(); ipField.setPreferredSize(new Dimension(130, 30)); - JPanel ipPanel = new JPanel(new BorderLayout(5, 5)); + JPanel ipPanel = new JPanel( + new BorderLayout(5, 5) + ); - ipPanel.add(new JLabel("IP destino:"), BorderLayout.WEST); + ipPanel.add( + new JLabel("IP destino:"), + BorderLayout.WEST + ); - ipPanel.add(ipField, BorderLayout.CENTER); + ipPanel.add( + ipField, + BorderLayout.CENTER + ); bottomPanel.add(ipPanel, BorderLayout.WEST); } @@ -45,13 +104,71 @@ public class PublicChatWindow extends ChatWindow { udpButton.addActionListener(e -> sendUDP()); multicastButton.addActionListener(e -> sendMulticast()); - JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0)); + JPanel buttonsPanel = new JPanel( + new FlowLayout(FlowLayout.RIGHT, 5, 0) + ); buttonsPanel.add(tcpButton); buttonsPanel.add(udpButton); buttonsPanel.add(multicastButton); - bottomPanel.add(buttonsPanel, BorderLayout.EAST); + bottomPanel.add( + buttonsPanel, + BorderLayout.EAST + ); + } + + private MpChatMessage createMessage(String tipoMensagem) { + try { + String nome = pitiupi.getUserName(); + String ip = InetAddress.getLocalHost().getHostAddress(); + String message = messageField.getText(); + + return new MpChatMessage( + nome, + ip, + tipoMensagem, + message + ); + + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + public void receiveMessage(MpChatMessage msg) { + SwingUtilities.invokeLater(() -> { + String mensagem = String.format( + "[%s] %s (%s): %s%n", + msg.getTipoMensagem(), + msg.getNome(), + msg.getIp(), + msg.getMessage() + ); + + StyledDocument document = receivedMessagesArea.getStyledDocument(); + + SimpleAttributeSet attributes = new SimpleAttributeSet(); + + if (msg.getTipoMensagem().equals("TCP Unicast") || msg.getTipoMensagem().equals("UDP Unicast")) { + StyleConstants.setForeground(attributes, new Color(128, 0, 128)); + } + + try { + document.insertString( + document.getLength(), + mensagem, + attributes + ); + + receivedMessagesArea.setCaretPosition( + document.getLength() + ); + + } catch (BadLocationException ex) { + Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex); + } + }); } private void sendTCP() { @@ -60,10 +177,12 @@ public class PublicChatWindow extends ChatWindow { InetAddress ip = InetAddress.getByName(ipField.getText()); - connectionManager.sendTcp(msg, ip); + pitiupi.sendTcp(msg, ip); } catch (Exception ex) { - Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex); + Logger.getLogger( + PublicChatWindow.class.getName() + ).log(Level.SEVERE, null, ex); } } @@ -73,10 +192,12 @@ public class PublicChatWindow extends ChatWindow { InetAddress ip = InetAddress.getByName(ipField.getText()); - connectionManager.sendUdpUnicast(msg, ip); + pitiupi.sendUdpUnicast(msg, ip); } catch (Exception ex) { - Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex); + Logger.getLogger( + PublicChatWindow.class.getName() + ).log(Level.SEVERE, null, ex); } } @@ -84,10 +205,12 @@ public class PublicChatWindow extends ChatWindow { try { MpChatMessage msg = createMessage("UDP Multicast"); - connectionManager.sendUdpMulticast(msg); + pitiupi.sendUdpMulticast(msg); } catch (Exception ex) { - Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex); + Logger.getLogger( + PublicChatWindow.class.getName() + ).log(Level.SEVERE, null, ex); } } } \ No newline at end of file diff --git a/pitiupi.mpChat/src/GUI/UnicastMpChatMenu.java b/pitiupi.mpChat/src/GUI/UnicastMpChatMenu.java index 52cc699..a1816f9 100644 --- a/pitiupi.mpChat/src/GUI/UnicastMpChatMenu.java +++ b/pitiupi.mpChat/src/GUI/UnicastMpChatMenu.java @@ -1,4 +1,25 @@ package GUI; -public class UnicastMpChatMenu { +import pitiupi.models.Menus.UnicastMenus.UnicastActionMenu; +import pitiupi.models.User; +import plugin.MultiProtocolChat; + +import javax.swing.*; + +public class UnicastMpChatMenu extends UnicastActionMenu { + private final MultiProtocolChat multiProtocolChat; + + public UnicastMpChatMenu(MultiProtocolChat multiProtocolChat) { + this.multiProtocolChat = multiProtocolChat; + } + + @Override + public void onClick(User user) { + multiProtocolChat.openConnection(user.getAddress().toString()); + } + + @Override + public String getText() { + return "start Private Chat"; + } } diff --git a/pitiupi.mpChat/src/plugin/MultiProtocolChat.java b/pitiupi.mpChat/src/plugin/MultiProtocolChat.java index a9999bd..766f973 100644 --- a/pitiupi.mpChat/src/plugin/MultiProtocolChat.java +++ b/pitiupi.mpChat/src/plugin/MultiProtocolChat.java @@ -1,24 +1,28 @@ package plugin; -import GUI.ChatMenu; -import control.ChatController; +import GUI.MulticastMpChatMenu; +import GUI.PrivateChatWindow; +import GUI.PublicChatWindow; +import GUI.UnicastMpChatMenu; import net.MpChatMessage; -import pitiupi.control.ConnectionManager; -import pitiupi.control.GuiManager; +import pitiupi.models.Menus.MenuCategory; import pitiupi.models.Messages.Message; import pitiupi.net.tcp.TcpConnection; import pitiupi.models.Plugin; +import pitiupi.plugin.Pitiupi; import javax.swing.*; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.net.InetAddress; +import java.util.List; public class MultiProtocolChat extends Plugin { - ChatController chatController; - ConnectionManager connectionManager; - GuiManager guiManager; + Pitiupi pitiupi; + + PublicChatWindow publicChatWindow; + PrivateChatWindow privateChatWindow; @Override public String getName() { @@ -41,30 +45,36 @@ public class MultiProtocolChat extends Plugin { } @Override - public void createPlugin(ConnectionManager connectionManager, GuiManager guiManager) { - this.connectionManager = connectionManager; - this.guiManager = guiManager; + public void createPlugin(Pitiupi pitiupi) { + this.pitiupi = pitiupi; - ChatMenu chatMenu = new ChatMenu(this); - chatController = new ChatController(connectionManager, chatMenu); - guiManager.addMulticastMenu(chatMenu); + publicChatWindow = new PublicChatWindow(pitiupi); + privateChatWindow = new PrivateChatWindow(pitiupi); + + MulticastMpChatMenu multicastMpChatMenu = new MulticastMpChatMenu(publicChatWindow); + UnicastMpChatMenu unicastMpChatMenu = new UnicastMpChatMenu(this); + + pitiupi.createMenu(MenuCategory.Social, multicastMpChatMenu); + pitiupi.createMenu(MenuCategory.Social, unicastMpChatMenu); } @Override - public Message getMessage() { - return new MpChatMessage(); + public List> getMessages() { + return List.of(MpChatMessage.class); } @Override - public void receiveMessage(byte[] message) { - MpChatMessage mpChatMessage = parseMessage(message); - chatController.receivePublic(mpChatMessage); + public void receiveMessage(Message message) { + if (message instanceof MpChatMessage mpChatMessage) { + publicChatWindow.receiveMessage(mpChatMessage); + } } + @Override public boolean receivePrivateConnection(TcpConnection connection) { SwingUtilities.invokeLater(() -> { - chatController.addChatWindow(connection); + privateChatWindow.addConnection(connection); }); return true; } @@ -72,25 +82,23 @@ public class MultiProtocolChat extends Plugin { @Override public boolean receiveBytes(TcpConnection connection, byte[] bytes) { MpChatMessage mpChatMessage = parseMessage(bytes); - chatController.receivePrivate(connection, mpChatMessage); + privateChatWindow.receiveMessage(connection, mpChatMessage); return true; } @Override public boolean onSocketClosed(TcpConnection connection) { - chatController.removeChatWindow(connection); + privateChatWindow.removeConnection(connection); return true; } - public boolean openConnection(String ip) { + public void openConnection(String ip) { try { - connectionManager.connectPluginTcp(InetAddress.getByName(ip), getIdentifier(), getIdentifier()); - return true; + pitiupi.connectTcp(InetAddress.getByName(ip), getIdentifier(), getIdentifier()); } catch (Exception e) { System.out.println("Error opening connection: " + e.getMessage()); } - return false; } private MpChatMessage parseMessage(byte[] bytes) {