BugFix e atualização da interface no mpChat

This commit is contained in:
GustavoHMDS committed 2026-10-07 19:31:37 -03:00
1 parent 7a699cd280
commit 581a924afc
8 files changed
+176 -133

No files matched your search

@@ -0,0 +1 @@
plugin.MultiProtocolChat
+37 -117
View File
@@ -1,135 +1,39 @@
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 JFrame {
private final Pitiupi pitiupi;
private final Map<TcpConnection, PrivateChatPanel> chats;
private final JPanel chatPanel;
private final CardLayout cardLayout;
private final DefaultListModel<TcpConnection> connectionListModel;
private final JList<TcpConnection> 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);
}
public void addConnection(TcpConnection connection) {
if (chats.containsKey(connection)) {
return;
}
PrivateChatPanel panel = new PrivateChatPanel(connection);
chats.put(connection, panel);
connectionListModel.addElement(connection);
String cardName = getCardName(connection);
chatPanel.add(panel, cardName);
if (connectionList.getSelectedValue() == null) {
connectionList.setSelectedValue(connection, true);
}
}
public void removeConnection(TcpConnection connection) {
PrivateChatPanel panel = chats.remove(connection);
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) {
public PrivateChatWindow(
Pitiupi pitiupi,
TcpConnection connection
) {
this.pitiupi = pitiupi;
this.connection = connection;
setLayout(new BorderLayout(10, 10));
setTitle("Chat privado");
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)
);
receivedMessagesArea = new JTextArea();
receivedMessagesArea.setEditable(false);
@@ -143,19 +47,36 @@ public class PrivateChatWindow extends JFrame {
BorderFactory.createTitledBorder("Mensagens")
);
add(messagesScrollPane, BorderLayout.CENTER);
mainPanel.add(
messagesScrollPane,
BorderLayout.CENTER
);
JPanel bottomPanel = new JPanel(new BorderLayout(10, 10));
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);
bottomPanel.add(
messageField,
BorderLayout.CENTER
);
add(bottomPanel, BorderLayout.SOUTH);
bottomPanel.add(
tcpButton,
BorderLayout.EAST
);
mainPanel.add(
bottomPanel,
BorderLayout.SOUTH
);
setContentPane(mainPanel);
}
private void sendTCP() {
@@ -164,7 +85,7 @@ public class PrivateChatWindow extends JFrame {
MpChatMessage message = new MpChatMessage(
nome,
InetAddress.getLocalHost().toString(),
InetAddress.getLocalHost().getHostAddress(),
"TCP Private",
messageField.getText()
);
@@ -198,4 +119,3 @@ public class PrivateChatWindow extends JFrame {
});
}
}
}
@@ -1,25 +1,26 @@
package GUI;
import control.PrivateChatController;
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;
private final PrivateChatController controller;
public UnicastMpChatMenu(
PrivateChatController controller
) {
this.controller = controller;
}
@Override
public void onClick(User user) {
multiProtocolChat.openConnection(user.getAddress().toString());
controller.openChat(user);
}
@Override
public String getText() {
return "start Private Chat";
return "Start Private Chat";
}
}
@@ -0,0 +1,116 @@
package control;
import GUI.PrivateChatWindow;
import net.MpChatMessage;
import pitiupi.models.User;
import pitiupi.net.tcp.TcpConnection;
import pitiupi.plugin.Pitiupi;
import plugin.MultiProtocolChat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class PrivateChatController {
private final Pitiupi pitiupi;
private final MultiProtocolChat multiProtocolChat;
/*
* Relaciona o endereço do usuário à janela de chat.
*/
private final Map<String, PrivateChatWindow> windows;
/*
* Endereços para os quais uma conexão já foi solicitada,
* mas ainda não chegou.
*/
private final Set<String> pendingConnections;
public PrivateChatController(
Pitiupi pitiupi,
MultiProtocolChat multiProtocolChat
) {
this.pitiupi = pitiupi;
this.multiProtocolChat = multiProtocolChat;
this.windows = new HashMap<>();
this.pendingConnections = new HashSet<>();
}
public void openChat(User user) {
String address = user.getAddress().getHostAddress();
PrivateChatWindow window = windows.get(address);
/*
* Já existe uma janela para esse usuário.
*/
if (window != null) {
window.setVisible(true);
window.toFront();
window.requestFocus();
return;
}
/*
* Já estamos esperando uma conexão para esse usuário.
*/
if (pendingConnections.contains(address)) {
return;
}
/*
* Ainda não existe conexão.
*/
pendingConnections.add(address);
multiProtocolChat.openConnection(address);
}
public void receiveMessage(TcpConnection connection, MpChatMessage message) {
String address = connection.getAddress().toString();
PrivateChatWindow window = windows.get(address);
if (window == null) {
return;
}
window.receiveMessage(message);
}
/**
* Deve ser chamado quando uma nova conexão privada chegar.
*/
public void connectionReceived(TcpConnection connection) {
String address = connection.getAddress().toString();
pendingConnections.remove(address);
PrivateChatWindow window = new PrivateChatWindow(
pitiupi,
connection
);
windows.put(address, window);
window.setVisible(true);
window.toFront();
window.requestFocus();
}
/**
* Fecha a janela e remove o relacionamento.
*/
public void closeChat(TcpConnection connection) {
String address = connection.getAddress().toString();
PrivateChatWindow window = windows.remove(address);
if (window != null) {
window.dispose();
}
}
}
@@ -4,6 +4,7 @@ import GUI.MulticastMpChatMenu;
import GUI.PrivateChatWindow;
import GUI.PublicChatWindow;
import GUI.UnicastMpChatMenu;
import control.PrivateChatController;
import net.MpChatMessage;
import pitiupi.models.Menus.MenuCategory;
import pitiupi.models.Messages.Message;
@@ -21,8 +22,8 @@ import java.util.List;
public class MultiProtocolChat extends Plugin {
Pitiupi pitiupi;
PrivateChatController privateChatController;
PublicChatWindow publicChatWindow;
PrivateChatWindow privateChatWindow;
@Override
public String getName() {
@@ -48,11 +49,12 @@ public class MultiProtocolChat extends Plugin {
public void createPlugin(Pitiupi pitiupi) {
this.pitiupi = pitiupi;
privateChatController = new PrivateChatController(pitiupi, this);
publicChatWindow = new PublicChatWindow(pitiupi);
privateChatWindow = new PrivateChatWindow(pitiupi);
MulticastMpChatMenu multicastMpChatMenu = new MulticastMpChatMenu(publicChatWindow);
UnicastMpChatMenu unicastMpChatMenu = new UnicastMpChatMenu(this);
UnicastMpChatMenu unicastMpChatMenu = new UnicastMpChatMenu(privateChatController);
pitiupi.createMenu(MenuCategory.Social, multicastMpChatMenu);
pitiupi.createMenu(MenuCategory.Social, unicastMpChatMenu);
@@ -74,7 +76,7 @@ public class MultiProtocolChat extends Plugin {
@Override
public boolean receivePrivateConnection(TcpConnection connection) {
SwingUtilities.invokeLater(() -> {
privateChatWindow.addConnection(connection);
privateChatController.connectionReceived(connection);
});
return true;
}
@@ -82,13 +84,13 @@ public class MultiProtocolChat extends Plugin {
@Override
public boolean receiveBytes(TcpConnection connection, byte[] bytes) {
MpChatMessage mpChatMessage = parseMessage(bytes);
privateChatWindow.receiveMessage(connection, mpChatMessage);
privateChatController.receiveMessage(connection, mpChatMessage);
return true;
}
@Override
public boolean onSocketClosed(TcpConnection connection) {
privateChatWindow.removeConnection(connection);
privateChatController.closeChat(connection);
return true;
}
-1
View File
@@ -111,7 +111,6 @@ public class MenuBar extends JMenuBar {
}
public void addPluginMenu(MenuCategory category, JMenuItem menu){
System.out.println("addPluginMenu");
categories.get(category).add(menu);
}
}
+3 -1
View File
@@ -66,6 +66,8 @@ public class SocketTCP extends Thread {
try {
serverSocket = new ServerSocket(connectionManager.getPort());
address = InetAddress.getByName(InetAddress.getLocalHost().getHostAddress());
if (address != null) System.out.println("SocketTCP: "+ address);
else System.out.println("Adress: Null");
} catch (IOException ex) {
System.out.println("There is no socket connection. Sorry.");
System.out.println(ex.toString());
@@ -336,7 +338,7 @@ public class SocketTCP extends Thread {
* ao plugin destinatário.
*
* <p>Dados que não representam mensagens de controle são entregues
* diretamente ao {@link PrivateConnectionPlugin}. Mensagens de controle
* diretamente ao {@link pitiupi.models.Plugin}. Mensagens de controle
* relacionadas ao encerramento ou a erros internos provocam a notificação
* do plugin e o fechamento da conexão.</p>
*
@@ -40,6 +40,8 @@ public class TcpConnection {
this.input = new DataInputStream(socket.getInputStream());
this.output = new DataOutputStream(socket.getOutputStream());
this.address = socket.getInetAddress();
if (address != null) System.out.println("TcpConnection: " + address);
else System.out.println("Adress: Null");
this.lastActivity = System.currentTimeMillis();
this.timeout = 300_000; // 5 minutos
}